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
diff --git a/src/vnet/ip/ip.h b/src/vnet/ip/ip.h
index 3fa9726..6d822d2 100644
--- a/src/vnet/ip/ip.h
+++ b/src/vnet/ip/ip.h
@@ -278,6 +278,14 @@
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 8ea7733..30cb75a 100644
--- a/src/vnet/ip/ip_types.api
+++ b/src/vnet/ip/ip_types.api
@@ -23,6 +23,17 @@
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 f779fe7..fa1f0fe 100644
--- a/src/vnet/ip/ip_types.h
+++ b/src/vnet/ip/ip_types.h
@@ -38,9 +38,43 @@
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 72a16ad..6e5f997 100644
--- a/src/vnet/ip/ip_types_api.c
+++ b/src/vnet/ip/ip_types_api.c
@@ -107,6 +107,32 @@
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 62764e6..5948ccf 100644
--- a/src/vnet/ip/ip_types_api.h
+++ b/src/vnet/ip/ip_types_api.h
@@ -38,6 +38,10 @@
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