aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/classify
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2021-09-30 13:41:00 +0200
committerNeale Ranns <neale@graphiant.com>2021-10-06 11:58:43 +0000
commitabb2a42239430a1a67b259b931848a9195402d1a (patch)
treeebc0c6ed52424f0bea5130090a00b96053e4b451 /src/vnet/classify
parent7b3a3df263c7a5bf549f350553cbd9bce7ee40b3 (diff)
ip: add classifier-based ACLs support on ip punt
This feature allows one to add classifier-based ACLs on packets punted from the ip infra, eg. to only whitelist specific sender(s). Type: feature Change-Id: Idab37b188583efbca980038875fc3e540cb2e880 Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vnet/classify')
-rw-r--r--src/vnet/classify/classify.api16
-rw-r--r--src/vnet/classify/classify_api.c16
-rw-r--r--src/vnet/classify/in_out_acl.c126
-rw-r--r--src/vnet/classify/in_out_acl.h16
4 files changed, 117 insertions, 57 deletions
diff --git a/src/vnet/classify/classify.api b/src/vnet/classify/classify.api
index c569fe6a599..d1d7340302f 100644
--- a/src/vnet/classify/classify.api
+++ b/src/vnet/classify/classify.api
@@ -420,6 +420,22 @@ autoreply define input_acl_set_interface
bool is_add;
};
+/** \brief Add/del punt ACL
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip4_table_index - ip4 punt classify table index (~0 for skip)
+ @param ip6_table_index - ip6 punt classify table index (~0 for skip)
+ @param is_add - add punt ACL if non-zero, else delete
+*/
+autoreply define punt_acl_add_del
+{
+ u32 client_index;
+ u32 context;
+ u32 ip4_table_index [default=0xffffffff];
+ u32 ip6_table_index [default=0xffffffff];
+ bool is_add [default=true];
+};
+
/** \brief Set/unset output ACL interface
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
diff --git a/src/vnet/classify/classify_api.c b/src/vnet/classify/classify_api.c
index 269aac1a194..3e8dc511479 100644
--- a/src/vnet/classify/classify_api.c
+++ b/src/vnet/classify/classify_api.c
@@ -896,6 +896,22 @@ static void vl_api_input_acl_set_interface_t_handler
REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
}
+static void
+vl_api_punt_acl_add_del_t_handler (vl_api_punt_acl_add_del_t *mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_punt_acl_add_del_reply_t *rmp;
+ int rv;
+
+ rv = vnet_set_in_out_acl_intfc (
+ vm, 0 /* sw_if_index */, ~0 /* ip4_table_index */,
+ ~0 /* ip6_table_index */, ~0 /* l2_table_index */,
+ ntohl (mp->ip4_table_index), ntohl (mp->ip6_table_index), mp->is_add,
+ 0 /* is_output */);
+
+ REPLY_MACRO (VL_API_PUNT_ACL_ADD_DEL_REPLY);
+}
+
static void vl_api_output_acl_set_interface_t_handler
(vl_api_output_acl_set_interface_t * mp)
{
diff --git a/src/vnet/classify/in_out_acl.c b/src/vnet/classify/in_out_acl.c
index 7f5a926212c..752305e1cc2 100644
--- a/src/vnet/classify/in_out_acl.c
+++ b/src/vnet/classify/in_out_acl.c
@@ -21,63 +21,75 @@
in_out_acl_main_t in_out_acl_main;
static int
-vnet_in_out_acl_ip_feature_enable (vlib_main_t * vnm,
- in_out_acl_main_t * am,
- u32 sw_if_index,
- in_out_acl_table_id_t tid,
- int feature_enable, int is_output)
+vnet_in_out_acl_feature_enable (in_out_acl_main_t *am, u32 sw_if_index,
+ in_out_acl_table_id_t tid, int feature_enable,
+ int is_output)
{
+ const char *arc_name, *feature_name;
+ vnet_feature_config_main_t *fcm;
+ u8 arc;
+ int rv;
- if (tid == IN_OUT_ACL_TABLE_L2)
+ switch (tid)
{
+ case IN_OUT_ACL_N_TABLES:
+ return VNET_API_ERROR_NO_SUCH_TABLE;
+ case IN_OUT_ACL_TABLE_L2:
if (is_output)
l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_ACL,
feature_enable);
else
l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ACL,
feature_enable);
+ return 0;
+ case IN_OUT_ACL_TABLE_IP4:
+ arc_name = is_output ? "ip4-output" : "ip4-unicast";
+ feature_name = is_output ? "ip4-outacl" : "ip4-inacl";
+ break;
+ case IN_OUT_ACL_TABLE_IP6:
+ arc_name = is_output ? "ip6-output" : "ip6-unicast";
+ feature_name = is_output ? "ip6-outacl" : "ip6-inacl";
+ break;
+ case IN_OUT_ACL_TABLE_IP4_PUNT:
+ if (sw_if_index != 0)
+ return VNET_API_ERROR_INVALID_INTERFACE;
+ arc_name = "ip4-punt";
+ feature_name = "ip4-punt-acl";
+ break;
+ case IN_OUT_ACL_TABLE_IP6_PUNT:
+ if (sw_if_index != 0)
+ return VNET_API_ERROR_INVALID_INTERFACE;
+ arc_name = "ip6-punt";
+ feature_name = "ip6-punt-acl";
+ break;
}
- else
- { /* IP[46] */
- vnet_feature_config_main_t *fcm;
- u8 arc;
- if (tid == IN_OUT_ACL_TABLE_IP4)
- {
- char *arc_name = is_output ? "ip4-output" : "ip4-unicast";
- vnet_feature_enable_disable (arc_name,
- is_output ? "ip4-outacl" : "ip4-inacl",
- sw_if_index, feature_enable, 0, 0);
- arc = vnet_get_feature_arc_index (arc_name);
- }
- else
- {
- char *arc_name = is_output ? "ip6-output" : "ip6-unicast";
- vnet_feature_enable_disable (arc_name,
- is_output ? "ip6-outacl" : "ip6-inacl",
- sw_if_index, feature_enable, 0, 0);
- arc = vnet_get_feature_arc_index (arc_name);
- }
+ rv = vnet_feature_enable_disable (arc_name, feature_name, sw_if_index,
+ feature_enable, 0, 0);
+ if (rv)
+ return rv;
- fcm = vnet_get_feature_arc_config_main (arc);
- am->vnet_config_main[is_output][tid] = &fcm->config_main;
- }
+ arc = vnet_get_feature_arc_index (arc_name);
+ fcm = vnet_get_feature_arc_config_main (arc);
+ am->vnet_config_main[is_output][tid] = &fcm->config_main;
return 0;
}
int
-vnet_set_in_out_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
- u32 ip4_table_index,
- u32 ip6_table_index, u32 l2_table_index,
- u32 is_add, u32 is_output)
+vnet_set_in_out_acl_intfc (vlib_main_t *vm, u32 sw_if_index,
+ u32 ip4_table_index, u32 ip6_table_index,
+ u32 l2_table_index, u32 ip4_punt_table_index,
+ u32 ip6_punt_table_index, u32 is_add, u32 is_output)
{
in_out_acl_main_t *am = &in_out_acl_main;
vnet_classify_main_t *vcm = am->vnet_classify_main;
- u32 acl[IN_OUT_ACL_N_TABLES] = { ip4_table_index, ip6_table_index,
- l2_table_index
+ u32 acl[IN_OUT_ACL_N_TABLES] = {
+ ip4_table_index, ip6_table_index, l2_table_index,
+ ip4_punt_table_index, ip6_punt_table_index,
};
u32 ti;
+ int rv;
/* Assume that we've validated sw_if_index in the API layer */
@@ -111,8 +123,10 @@ vnet_set_in_out_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
!= ~0)
return 0;
- vnet_in_out_acl_ip_feature_enable (vm, am, sw_if_index, ti, is_add,
- is_output);
+ rv = vnet_in_out_acl_feature_enable (am, sw_if_index, ti, is_add,
+ is_output);
+ if (rv)
+ return rv;
if (is_add)
am->classify_table_index_by_sw_if_index[is_output][ti][sw_if_index] =
@@ -130,9 +144,10 @@ vnet_set_input_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
u32 ip4_table_index,
u32 ip6_table_index, u32 l2_table_index, u32 is_add)
{
- return vnet_set_in_out_acl_intfc (vm, sw_if_index, ip4_table_index,
- ip6_table_index, l2_table_index, is_add,
- IN_OUT_ACL_INPUT_TABLE_GROUP);
+ return vnet_set_in_out_acl_intfc (
+ vm, sw_if_index, ip4_table_index, ip6_table_index, l2_table_index,
+ ~0 /* ip4_punt_table_index */, ~0 /* ip6_punt_table_index */, is_add,
+ IN_OUT_ACL_INPUT_TABLE_GROUP);
}
int
@@ -141,9 +156,10 @@ vnet_set_output_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
u32 ip6_table_index, u32 l2_table_index,
u32 is_add)
{
- return vnet_set_in_out_acl_intfc (vm, sw_if_index, ip4_table_index,
- ip6_table_index, l2_table_index, is_add,
- IN_OUT_ACL_OUTPUT_TABLE_GROUP);
+ return vnet_set_in_out_acl_intfc (
+ vm, sw_if_index, ip4_table_index, ip6_table_index, l2_table_index,
+ ~0 /* ip4_punt_table_index */, ~0 /* ip6_punt_table_index */, is_add,
+ IN_OUT_ACL_OUTPUT_TABLE_GROUP);
}
static clib_error_t *
@@ -155,6 +171,8 @@ set_in_out_acl_command_fn (vlib_main_t * vm,
u32 sw_if_index = ~0;
u32 ip4_table_index = ~0;
u32 ip6_table_index = ~0;
+ u32 ip4_punt_table_index = ~0;
+ u32 ip6_punt_table_index = ~0;
u32 l2_table_index = ~0;
u32 is_add = 1;
u32 idx_cnt = 0;
@@ -169,6 +187,10 @@ set_in_out_acl_command_fn (vlib_main_t * vm,
idx_cnt++;
else if (unformat (input, "ip6-table %d", &ip6_table_index))
idx_cnt++;
+ else if (unformat (input, "ip4-punt-table %d", &ip4_punt_table_index))
+ idx_cnt++;
+ else if (unformat (input, "ip6-punt-table %d", &ip6_punt_table_index))
+ idx_cnt++;
else if (unformat (input, "l2-table %d", &l2_table_index))
idx_cnt++;
else if (unformat (input, "del"))
@@ -186,9 +208,9 @@ set_in_out_acl_command_fn (vlib_main_t * vm,
if (idx_cnt > 1)
return clib_error_return (0, "Only one table index per API is allowed.");
- rv = vnet_set_in_out_acl_intfc (vm, sw_if_index, ip4_table_index,
- ip6_table_index, l2_table_index, is_add,
- is_output);
+ rv = vnet_set_in_out_acl_intfc (
+ vm, sw_if_index, ip4_table_index, ip6_table_index, l2_table_index,
+ ip4_punt_table_index, ip6_punt_table_index, is_add, is_output);
switch (rv)
{
@@ -200,6 +222,9 @@ set_in_out_acl_command_fn (vlib_main_t * vm,
case VNET_API_ERROR_NO_SUCH_ENTRY:
return clib_error_return (0, "No such classifier table");
+
+ default:
+ return clib_error_return (0, "Error: %d", rv);
}
return 0;
}
@@ -232,11 +257,12 @@ set_output_acl_command_fn (vlib_main_t * vm,
*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (set_input_acl_command, static) = {
- .path = "set interface input acl",
- .short_help =
+ .path = "set interface input acl",
+ .short_help =
"set interface input acl intfc <int> [ip4-table <index>]\n"
- " [ip6-table <index>] [l2-table <index>] [del]",
- .function = set_input_acl_command_fn,
+ " [ip6-table <index>] [l2-table <index>] [ip4-punt-table <index>]\n"
+ " [ip6-punt-table <index> [del]",
+ .function = set_input_acl_command_fn,
};
VLIB_CLI_COMMAND (set_output_acl_command, static) = {
.path = "set interface output acl",
diff --git a/src/vnet/classify/in_out_acl.h b/src/vnet/classify/in_out_acl.h
index be0323055d8..331c64f531f 100644
--- a/src/vnet/classify/in_out_acl.h
+++ b/src/vnet/classify/in_out_acl.h
@@ -31,6 +31,8 @@ typedef enum
IN_OUT_ACL_TABLE_IP4,
IN_OUT_ACL_TABLE_IP6,
IN_OUT_ACL_TABLE_L2,
+ IN_OUT_ACL_TABLE_IP4_PUNT,
+ IN_OUT_ACL_TABLE_IP6_PUNT,
IN_OUT_ACL_N_TABLES,
} in_out_acl_table_id_t;
@@ -59,14 +61,14 @@ typedef struct
extern in_out_acl_main_t in_out_acl_main;
-int vnet_set_in_out_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
- u32 ip4_table_index,
- u32 ip6_table_index,
- u32 l2_table_index, u32 is_add, u32 is_output);
+int vnet_set_in_out_acl_intfc (vlib_main_t *vm, u32 sw_if_index,
+ u32 ip4_table_index, u32 ip6_table_index,
+ u32 l2_table_index, u32 ip4_punt_table_index,
+ u32 ip6_punt_table_index, u32 is_add,
+ u32 is_output);
-int vnet_set_input_acl_intfc (vlib_main_t * vm, u32 sw_if_index,
- u32 ip4_table_index,
- u32 ip6_table_index,
+int vnet_set_input_acl_intfc (vlib_main_t *vm, u32 sw_if_index,
+ u32 ip4_table_index, u32 ip6_table_index,
u32 l2_table_index, u32 is_add);
int vnet_set_output_acl_intfc (vlib_main_t * vm, u32 sw_if_index,