ip: Sub Address Family types. Feature enable for each SAFI 76/30176/4
authorNeale Ranns <neale.ranns@cisco.com>
Thu, 26 Nov 2020 14:15:33 +0000 (14:15 +0000)
committerNeale Ranns <nranns@cisco.com>
Fri, 27 Nov 2020 12:25:23 +0000 (12:25 +0000)
Type: improvement

Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
Change-Id: I318424ffa569d9a09187066d6ba15576757c1cf6

src/vnet/ip/ip.c
src/vnet/ip/ip.h
src/vnet/ip/ip_types.api
src/vnet/ip/ip_types.h
src/vnet/ip/ip_types_api.c
src/vnet/ip/ip_types_api.h
src/vnet/qos/qos_record.c

index 062f5e7..f76d519 100644 (file)
@@ -102,6 +102,92 @@ ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
                      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)
 {
@@ -138,6 +224,40 @@ unformat_ip_address_family (unformat_input_t * input, va_list * args)
   return (0);
 }
 
+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)
 {
index 3fa9726..6d822d2 100644 (file)
@@ -278,6 +278,14 @@ u8 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4);
 void ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4);
 void ip_set (ip46_address_t * dst, void *src, u8 is_ip4);
 
+void ip_feature_enable_disable (ip_address_family_t af,
+                               ip_sub_address_family_t safi,
+                               ip_feature_location_t loc,
+                               const char *feature,
+                               u32 sw_if_index, int enable_disable,
+                               void *feature_config,
+                               u32 n_feature_config_bytes);
+
 always_inline u32 vlib_buffer_get_ip4_fib_index (vlib_buffer_t * b);
 always_inline u32 vlib_buffer_get_ip6_fib_index (vlib_buffer_t * b);
 always_inline u32
index 8ea7733..30cb75a 100644 (file)
@@ -23,6 +23,17 @@ enum address_family : u8 {
   ADDRESS_IP6,
 };
 
+/**
+ * @brief The location at which to apply a feature
+ */
+enum ip_feature_location: u8 {
+  IP_API_FEATURE_INPUT = 0,
+  IP_API_FEATURE_OUTPUT,
+  IP_API_FEATURE_LOCAL,
+  IP_API_FEATURE_PUNT,
+  IP_API_FEATURE_DROP,
+};
+
 /* ECN code points - RFC 3168
    https://tools.ietf.org/html/rfc3168
 */
index f779fe7..fa1f0fe 100644 (file)
@@ -38,9 +38,43 @@ extern fib_protocol_t ip_address_family_to_fib_proto (ip_address_family_t af);
 extern ip_address_family_t ip_address_family_from_fib_proto (fib_protocol_t
                                                             fp);
 
+typedef enum ip_sub_address_family_t_
+{
+  SAFI_UNICAST,
+  SAFI_MULTICAST,
+} __clib_packed ip_sub_address_family_t;
+
+#define N_SAFI (SAFI_MULTICAST+1)
+
+extern uword unformat_ip_sub_address_family (unformat_input_t * input,
+                                            va_list * args);
+extern u8 *format_ip_sub_address_family (u8 * s, va_list * args);
+
+#define FOR_EACH_IP_ADDRESS_SUB_FAMILY(_safi) \
+  for (_safi = SAFI_UNICAST; _safi <= SAFI_MULTICAST; _safi++)
+
 #define u8_ptr_add(ptr, index) (((u8 *)ptr) + index)
 #define u16_net_add(u, val) clib_host_to_net_u16(clib_net_to_host_u16(u) + (val))
 
+/**
+ * Locations in the IP switch path where features can be applied
+ */
+#define foreach_ip_feature_location                 \
+  _(INPUT, "input")                                 \
+  _(OUTPUT, "output")                               \
+  _(LOCAL, "local")                                 \
+  _(PUNT, "punt")                                   \
+  _(DROP, "drop")                                   \
+
+typedef enum ip_feature_location_t_
+{
+#define _(a,b) IP_FEATURE_##a,
+  foreach_ip_feature_location
+#undef _
+} __clib_packed ip_feature_location_t;
+
+#define N_IP_FEATURE_LOCATIONS (IP_FEATURE_DROP+1)
+
 /* *INDENT-OFF* */
 typedef struct ip_address
 {
index 72a16ad..6e5f997 100644 (file)
@@ -107,6 +107,32 @@ ip_dscp_encode (ip_dscp_t dscp)
   return ((vl_api_ip_dscp_t) dscp);
 }
 
+int
+ip_feature_location_decode (vl_api_ip_feature_location_t loc,
+                           ip_feature_location_t * out)
+{
+  /* Not all feature_locationcol are defined in vl_api_ip_feature_location_t
+   * so we must cast to a different type.
+   */
+  switch (loc)
+    {
+#define _(n,s)                                    \
+      case IP_API_FEATURE_##n:                    \
+        *out = IP_FEATURE_##n;                    \
+        return (0);
+      foreach_ip_feature_location
+#undef _
+    }
+  return (VNET_API_ERROR_FEATURE_DISABLED);
+}
+
+vl_api_ip_feature_location_t
+ip_feature_location_encode (ip_feature_location_t loc)
+{
+  return ((vl_api_ip_feature_location_t) (loc));
+}
+
+
 void
 ip6_address_encode (const ip6_address_t * in, vl_api_ip6_address_t out)
 {
index 62764e6..5948ccf 100644 (file)
@@ -38,6 +38,10 @@ extern int ip_proto_decode (vl_api_ip_proto_t ipp, ip_protocol_t * out);
 extern vl_api_ip_proto_t ip_proto_encode (ip_protocol_t ipp);
 extern ip_dscp_t ip_dscp_decode (vl_api_ip_dscp_t _dscp);
 extern vl_api_ip_dscp_t ip_dscp_encode (ip_dscp_t dscp);
+extern int ip_feature_location_decode (vl_api_ip_feature_location_t in,
+                                      ip_feature_location_t * out);
+extern vl_api_ip_feature_location_t
+ip_feature_location_encode (ip_feature_location_t f);
 
 /**
  * Decode/Encode for struct/union types
index 40e6b07..d52c144 100644 (file)
@@ -34,14 +34,12 @@ qos_record_feature_config (u32 sw_if_index,
   switch (input_source)
     {
     case QOS_SOURCE_IP:
-      vnet_feature_enable_disable ("ip6-unicast", "ip6-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip6-multicast", "ip6-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip4-unicast", "ip4-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip4-multicast", "ip4-qos-record",
-                                  sw_if_index, enable, NULL, 0);
+      ip_feature_enable_disable (AF_IP6, N_SAFI, IP_FEATURE_INPUT,
+                                "ip6-qos-record",
+                                sw_if_index, enable, NULL, 0);
+      ip_feature_enable_disable (AF_IP4, N_SAFI, IP_FEATURE_INPUT,
+                                "ip4-qos-record",
+                                sw_if_index, enable, NULL, 0);
       l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_IP_QOS_RECORD,
                                  enable);
       break;
@@ -50,14 +48,12 @@ qos_record_feature_config (u32 sw_if_index,
                                   sw_if_index, enable, NULL, 0);
       break;
     case QOS_SOURCE_VLAN:
-      vnet_feature_enable_disable ("ip6-unicast", "vlan-ip6-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip6-multicast", "vlan-ip6-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip4-unicast", "vlan-ip4-qos-record",
-                                  sw_if_index, enable, NULL, 0);
-      vnet_feature_enable_disable ("ip4-multicast", "vlan-ip4-qos-record",
-                                  sw_if_index, enable, NULL, 0);
+      ip_feature_enable_disable (AF_IP6, N_SAFI, IP_FEATURE_INPUT,
+                                "vlan-ip6-qos-record",
+                                sw_if_index, enable, NULL, 0);
+      ip_feature_enable_disable (AF_IP4, N_SAFI, IP_FEATURE_INPUT,
+                                "vlan-ip4-qos-record",
+                                sw_if_index, enable, NULL, 0);
       vnet_feature_enable_disable ("mpls-input", "vlan-mpls-qos-record",
                                   sw_if_index, enable, NULL, 0);
       break;