From f0c1c96b0be1552deff0fbfc62db4ce510cb700d Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Thu, 2 Nov 2017 21:31:46 -0700 Subject: [PATCH] session: support drop action in rules table Change-Id: Ided2980373ed5329c68f958f61be893428bccd31 Signed-off-by: Florin Coras --- src/vnet/session/mma_template.c | 12 +++--- src/vnet/session/session_lookup.c | 66 ++++++++++++++++++-------------- src/vnet/session/session_rules_table.h | 2 + src/vnet/session/session_test.c | 70 +++++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 36 deletions(-) diff --git a/src/vnet/session/mma_template.c b/src/vnet/session/mma_template.c index a8386695944..6efb2ff61ab 100644 --- a/src/vnet/session/mma_template.c +++ b/src/vnet/session/mma_template.c @@ -99,11 +99,11 @@ RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt, ASSERT (rp); if (!RT (rule_is_match_for_key) (key, rp)) - return ~0; + return SESSION_RULES_TABLE_INVALID_INDEX; for (i = 0; i < vec_len (rp->next_indices); i++) { rv = RT (mma_rules_table_lookup) (srt, key, rp->next_indices[i]); - if (rv != ~0) + if (rv != SESSION_RULES_TABLE_INVALID_INDEX) return (rv); } return (rp->action_index); @@ -123,11 +123,11 @@ RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt, ASSERT (rp); if (!RT (rule_is_match_for_key) (key, rp)) - return ~0; + return SESSION_RULES_TABLE_INVALID_INDEX; for (i = 0; i < vec_len (rp->next_indices); i++) { rv = RT (mma_rules_table_lookup_rule) (srt, key, rp->next_indices[i]); - if (rv != ~0) + if (rv != SESSION_RULES_TABLE_INVALID_INDEX) return (rv); } return rule_index; @@ -218,7 +218,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt, rp = RT (mma_rules_table_get_rule) (srt, rule_index); if (!RT (rule_is_match_for_key) (&rule->match, rp)) - return ~0; + return SESSION_RULES_TABLE_INVALID_INDEX; if (RT (rule_is_exact_match) (rule, rp)) { if (rule_index == srt->root_index) @@ -257,7 +257,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt, else if (rv == 0) return rv; } - return ~0; + return SESSION_RULES_TABLE_INVALID_INDEX; } /* diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 58af2bc02d0..c55712ea850 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -339,6 +339,14 @@ session_lookup_del_session (stream_session_t * s) return session_lookup_del_connection (ts); } +static u32 +session_lookup_action_to_session (u32 action_index) +{ + if (action_index != SESSION_RULES_TABLE_ACTION_DROP) + return action_index; + return SESSION_INVALID_INDEX; +} + static stream_session_t * session_lookup_app_listen_session (u32 app_index, u8 fib_proto, u8 transport_proto) @@ -356,11 +364,12 @@ session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto, ip4_address_t * lcl, u16 lcl_port, ip4_address_t * rmt, u16 rmt_port) { - u32 action_index; + u32 action_index, session_index; action_index = session_rules_table_lookup4 (srt, proto, lcl, rmt, lcl_port, rmt_port); + session_index = session_lookup_action_to_session (action_index); /* Nothing sophisticated for now, action index is app index */ - return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP4, + return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP4, proto); } @@ -369,10 +378,11 @@ session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto, ip6_address_t * lcl, u16 lcl_port, ip6_address_t * rmt, u16 rmt_port) { - u32 action_index; + u32 action_index, session_index; action_index = session_rules_table_lookup6 (srt, proto, lcl, rmt, lcl_port, rmt_port); - return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP6, + session_index = session_lookup_action_to_session (action_index); + return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6, proto); } @@ -384,7 +394,7 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) session_kv6_t kv6; ip4_address_t lcl4; ip6_address_t lcl6; - u32 si; + u32 ai; int rv; st = session_table_get (table_index); @@ -399,11 +409,11 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) return kv4.value; memset (&lcl4, 0, sizeof (lcl4)); - si = - session_rules_table_lookup4 (&st->session_rules, sep->transport_proto, - &lcl4, &sep->ip.ip4, 0, sep->port); - if (si != SESSION_RULES_TABLE_INVALID_INDEX) - return si; + ai = session_rules_table_lookup4 (&st->session_rules, + sep->transport_proto, &lcl4, + &sep->ip.ip4, 0, sep->port); + if (ai != SESSION_RULES_TABLE_INVALID_INDEX) + return session_lookup_action_to_session (ai); } else { @@ -414,11 +424,11 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) return kv6.value; memset (&lcl6, 0, sizeof (lcl6)); - si = - session_rules_table_lookup6 (&st->session_rules, sep->transport_proto, - &lcl6, &sep->ip.ip6, 0, sep->port); - if (si != SESSION_RULES_TABLE_INVALID_INDEX) - return si; + ai = session_rules_table_lookup6 (&st->session_rules, + sep->transport_proto, &lcl6, + &sep->ip.ip6, 0, sep->port); + if (ai != SESSION_RULES_TABLE_INVALID_INDEX) + return session_lookup_action_to_session (ai); } return SESSION_INVALID_HANDLE; } @@ -475,7 +485,7 @@ session_lookup_local_session_endpoint (u32 table_index, session_kv6_t kv6; ip4_address_t lcl4; ip6_address_t lcl6; - u32 si; + u32 ai; int rv; st = session_table_get (table_index); @@ -499,11 +509,11 @@ session_lookup_local_session_endpoint (u32 table_index, return (u32) kv4.value; memset (&lcl4, 0, sizeof (lcl4)); - si = - session_rules_table_lookup4 (&st->session_rules, sep->transport_proto, - &lcl4, &sep->ip.ip4, 0, sep->port); - if (si != SESSION_RULES_TABLE_INVALID_INDEX) - return si; + ai = session_rules_table_lookup4 (&st->session_rules, + sep->transport_proto, &lcl4, + &sep->ip.ip4, 0, sep->port); + if (ai != SESSION_RULES_TABLE_INVALID_INDEX) + return session_lookup_action_to_session (ai); } else { @@ -522,11 +532,11 @@ session_lookup_local_session_endpoint (u32 table_index, return (u32) kv6.value; memset (&lcl6, 0, sizeof (lcl6)); - si = - session_rules_table_lookup6 (&st->session_rules, sep->transport_proto, - &lcl6, &sep->ip.ip6, 0, sep->port); - if (si != SESSION_RULES_TABLE_INVALID_INDEX) - return si; + ai = session_rules_table_lookup6 (&st->session_rules, + sep->transport_proto, &lcl6, + &sep->ip.ip6, 0, sep->port); + if (ai != SESSION_RULES_TABLE_INVALID_INDEX) + return session_lookup_action_to_session (ai); } return SESSION_INVALID_INDEX; } @@ -1115,8 +1125,8 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args) if (args->scope & SESSION_RULE_SCOPE_LOCAL) { st = app_namespace_get_local_table (app_ns); - error = - session_rules_table_add_del (&st->session_rules, &args->table_args); + error = session_rules_table_add_del (&st->session_rules, + &args->table_args); } return error; } diff --git a/src/vnet/session/session_rules_table.h b/src/vnet/session/session_rules_table.h index e9d573a3b04..27b0f8856f5 100644 --- a/src/vnet/session/session_rules_table.h +++ b/src/vnet/session/session_rules_table.h @@ -65,6 +65,8 @@ typedef struct _session_rules_table_add_del_args u8 is_add; } session_rule_table_add_del_args_t; +#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1) + typedef struct _session_rules_table_t { /** diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c index 4b47754464d..a3e76c25539 100644 --- a/src/vnet/session/session_test.c +++ b/src/vnet/session/session_test.c @@ -732,6 +732,19 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) stream_session_t *listener, *s; app_namespace_t *default_ns = app_namespace_get_default (); u32 local_ns_index = default_ns->local_table_index; + int verbose = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "verbose")) + verbose = 1; + else + { + vlib_cli_output (vm, "parse error: '%U'", format_unformat_error, + input); + return -1; + } + } server_sep.is_ip4 = 1; server_sep.port = dummy_port; @@ -834,7 +847,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) &rmt_pref.fp_addr.ip4, lcl_port + 1, rmt_port, TRANSPORT_PROTO_TCP, 0); SESSION_TEST ((tc == 0), - "optimized lookup for wrong lcl port + 1 should not" " work"); + "optimized lookup for wrong lcl port + 1 should not work"); /* * Add 1.2.3.4/16 * 5.6.7.8/16 4321 @@ -853,13 +866,52 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) SESSION_TEST ((app_index != server_index), "local session endpoint lookup " "should not work (constrained lcl ip)"); + /* + * Add drop rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop) + */ + args.table_args.lcl_port = 1234; + args.table_args.lcl.fp_addr.ip4 = lcl_ip; + args.table_args.lcl.fp_len = 32; + args.table_args.rmt.fp_addr.ip4 = rmt_ip; + args.table_args.rmt.fp_len = 32; + args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP; + error = vnet_session_rule_add_del (&args); + SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d", + args.table_args.action_index); + + if (verbose) + { + session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4, + TRANSPORT_PROTO_TCP); + session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4, + TRANSPORT_PROTO_TCP); + } + + tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4, + &rmt_pref.fp_addr.ip4, lcl_port, + rmt_port, TRANSPORT_PROTO_TCP, 0); + SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 " + "should fail (drop rule)"); + /* * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index */ + args.table_args.lcl_port = 0; args.table_args.lcl.fp_len = 0; + args.table_args.rmt.fp_len = 16; + args.table_args.action_index = server_index; error = vnet_session_rule_add_del (&args); SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d", args.table_args.action_index); + + if (verbose) + { + session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4, + TRANSPORT_PROTO_TCP); + session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4, + TRANSPORT_PROTO_TCP); + } + app_index = session_lookup_local_session_endpoint (local_ns_index, &sep); SESSION_TEST ((app_index == server_index), "local session endpoint lookup " "should work"); @@ -892,7 +944,21 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4, lcl_port, rmt_port, TRANSPORT_PROTO_TCP, 0); - SESSION_TEST ((tc == 0), "optimized lookup should not work (del)"); + SESSION_TEST ((tc == 0), + "optimized lookup should not work (del + negative)"); + + args.table_args.is_add = 0; + args.table_args.lcl_port = 1234; + args.table_args.lcl.fp_addr.ip4 = lcl_ip; + args.table_args.lcl.fp_len = 32; + args.table_args.rmt.fp_addr.ip4 = rmt_ip; + args.table_args.rmt.fp_len = 32; + error = vnet_session_rule_add_del (&args); + SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop"); + tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4, + &rmt_pref.fp_addr.ip4, lcl_port, + rmt_port, TRANSPORT_PROTO_TCP, 0); + SESSION_TEST ((tc == 0), "optimized lookup should not work (no-rule)"); return 0; } -- 2.16.6