ip: Sub Address Family types. Feature enable for each SAFI

Type: improvement

Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
Change-Id: I318424ffa569d9a09187066d6ba15576757c1cf6
diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c
index 062f5e7..f76d519 100644
--- a/src/vnet/ip/ip.c
+++ b/src/vnet/ip/ip.c
@@ -102,6 +102,92 @@
 		      sizeof (ip6_address_t));
 }
 
+/* *INDENT-OFF* */
+static const char *ip_arc_names[N_IP_FEATURE_LOCATIONS][N_AF][N_SAFI] = {
+  [IP_FEATURE_INPUT] = {
+    [AF_IP4] = {
+      [SAFI_UNICAST] = "ip4-unicast",
+      [SAFI_MULTICAST] = "ip4-multicast",
+    },
+    [AF_IP6] = {
+      [SAFI_UNICAST] = "ip6-unicast",
+      [SAFI_MULTICAST] = "ip6-multicast",
+    },
+  },
+  [IP_FEATURE_OUTPUT] = {
+    [AF_IP4] = {
+      [SAFI_UNICAST] = "ip4-output",
+      [SAFI_MULTICAST] = "ip4-output",
+    },
+    [AF_IP6] = {
+      [SAFI_UNICAST] = "ip6-output",
+      [SAFI_MULTICAST] = "ip6-output",
+    },
+  },
+  [IP_FEATURE_LOCAL] = {
+    [AF_IP4] = {
+      [SAFI_UNICAST] = "ip4-local",
+      [SAFI_MULTICAST] = "ip4-local",
+    },
+    [AF_IP6] = {
+      [SAFI_UNICAST] = "ip6-local",
+      [SAFI_MULTICAST] = "ip6-local",
+    },
+  },
+  [IP_FEATURE_PUNT] = {
+    [AF_IP4] = {
+      [SAFI_UNICAST] = "ip4-punt",
+      [SAFI_MULTICAST] = "ip4-punt",
+    },
+    [AF_IP6] = {
+      [SAFI_UNICAST] = "ip6-punt",
+      [SAFI_MULTICAST] = "ip6-punt",
+    },
+  },
+  [IP_FEATURE_DROP] = {
+    [AF_IP4] = {
+      [SAFI_UNICAST] = "ip4-drop",
+      [SAFI_MULTICAST] = "ip4-drop",
+    },
+    [AF_IP6] = {
+      [SAFI_UNICAST] = "ip6-drop",
+      [SAFI_MULTICAST] = "ip6-drop",
+    },
+  },
+};
+/* *INDENT-ON* */
+
+void
+ip_feature_enable_disable (ip_address_family_t af,
+			   ip_sub_address_family_t safi,
+			   ip_feature_location_t loc,
+			   const char *feature_name,
+			   u32 sw_if_index, int enable,
+			   void *feature_config, u32 n_feature_config_bytes)
+{
+  if (IP_FEATURE_INPUT == loc)
+    {
+      if (N_SAFI == safi)
+	FOR_EACH_IP_ADDRESS_SUB_FAMILY (safi)
+	  vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
+				       feature_name, sw_if_index,
+				       enable, feature_config,
+				       n_feature_config_bytes);
+      else
+	vnet_feature_enable_disable (ip_arc_names[loc][af][safi],
+				     feature_name, sw_if_index,
+				     enable, feature_config,
+				     n_feature_config_bytes);
+    }
+  else
+    vnet_feature_enable_disable (ip_arc_names[loc][af][SAFI_UNICAST],
+				 feature_name, sw_if_index,
+				 enable, feature_config,
+				 n_feature_config_bytes);
+}
+
+
+
 u8 *
 format_ip_address_family (u8 * s, va_list * args)
 {
@@ -139,6 +225,40 @@
 }
 
 u8 *
+format_ip_sub_address_family (u8 * s, va_list * args)
+{
+  ip_sub_address_family_t safi = va_arg (*args, int);	// int promo ip_sub_address_family_t);
+
+  switch (safi)
+    {
+    case SAFI_UNICAST:
+      return (format (s, "unicast"));
+    case SAFI_MULTICAST:
+      return (format (s, "multicast"));
+    }
+
+  return (format (s, "unknown"));
+}
+
+uword
+unformat_ip_sub_address_family (unformat_input_t * input, va_list * args)
+{
+  ip_sub_address_family_t *safi = va_arg (*args, ip_sub_address_family_t *);
+
+  if (unformat (input, "unicast") || unformat (input, "uni"))
+    {
+      *safi = SAFI_UNICAST;
+      return (1);
+    }
+  else if (unformat (input, "multicast") || unformat (input, "multi"))
+    {
+      *safi = SAFI_MULTICAST;
+      return (1);
+    }
+  return (0);
+}
+
+u8 *
 format_ip_dscp (u8 * s, va_list * va)
 {
   ip_dscp_t dscp = va_arg (*va, u32);	// int promotion of u8