From 6dc0c8d14745e1d55f62415a3a40454ff820d9ad Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 26 Nov 2020 14:15:33 +0000 Subject: [PATCH] ip: Sub Address Family types. Feature enable for each SAFI Type: improvement Signed-off-by: Neale Ranns Change-Id: I318424ffa569d9a09187066d6ba15576757c1cf6 --- src/vnet/ip/ip.c | 120 +++++++++++++++++++++++++++++++++++++++++++++ src/vnet/ip/ip.h | 8 +++ src/vnet/ip/ip_types.api | 11 +++++ src/vnet/ip/ip_types.h | 34 +++++++++++++ src/vnet/ip/ip_types_api.c | 26 ++++++++++ src/vnet/ip/ip_types_api.h | 4 ++ src/vnet/qos/qos_record.c | 28 +++++------ 7 files changed, 215 insertions(+), 16 deletions(-) diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c index 062f5e7a4ef..f76d51989e6 100644 --- a/src/vnet/ip/ip.c +++ b/src/vnet/ip/ip.c @@ -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) { diff --git a/src/vnet/ip/ip.h b/src/vnet/ip/ip.h index 3fa97267b36..6d822d29dbe 100644 --- a/src/vnet/ip/ip.h +++ b/src/vnet/ip/ip.h @@ -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 diff --git a/src/vnet/ip/ip_types.api b/src/vnet/ip/ip_types.api index 8ea77334081..30cb75a946f 100644 --- a/src/vnet/ip/ip_types.api +++ b/src/vnet/ip/ip_types.api @@ -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 */ diff --git a/src/vnet/ip/ip_types.h b/src/vnet/ip/ip_types.h index f779fe7e864..fa1f0fe0952 100644 --- a/src/vnet/ip/ip_types.h +++ b/src/vnet/ip/ip_types.h @@ -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 { diff --git a/src/vnet/ip/ip_types_api.c b/src/vnet/ip/ip_types_api.c index 72a16adec86..6e5f997a3c4 100644 --- a/src/vnet/ip/ip_types_api.c +++ b/src/vnet/ip/ip_types_api.c @@ -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) { diff --git a/src/vnet/ip/ip_types_api.h b/src/vnet/ip/ip_types_api.h index 62764e6c96e..5948ccfb7bf 100644 --- a/src/vnet/ip/ip_types_api.h +++ b/src/vnet/ip/ip_types_api.h @@ -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 diff --git a/src/vnet/qos/qos_record.c b/src/vnet/qos/qos_record.c index 40e6b0778bb..d52c1442d8d 100644 --- a/src/vnet/qos/qos_record.c +++ b/src/vnet/qos/qos_record.c @@ -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; -- 2.16.6