diff options
author | Florin Coras <fcoras@cisco.com> | 2017-11-05 23:07:07 -0800 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2017-11-06 21:45:22 +0000 |
commit | c97a7398fc465c480a3ac66cf4b0f91a034ed564 (patch) | |
tree | 31467dcc219751cd89903e83b66c3315e31be947 /src | |
parent | a3d933c87f146df801aa3947c25b6f1b2538f847 (diff) |
session: add rule tags
Change-Id: Id5ebb410f509ac4c83d60e48efd54e00035e5ce6
Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vat/api_format.c | 26 | ||||
-rw-r--r-- | src/vnet/session/application.c | 5 | ||||
-rw-r--r-- | src/vnet/session/mma_template.c | 20 | ||||
-rw-r--r-- | src/vnet/session/mma_template.h | 5 | ||||
-rw-r--r-- | src/vnet/session/session.api | 2 | ||||
-rwxr-xr-x | src/vnet/session/session_api.c | 83 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.c | 158 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.h | 4 | ||||
-rw-r--r-- | src/vnet/session/session_rules_table.c | 317 | ||||
-rw-r--r-- | src/vnet/session/session_rules_table.h | 41 | ||||
-rw-r--r-- | src/vnet/session/session_table.c | 5 | ||||
-rw-r--r-- | src/vnet/session/session_table.h | 2 | ||||
-rw-r--r-- | src/vnet/session/session_test.c | 61 | ||||
-rw-r--r-- | src/vpp/api/custom_dump.c | 9 |
14 files changed, 492 insertions, 246 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c index f27d51ab7c7..c972c192db3 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -21560,19 +21560,21 @@ vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp) if (mp->is_ip4) { - print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d", + print (vam->ofp, + "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s", mp->appns_index, mp->transport_proto, mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port, format_ip4_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port, - mp->action_index); + mp->action_index, mp->tag); } else { - print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d", + print (vam->ofp, + "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s", mp->appns_index, mp->transport_proto, mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port, format_ip6_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port, - mp->action_index); + mp->action_index, mp->tag); } } @@ -21606,6 +21608,7 @@ vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t * clib_net_to_host_u16 (mp->rmt_port)); vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen); vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen); + vat_json_object_add_string_copy (node, "tag", mp->tag); if (mp->is_ip4) { clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4)); @@ -21632,7 +21635,7 @@ api_session_rule_add_del (vat_main_t * vam) ip4_address_t lcl_ip4, rmt_ip4; ip6_address_t lcl_ip6, rmt_ip6; u8 is_ip4 = 1, conn_set = 0; - u8 is_add = 1; + u8 is_add = 1, *tag = 0; int ret; while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) @@ -21649,6 +21652,8 @@ api_session_rule_add_del (vat_main_t * vam) ; else if (unformat (i, "scope %d", &scope)) ; + else if (unformat (i, "tag %_%v%_", &tag)) + ; else if (unformat (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4, @@ -21688,8 +21693,10 @@ api_session_rule_add_del (vat_main_t * vam) mp->is_ip4 = is_ip4; mp->transport_proto = proto; - mp->lcl_plen = clib_host_to_net_u16 (lcl_plen); - mp->rmt_plen = clib_host_to_net_u16 (rmt_plen); + mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port); + mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port); + mp->lcl_plen = lcl_plen; + mp->rmt_plen = rmt_plen; mp->action_index = clib_host_to_net_u32 (action); mp->appns_index = clib_host_to_net_u32 (appns_index); mp->scope = scope; @@ -21704,6 +21711,11 @@ api_session_rule_add_del (vat_main_t * vam) clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6)); clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6)); } + if (tag) + { + clib_memcpy (mp->tag, tag, vec_len (tag)); + vec_free (tag); + } S (mp); W (ret); diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index c16b4dab057..9a519c763fe 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -558,6 +558,7 @@ application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto, if (!ip_is_zero (&tc->lcl_ip, 1)) { + memset (&args, 0, sizeof (args)); memset (&lcl_pref, 0, sizeof (lcl_pref)); ip_copy (&lcl_pref.fp_addr, &tc->lcl_ip, is_ip4); lcl_pref.fp_len = is_ip4 ? 32 : 128; @@ -572,7 +573,7 @@ application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto, args.table_args.rmt_port = 0; args.table_args.action_index = app->index; args.table_args.is_add = is_start; - args.table_args.transport_proto = transport_proto; + args.transport_proto = transport_proto; args.appns_index = app->ns_index; args.scope = SESSION_RULE_SCOPE_GLOBAL; return vnet_session_rule_add_del (&args); @@ -595,7 +596,7 @@ application_start_stop_proxy (application_t * app, u8 transport_proto, args.table_args.rmt_port = 0; args.table_args.action_index = app->index; args.table_args.is_add = is_start; - args.table_args.transport_proto = transport_proto; + args.transport_proto = transport_proto; args.appns_index = app->ns_index; args.scope = SESSION_RULE_SCOPE_LOCAL; vnet_session_rule_add_del (&args); diff --git a/src/vnet/session/mma_template.c b/src/vnet/session/mma_template.c index 6efb2ff61ab..248ced61451 100644 --- a/src/vnet/session/mma_template.c +++ b/src/vnet/session/mma_template.c @@ -94,16 +94,16 @@ RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt, u32 rv; int i; - ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX); + ASSERT (rule_index != MMA_TABLE_INVALID_INDEX); rp = RT (mma_rules_table_get_rule) (srt, rule_index); ASSERT (rp); if (!RT (rule_is_match_for_key) (key, rp)) - return SESSION_RULES_TABLE_INVALID_INDEX; + return MMA_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 != SESSION_RULES_TABLE_INVALID_INDEX) + if (rv != MMA_TABLE_INVALID_INDEX) return (rv); } return (rp->action_index); @@ -118,16 +118,16 @@ RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt, u32 rv; int i; - ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX); + ASSERT (rule_index != MMA_TABLE_INVALID_INDEX); rp = RT (mma_rules_table_get_rule) (srt, rule_index); ASSERT (rp); if (!RT (rule_is_match_for_key) (key, rp)) - return SESSION_RULES_TABLE_INVALID_INDEX; + return MMA_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 != SESSION_RULES_TABLE_INVALID_INDEX) + if (rv != MMA_TABLE_INVALID_INDEX) return (rv); } return rule_index; @@ -214,15 +214,15 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt, u32 rv; int i; - ASSERT (rule_index != SESSION_RULES_TABLE_INVALID_INDEX); + ASSERT (rule_index != MMA_TABLE_INVALID_INDEX); rp = RT (mma_rules_table_get_rule) (srt, rule_index); if (!RT (rule_is_match_for_key) (&rule->match, rp)) - return SESSION_RULES_TABLE_INVALID_INDEX; + return MMA_TABLE_INVALID_INDEX; if (RT (rule_is_exact_match) (rule, rp)) { if (rule_index == srt->root_index) - rp->action_index = SESSION_RULES_TABLE_INVALID_INDEX; + rp->action_index = MMA_TABLE_INVALID_INDEX; return 1; } for (i = 0; i < vec_len (rp->next_indices); i++) @@ -257,7 +257,7 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt, else if (rv == 0) return rv; } - return SESSION_RULES_TABLE_INVALID_INDEX; + return MMA_TABLE_INVALID_INDEX; } /* diff --git a/src/vnet/session/mma_template.h b/src/vnet/session/mma_template.h index 8b6fd75e69c..fd5e3ea5717 100644 --- a/src/vnet/session/mma_template.h +++ b/src/vnet/session/mma_template.h @@ -30,7 +30,7 @@ #define __rtt(a, b) _rtt(a,b) #define RTT(a) __rtt(a, MMA_RT_TYPE) -#define SESSION_RULES_TABLE_INVALID_INDEX ((u32)~0) +#define MMA_TABLE_INVALID_INDEX ((u32)~0) typedef struct { @@ -79,7 +79,8 @@ RT (session_rule_free) (RTT (mma_rules_table) * srt, RTT (mma_rule) * rule); RTT (mma_rule) * RT (mma_table_get_rule) (RTT (mma_rules_table) * srt, u32 srt_index); u32 -RT (mma_table_rule_index) (RTT (mma_rules_table) * srt, RTT (mma_rule) * sr); +RT (mma_rules_table_rule_index) (RTT (mma_rules_table) * srt, + RTT (mma_rule) * sr); #endif /* SRC_VNET_SESSION_MMA_TEMPLATE_H_ */ /* diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api index 8de09226365..6ed75efb08c 100644 --- a/src/vnet/session/session.api +++ b/src/vnet/session/session.api @@ -395,6 +395,7 @@ autoreply define session_rule_add_del { u8 is_add; u32 appns_index; u8 scope; + u8 tag[64]; }; /** \brief Dump session rules @@ -439,6 +440,7 @@ define session_rules_details u32 action_index; u32 appns_index; u8 scope; + u8 tag[64]; }; /* diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 7ca87a512a3..fc0a257f9fe 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -792,6 +792,7 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp) u8 fib_proto; int rv = 0; + memset (&args, 0, sizeof (args)); fib_proto = mp->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; table_args->lcl.fp_len = mp->lcl_plen; @@ -802,6 +803,8 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp) table_args->rmt_port = clib_net_to_host_u16 (mp->rmt_port); table_args->action_index = clib_net_to_host_u32 (mp->action_index); table_args->is_add = mp->is_add; + mp->tag[sizeof (mp->tag) - 1] = 0; + table_args->tag = format (0, "%s", mp->tag); args.appns_index = clib_net_to_host_u32 (mp->appns_index); args.scope = mp->scope; @@ -815,12 +818,13 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp) rv = clib_error_get_code (error); clib_error_report (error); } + vec_free (table_args->tag); REPLY_MACRO (VL_API_SESSION_RULE_ADD_DEL_REPLY); } static void send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local, - u8 transport_proto, u32 appns_index, + u8 transport_proto, u32 appns_index, u8 * tag, unix_shared_memory_queue_t * q, u32 context) { vl_api_session_rules_details_t *rmp = 0; @@ -846,13 +850,18 @@ send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local, is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL; rmp->transport_proto = transport_proto; rmp->appns_index = clib_host_to_net_u32 (appns_index); + if (tag) + { + clib_memcpy (rmp->tag, tag, vec_len (tag)); + rmp->tag[vec_len (tag)] = 0; + } vl_msg_api_send_shmem (q, (u8 *) & rmp); } static void -send_session_rule_details6 (mma_rule_40_t * rule, u8 scope, - u8 transport_proto, u32 appns_index, +send_session_rule_details6 (mma_rule_40_t * rule, u8 is_local, + u8 transport_proto, u32 appns_index, u8 * tag, unix_shared_memory_queue_t * q, u32 context) { vl_api_session_rules_details_t *rmp = 0; @@ -874,46 +883,55 @@ send_session_rule_details6 (mma_rule_40_t * rule, u8 scope, rmp->lcl_port = clib_host_to_net_u16 (match->lcl_port); rmp->rmt_port = clib_host_to_net_u16 (match->rmt_port); rmp->action_index = clib_host_to_net_u32 (rule->action_index); - rmp->scope = scope; + rmp->scope = + is_local ? SESSION_RULE_SCOPE_LOCAL : SESSION_RULE_SCOPE_GLOBAL; rmp->transport_proto = transport_proto; rmp->appns_index = clib_host_to_net_u32 (appns_index); + if (tag) + { + clib_memcpy (rmp->tag, tag, vec_len (tag)); + rmp->tag[vec_len (tag)] = 0; + } vl_msg_api_send_shmem (q, (u8 *) & rmp); } static void send_session_rules_table_details (session_rules_table_t * srt, u8 fib_proto, - u8 is_local, u32 appns_index, + u8 tp, u8 is_local, u32 appns_index, unix_shared_memory_queue_t * q, u32 context) { mma_rule_16_t *rule16; mma_rule_40_t *rule40; mma_rules_table_16_t *srt16; mma_rules_table_40_t *srt40; - u8 tp; + u32 ri; - for (tp = 0; tp < TRANSPORT_N_PROTO; tp++) + if (is_local || fib_proto == FIB_PROTOCOL_IP4) { - if (is_local || fib_proto == FIB_PROTOCOL_IP4) - { - /* *INDENT-OFF* */ - srt16 = &srt->session_rules_tables_16[tp]; - pool_foreach (rule16, srt16->rules, ({ - send_session_rule_details4 (rule16, is_local, tp, - appns_index, q, context); - })); - /* *INDENT-ON* */ - } - if (is_local || fib_proto == FIB_PROTOCOL_IP6) - { - /* *INDENT-OFF* */ - srt40 = &srt->session_rules_tables_40[tp]; - pool_foreach (rule40, srt40->rules, ({ - send_session_rule_details6 (rule40, is_local, tp, - appns_index, q, context); - })); - /* *INDENT-ON* */ - } + u8 *tag = 0; + /* *INDENT-OFF* */ + srt16 = &srt->session_rules_tables_16; + pool_foreach (rule16, srt16->rules, ({ + ri = mma_rules_table_rule_index_16 (srt16, rule16); + tag = session_rules_table_rule_tag (srt, ri, 1); + send_session_rule_details4 (rule16, is_local, tp, appns_index, tag, + q, context); + })); + /* *INDENT-ON* */ + } + if (is_local || fib_proto == FIB_PROTOCOL_IP6) + { + u8 *tag = 0; + /* *INDENT-OFF* */ + srt40 = &srt->session_rules_tables_40; + pool_foreach (rule40, srt40->rules, ({ + ri = mma_rules_table_rule_index_40 (srt40, rule40); + tag = session_rules_table_rule_tag (srt, ri, 1); + send_session_rule_details6 (rule40, is_local, tp, appns_index, tag, + q, context); + })); + /* *INDENT-ON* */ } } @@ -922,6 +940,7 @@ vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp) { unix_shared_memory_queue_t *q = NULL; session_table_t *st; + u8 tp; q = vl_api_client_index_to_input_queue (mp->client_index); if (q == 0) @@ -929,9 +948,13 @@ vl_api_session_rules_dump_t_handler (vl_api_one_map_server_dump_t * mp) /* *INDENT-OFF* */ session_table_foreach (st, ({ - send_session_rules_table_details (&st->session_rules, st->active_fib_proto, - st->is_local, st->appns_index, q, - mp->context); + for (tp = 0; tp < TRANSPORT_N_PROTO; tp++) + { + send_session_rules_table_details (&st->session_rules[tp], + st->active_fib_proto, tp, + st->is_local, st->appns_index, q, + mp->context); + } })); /* *INDENT-ON* */ } diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index d537b9c1c82..6cdb839ceff 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -368,12 +368,13 @@ session_lookup_app_listen_session (u32 app_index, u8 fib_proto, } stream_session_t * -session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto, +session_lookup_rules_table4 (session_table_t * st, u8 proto, ip4_address_t * lcl, u16 lcl_port, ip4_address_t * rmt, u16 rmt_port) { + session_rules_table_t *srt = &st->session_rules[proto]; u32 action_index, session_index; - action_index = session_rules_table_lookup4 (srt, proto, lcl, rmt, lcl_port, + action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port, rmt_port); session_index = session_lookup_action_to_session (action_index); /* Nothing sophisticated for now, action index is app index */ @@ -382,12 +383,13 @@ session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto, } stream_session_t * -session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto, +session_lookup_rules_table6 (session_table_t * st, u8 proto, ip6_address_t * lcl, u16 lcl_port, ip6_address_t * rmt, u16 rmt_port) { + session_rules_table_t *srt = &st->session_rules[proto]; u32 action_index, session_index; - action_index = session_rules_table_lookup6 (srt, proto, lcl, rmt, lcl_port, + action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port, rmt_port); session_index = session_lookup_action_to_session (action_index); return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6, @@ -397,6 +399,7 @@ session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto, u64 session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) { + session_rules_table_t *srt; session_table_t *st; session_kv4_t kv4; session_kv6_t kv6; @@ -417,9 +420,9 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) return kv4.value; memset (&lcl4, 0, sizeof (lcl4)); - ai = session_rules_table_lookup4 (&st->session_rules, - sep->transport_proto, &lcl4, - &sep->ip.ip4, 0, sep->port); + srt = &st->session_rules[sep->transport_proto]; + ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0, + sep->port); if (ai != SESSION_RULES_TABLE_INVALID_INDEX) return session_lookup_action_to_session (ai); } @@ -432,9 +435,9 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) return kv6.value; memset (&lcl6, 0, sizeof (lcl6)); - ai = session_rules_table_lookup6 (&st->session_rules, - sep->transport_proto, &lcl6, - &sep->ip.ip6, 0, sep->port); + srt = &st->session_rules[sep->transport_proto]; + ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0, + sep->port); if (ai != SESSION_RULES_TABLE_INVALID_INDEX) return session_lookup_action_to_session (ai); } @@ -466,8 +469,7 @@ session_lookup_global_session_endpoint (session_endpoint_t * sep) if (rv == 0) return session_get_from_handle (kv4.value); memset (&lcl4, 0, sizeof (lcl4)); - return session_lookup_rules_table4 (&st->session_rules, - sep->transport_proto, &lcl4, 0, + return session_lookup_rules_table4 (st, sep->transport_proto, &lcl4, 0, &sep->ip.ip4, sep->port); } else @@ -478,8 +480,7 @@ session_lookup_global_session_endpoint (session_endpoint_t * sep) if (rv == 0) return session_get_from_handle (kv6.value); memset (&lcl6, 0, sizeof (lcl6)); - return session_lookup_rules_table6 (&st->session_rules, - sep->transport_proto, &lcl6, 0, + return session_lookup_rules_table6 (st, sep->transport_proto, &lcl6, 0, &sep->ip.ip6, sep->port); } } @@ -488,6 +489,7 @@ u32 session_lookup_local_session_endpoint (u32 table_index, session_endpoint_t * sep) { + session_rules_table_t *srt; session_table_t *st; session_kv4_t kv4; session_kv6_t kv6; @@ -517,9 +519,9 @@ session_lookup_local_session_endpoint (u32 table_index, return (u32) kv4.value; memset (&lcl4, 0, sizeof (lcl4)); - ai = session_rules_table_lookup4 (&st->session_rules, - sep->transport_proto, &lcl4, - &sep->ip.ip4, 0, sep->port); + srt = &st->session_rules[sep->transport_proto]; + ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0, + sep->port); if (ai != SESSION_RULES_TABLE_INVALID_INDEX) return session_lookup_action_to_session (ai); } @@ -540,9 +542,9 @@ session_lookup_local_session_endpoint (u32 table_index, return (u32) kv6.value; memset (&lcl6, 0, sizeof (lcl6)); - ai = session_rules_table_lookup6 (&st->session_rules, - sep->transport_proto, &lcl6, - &sep->ip.ip6, 0, sep->port); + srt = &st->session_rules[sep->transport_proto]; + ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0, + sep->port); if (ai != SESSION_RULES_TABLE_INVALID_INDEX) return session_lookup_action_to_session (ai); } @@ -723,20 +725,20 @@ session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4) return 0; } -transport_connection_t * -session_lookup_rules_table_connection4 (session_rules_table_t * srt, u8 proto, +static transport_connection_t * +session_lookup_rules_table_connection4 (session_table_t * st, u8 proto, ip4_address_t * lcl, u16 lcl_port, ip4_address_t * rmt, u16 rmt_port) { stream_session_t *s; - s = session_lookup_rules_table4 (srt, proto, lcl, lcl_port, rmt, rmt_port); + s = session_lookup_rules_table4 (st, proto, lcl, lcl_port, rmt, rmt_port); if (s) return tp_vfts[s->session_type].get_listener (s->connection_index); return 0; } -transport_connection_t * -session_lookup_rules_table_connection6 (session_rules_table_t * srt, u8 proto, +static transport_connection_t * +session_lookup_rules_table_connection6 (session_table_t * srt, u8 proto, ip6_address_t * lcl, u16 lcl_port, ip6_address_t * rmt, u16 rmt_port) { @@ -811,9 +813,8 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, } /* Check the session rules table */ - return session_lookup_rules_table_connection4 (&st->session_rules, proto, - lcl, lcl_port, rmt, - rmt_port); + return session_lookup_rules_table_connection4 (st, proto, lcl, lcl_port, + rmt, rmt_port); } /** @@ -869,9 +870,8 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, return tp_vfts[sst].get_half_open (kv4.value & 0xFFFFFFFF); } /* Check the session rules table */ - return session_lookup_rules_table_connection4 (&st->session_rules, proto, - lcl, lcl_port, rmt, - rmt_port); + return session_lookup_rules_table_connection4 (st, proto, lcl, lcl_port, + rmt, rmt_port); } /** @@ -909,7 +909,7 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt, /* If nothing is found, check if any listener is available */ if ((s = session_lookup_listener4_i (st, lcl, lcl_port, proto))) return s; - return session_lookup_rules_table4 (&st->session_rules, proto, lcl, + return session_lookup_rules_table4 (st, proto, lcl, lcl_port, rmt, rmt_port); } @@ -975,9 +975,8 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, return tp_vfts[sst].get_half_open (kv6.value & 0xFFFFFFFF); } - return session_lookup_rules_table_connection6 (&st->session_rules, proto, - lcl, lcl_port, rmt, - rmt_port); + return session_lookup_rules_table_connection6 (st, proto, lcl, lcl_port, + rmt, rmt_port); } /** @@ -1032,9 +1031,8 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, return tp_vfts[sst].get_half_open (kv6.value & 0xFFFFFFFF); } - return session_lookup_rules_table_connection6 (&st->session_rules, proto, - lcl, lcl_port, rmt, - rmt_port); + return session_lookup_rules_table_connection6 (st, proto, lcl, lcl_port, + rmt, rmt_port); } /** @@ -1071,7 +1069,7 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt, /* If nothing is found, check if any listener is available */ if ((s = session_lookup_listener6_i (st, lcl, lcl_port, proto))) return s; - return session_lookup_rules_table6 (&st->session_rules, proto, lcl, + return session_lookup_rules_table6 (st, proto, lcl, lcl_port, rmt, rmt_port); } @@ -1110,6 +1108,7 @@ clib_error_t * vnet_session_rule_add_del (session_rule_add_del_args_t * args) { app_namespace_t *app_ns = app_namespace_get (args->appns_index); + session_rules_table_t *srt; session_table_t *st; u32 fib_index; u8 fib_proto; @@ -1121,20 +1120,27 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args) if (args->scope > 3) return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0, "invalid scope"); + if (args->transport_proto != TRANSPORT_PROTO_TCP + && args->transport_proto != TRANSPORT_PROTO_UDP) + return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0, + "invalid transport proto"); if ((args->scope & SESSION_RULE_SCOPE_GLOBAL) || args->scope == 0) { fib_proto = args->table_args.rmt.fp_proto; fib_index = app_namespace_get_fib_index (app_ns, fib_proto); st = session_table_get_for_fib_index (fib_proto, fib_index); - if ((error = session_rules_table_add_del (&st->session_rules, - &args->table_args))) - return error; + srt = &st->session_rules[args->transport_proto]; + if ((error = session_rules_table_add_del (srt, &args->table_args))) + { + clib_error_report (error); + return error; + } } 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); + srt = &st->session_rules[args->transport_proto]; + error = session_rules_table_add_del (srt, &args->table_args); } return error; } @@ -1232,12 +1238,14 @@ static clib_error_t * session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen; + u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen = 0, rmt_plen = 0; u32 appns_index, scope = 0; ip46_address_t lcl_ip, rmt_ip; u8 is_ip4 = 1, conn_set = 0; u8 fib_proto, is_add = 1, *ns_id = 0; + u8 *tag = 0; app_namespace_t *app_ns; + clib_error_t *error; memset (&lcl_ip, 0, sizeof (lcl_ip)); memset (&rmt_ip, 0, sizeof (rmt_ip)); @@ -1275,19 +1283,42 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, } else if (unformat (input, "action %d", &action)) ; + else if (unformat (input, "tag %_%v%_", &tag)) + ; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); } - if (proto == ~0 || !conn_set || action == ~0) - return clib_error_return (0, "proto, connection and action must be set"); + if (proto == ~0) + { + vlib_cli_output (vm, "proto must be set"); + return 0; + } + if (is_add && !conn_set && action == ~0) + { + vlib_cli_output (vm, "connection and action must be set for add"); + return 0; + } + if (!is_add && !tag && !conn_set) + { + vlib_cli_output (vm, "connection or tag must be set for delete"); + return 0; + } + if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN) + { + vlib_cli_output (vm, "tag too long (max u64)"); + return 0; + } if (ns_id) { app_ns = app_namespace_get_from_id (ns_id); if (!app_ns) - return clib_error_return (0, "namespace %v does not exist", ns_id); + { + vlib_cli_output (vm, "namespace %v does not exist", ns_id); + return 0; + } } else { @@ -1307,10 +1338,13 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, .table_args.rmt_port = rmt_port, .table_args.action_index = action, .table_args.is_add = is_add, + .table_args.tag = tag, .appns_index = appns_index, .scope = scope, }; - return vnet_session_rule_add_del (&args); + error = vnet_session_rule_add_del (&args); + vec_free (tag); + return error; } /* *INDENT-OFF* */ @@ -1328,10 +1362,11 @@ session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto, u8 transport_proto) { vlib_main_t *vm = vlib_get_main (); + session_rules_table_t *srt; session_table_t *st; st = session_table_get_for_fib_index (fib_index, fib_proto); - session_rules_table_cli_dump (vm, &st->session_rules, fib_proto, - transport_proto); + srt = &st->session_rules[transport_proto]; + session_rules_table_cli_dump (vm, srt, fib_proto); } void @@ -1339,10 +1374,11 @@ session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto, u8 transport_proto) { vlib_main_t *vm = vlib_get_main (); + session_rules_table_t *srt; session_table_t *st; st = session_table_get (table_index); - session_rules_table_cli_dump (vm, &st->session_rules, fib_proto, - transport_proto); + srt = &st->session_rules[transport_proto]; + session_rules_table_cli_dump (vm, srt, fib_proto); } static clib_error_t * @@ -1354,6 +1390,7 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, ip46_address_t lcl_ip, rmt_ip; u8 is_ip4 = 1, show_one = 0; app_namespace_t *app_ns; + session_rules_table_t *srt; session_table_t *st; u8 *ns_id = 0, fib_proto; @@ -1423,16 +1460,17 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, if (show_one) { - session_rules_table_show_rule (vm, &st->session_rules, transport_proto, - &lcl_ip, lcl_port, &rmt_ip, rmt_port, - is_ip4); + srt = &st->session_rules[transport_proto]; + session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip, + rmt_port, is_ip4); return 0; } - session_rules_table_cli_dump (vm, &st->session_rules, FIB_PROTOCOL_IP4, - transport_proto); - session_rules_table_cli_dump (vm, &st->session_rules, FIB_PROTOCOL_IP6, - transport_proto); + vlib_cli_output (vm, "%U rules table", format_transport_proto, + transport_proto); + srt = &st->session_rules[transport_proto]; + session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4); + session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6); vec_free (ns_id); return 0; diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h index fa89727e2fe..246ab524b0f 100644 --- a/src/vnet/session/session_lookup.h +++ b/src/vnet/session/session_lookup.h @@ -113,6 +113,10 @@ typedef struct _session_rule_add_del_args * Rule scope flag. */ u8 scope; + /** + * Transport protocol for the rule + */ + u8 transport_proto; } session_rule_add_del_args_t; clib_error_t *vnet_session_rule_add_del (session_rule_add_del_args_t * args); diff --git a/src/vnet/session/session_rules_table.c b/src/vnet/session/session_rules_table.c index 685871d46ed..fa8a056fbf0 100644 --- a/src/vnet/session/session_rules_table.c +++ b/src/vnet/session/session_rules_table.c @@ -20,6 +20,86 @@ #include <vnet/session/session_rules_table.h> #include <vnet/session/transport.h> +u32 +session_rule_tag_key_index (u32 ri, u8 is_ip4) +{ + return ((ri << 1) | is_ip4); +} + +void +session_rule_tag_key_index_parse (u32 rti_key, u32 * ri, u8 * is_ip4) +{ + *is_ip4 = rti_key & 1; + *ri = rti_key >> 1; +} + +u8 * +session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri, u8 is_ip4) +{ + uword *tip; + session_rule_tag_t *rt; + + tip = + hash_get (srt->tags_by_rules, session_rule_tag_key_index (ri, is_ip4)); + if (tip) + { + rt = pool_elt_at_index (srt->rule_tags, *tip); + return rt->tag; + } + return 0; +} + +void +session_rules_table_add_del_tag (session_rules_table_t * srt, u8 * tag, + u32 rule_index, u8 is_ip4, u8 is_add) +{ + uword *rip, *rtip; + session_rule_tag_t *rt; + u32 rti_key; + + if (tag == 0) + return; + if (is_add) + { + pool_get (srt->rule_tags, rt); + rt->tag = vec_dup (tag); + hash_set_mem (srt->rules_by_tag, rt->tag, rule_index); + rti_key = session_rule_tag_key_index (rule_index, is_ip4); + hash_set (srt->tags_by_rules, rti_key, rt - srt->rule_tags); + } + else + { + rip = hash_get_mem (srt->rules_by_tag, tag); + if (!rip) + { + clib_warning ("tag has no rule associated"); + return; + } + rti_key = session_rule_tag_key_index (*rip, is_ip4); + rtip = hash_get (srt->tags_by_rules, rti_key); + if (!rtip) + { + clib_warning ("rule has no tag associated"); + return; + } + rt = pool_elt_at_index (srt->rule_tags, *rtip); + ASSERT (rt); + hash_unset_mem (srt->rules_by_tag, tag); + hash_unset (srt->tags_by_rules, rti_key); + pool_put (srt->rule_tags, rt); + } +} + +u32 +session_rules_table_rule_for_tag (session_rules_table_t * srt, u8 * tag) +{ + uword *rp; + if (tag == 0) + return SESSION_RULES_TABLE_INVALID_INDEX; + rp = hash_get_mem (srt->rules_by_tag, tag); + return (rp == 0 ? SESSION_RULES_TABLE_INVALID_INDEX : *rp); +} + static void fib_pref_normalize (fib_prefix_t * pref) { @@ -32,64 +112,76 @@ fib_pref_normalize (fib_prefix_t * pref) u8 * format_session_rule4 (u8 * s, va_list * args) { - mma_rules_table_16_t *srt = va_arg (*args, mma_rules_table_16_t *); + session_rules_table_t *srt = va_arg (*args, session_rules_table_t *); mma_rule_16_t *sr = va_arg (*args, mma_rule_16_t *); session_mask_or_match_4_t *mask, *match; + mma_rules_table_16_t *srt4; + u8 *tag = 0, *null_tag = format (0, "none"); + u32 ri; int i; + srt4 = &srt->session_rules_tables_16; + ri = mma_rules_table_rule_index_16 (srt4, sr); + tag = session_rules_table_rule_tag (srt, ri, 1); match = (session_mask_or_match_4_t *) & sr->match; mask = (session_mask_or_match_4_t *) & sr->mask; - s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d", - mma_rules_table_rule_index_16 (srt, sr), format_ip4_address, - &match->lcl_ip, - ip4_mask_to_preflen (&mask->lcl_ip), - match->lcl_port, format_ip4_address, &match->rmt_ip, - ip4_mask_to_preflen (&mask->rmt_ip), - match->rmt_port, sr->action_index); + s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri, + format_ip4_address, &match->lcl_ip, + ip4_mask_to_preflen (&mask->lcl_ip), match->lcl_port, + format_ip4_address, &match->rmt_ip, + ip4_mask_to_preflen (&mask->rmt_ip), match->rmt_port, + sr->action_index, tag ? tag : null_tag); if (vec_len (sr->next_indices)) { s = format (s, "\n children: "); for (i = 0; i < vec_len (sr->next_indices); i++) s = format (s, "%d ", sr->next_indices[i]); } + vec_free (null_tag); return s; } u8 * format_session_rule6 (u8 * s, va_list * args) { - mma_rules_table_40_t *srt = va_arg (*args, mma_rules_table_40_t *); + session_rules_table_t *srt = va_arg (*args, session_rules_table_t *); mma_rule_40_t *sr = va_arg (*args, mma_rule_40_t *); session_mask_or_match_6_t *mask, *match; + mma_rules_table_40_t *srt6; + u8 *tag = 0, *null_tag = format (0, "none"); + u32 ri; int i; + srt6 = &srt->session_rules_tables_40; + ri = mma_rules_table_rule_index_40 (srt6, sr); + tag = session_rules_table_rule_tag (srt, ri, 0); match = (session_mask_or_match_6_t *) & sr->match; mask = (session_mask_or_match_6_t *) & sr->mask; - s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d", - mma_rules_table_rule_index_40 (srt, sr), format_ip6_address, - &match->lcl_ip, ip6_mask_to_preflen (&mask->lcl_ip), - match->lcl_port, format_ip6_address, &match->rmt_ip, + s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri, + format_ip6_address, &match->lcl_ip, + ip6_mask_to_preflen (&mask->lcl_ip), match->lcl_port, + format_ip6_address, &match->rmt_ip, ip6_mask_to_preflen (&mask->rmt_ip), match->rmt_port, - sr->action_index); + sr->action_index, tag ? tag : null_tag); if (vec_len (sr->next_indices)) { s = format (s, "\n children: "); for (i = 0; i < vec_len (sr->next_indices); i++) s = format (s, "%d ", sr->next_indices[i]); } + vec_free (null_tag); return s; } void * -session_rules_table_get (session_rules_table_t * srt, u8 transport_proto, - u8 fib_proto) +session_rules_table_get (session_rules_table_t * srt, u8 fib_proto) { if (fib_proto == FIB_PROTOCOL_IP4) - return &srt->session_rules_tables_16[transport_proto]; + return &srt->session_rules_tables_16; else if (fib_proto == FIB_PROTOCOL_IP6) - return &srt->session_rules_tables_40[transport_proto]; + return &srt->session_rules_tables_40; return 0; } @@ -208,61 +300,105 @@ session_rules_table_alloc_rule_40 (mma_rules_table_40_t * srt, return rule; } +/** + * Add/delete session rule + * + * @param srt table where rule should be added + * @param args rule arguments + * + * @return 0 if success, clib_error_t error otherwise + */ clib_error_t * session_rules_table_add_del (session_rules_table_t * srt, session_rule_table_add_del_args_t * args) { u8 fib_proto = args->rmt.fp_proto; + u32 ri_from_tag, ri; + int rv; - if (args->transport_proto != TRANSPORT_PROTO_TCP - && args->transport_proto != TRANSPORT_PROTO_UDP) + ri_from_tag = session_rules_table_rule_for_tag (srt, args->tag); + if (args->is_add && ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX) return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0, - "invalid transport proto"); + "tag exists"); if (fib_proto == FIB_PROTOCOL_IP4) { mma_rules_table_16_t *srt4; - srt4 = &srt->session_rules_tables_16[args->transport_proto]; + srt4 = &srt->session_rules_tables_16; if (args->is_add) { - mma_rule_16_t *rule; - rule = session_rules_table_alloc_rule_16 (srt4, &args->lcl, - args->lcl_port, - &args->rmt, - args->rmt_port); - rule->action_index = args->action_index; - mma_rules_table_add_rule_16 (srt4, rule); + mma_rule_16_t *rule4; + rule4 = session_rules_table_alloc_rule_16 (srt4, &args->lcl, + args->lcl_port, + &args->rmt, + args->rmt_port); + rule4->action_index = args->action_index; + rv = mma_rules_table_add_rule_16 (srt4, rule4); + if (!rv) + { + ri = mma_rules_table_rule_index_16 (srt4, rule4); + session_rules_table_add_del_tag (srt, args->tag, ri, 1, 1); + } } else { - mma_rule_16_t rule; - memset (&rule, 0, sizeof (rule)); - session_rules_table_init_rule_16 (&rule, &args->lcl, args->lcl_port, - &args->rmt, args->rmt_port); - mma_rules_table_del_rule_16 (srt4, &rule, srt4->root_index); + mma_rule_16_t *rule; + if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX) + { + rule = mma_rules_table_get_rule_16 (srt4, ri_from_tag); + mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index); + session_rules_table_add_del_tag (srt, args->tag, 0, 1, 0); + } + else + { + mma_rule_16_t _rule; + rule = &_rule; + memset (rule, 0, sizeof (*rule)); + session_rules_table_init_rule_16 (rule, &args->lcl, + args->lcl_port, &args->rmt, + args->rmt_port); + mma_rules_table_del_rule_16 (srt4, rule, srt4->root_index); + } } } else if (fib_proto == FIB_PROTOCOL_IP6) { mma_rules_table_40_t *srt6; - mma_rule_40_t *rule; - srt6 = &srt->session_rules_tables_40[args->transport_proto]; + mma_rule_40_t *rule6; + srt6 = &srt->session_rules_tables_40; if (args->is_add) { - rule = session_rules_table_alloc_rule_40 (srt6, &args->lcl, - args->lcl_port, - &args->rmt, - args->rmt_port); - rule->action_index = args->action_index; - mma_rules_table_add_rule_40 (srt6, rule); + rule6 = session_rules_table_alloc_rule_40 (srt6, &args->lcl, + args->lcl_port, + &args->rmt, + args->rmt_port); + rule6->action_index = args->action_index; + rv = mma_rules_table_add_rule_40 (srt6, rule6); + if (!rv) + { + ri = mma_rules_table_rule_index_40 (srt6, rule6); + session_rules_table_add_del_tag (srt, args->tag, ri, 0, 1); + } } else { - mma_rule_40_t rule; - memset (&rule, 0, sizeof (rule)); - session_rules_table_init_rule_40 (&rule, &args->lcl, args->lcl_port, - &args->rmt, args->rmt_port); - mma_rules_table_del_rule_40 (srt6, &rule, srt6->root_index); + mma_rule_40_t *rule; + if (ri_from_tag != SESSION_RULES_TABLE_INVALID_INDEX) + { + rule = mma_rules_table_get_rule_40 (srt6, ri_from_tag); + mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index); + session_rules_table_add_del_tag (srt, args->tag, 0, 0, 0); + } + else + { + mma_rule_40_t _rule; + rule = &_rule; + memset (rule, 0, sizeof (*rule)); + session_rules_table_init_rule_40 (rule, &args->lcl, + args->lcl_port, &args->rmt, + args->rmt_port); + mma_rules_table_del_rule_40 (srt6, rule, srt6->root_index); + } } } else @@ -272,36 +408,34 @@ session_rules_table_add_del (session_rules_table_t * srt, } u32 -session_rules_table_lookup4 (session_rules_table_t * srt, u8 transport_proto, +session_rules_table_lookup4 (session_rules_table_t * srt, ip4_address_t * lcl_ip, ip4_address_t * rmt_ip, u16 lcl_port, u16 rmt_port) { - mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16[transport_proto]; + mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16; session_mask_or_match_4_t key = { .lcl_ip.as_u32 = lcl_ip->as_u32, .rmt_ip.as_u32 = rmt_ip->as_u32, .lcl_port = lcl_port, .rmt_port = rmt_port, }; - return mma_rules_table_lookup_16 (srt4, - (mma_mask_or_match_16_t *) & key, + return mma_rules_table_lookup_16 (srt4, (mma_mask_or_match_16_t *) & key, srt4->root_index); } u32 -session_rules_table_lookup6 (session_rules_table_t * srt, u8 transport_proto, +session_rules_table_lookup6 (session_rules_table_t * srt, ip6_address_t * lcl_ip, ip6_address_t * rmt_ip, u16 lcl_port, u16 rmt_port) { - mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40[transport_proto]; + mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40; session_mask_or_match_6_t key = { .lcl_port = lcl_port, .rmt_port = rmt_port, }; clib_memcpy (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip)); clib_memcpy (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip)); - return mma_rules_table_lookup_40 (srt6, - (mma_mask_or_match_40_t *) & key, + return mma_rules_table_lookup_40 (srt6, (mma_mask_or_match_40_t *) & key, srt6->root_index); } @@ -313,36 +447,32 @@ session_rules_table_init (session_rules_table_t * srt) mma_rule_16_t *rule4; mma_rule_40_t *rule6; fib_prefix_t null_prefix; - int i; memset (&null_prefix, 0, sizeof (null_prefix)); - for (i = 0; i < TRANSPORT_N_PROTO; i++) - { - srt4 = &srt->session_rules_tables_16[i]; - rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0, - &null_prefix, 0); - rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX; - srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4); - srt4->rule_cmp_fn = rule_cmp_16; - } - - for (i = 0; i < TRANSPORT_N_PROTO; i++) - { - srt6 = &srt->session_rules_tables_40[i];; - rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0, - &null_prefix, 0); - rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX; - srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6); - srt6->rule_cmp_fn = rule_cmp_40; - } + srt4 = &srt->session_rules_tables_16; + rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0, + &null_prefix, 0); + rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX; + srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4); + srt4->rule_cmp_fn = rule_cmp_16; + + srt6 = &srt->session_rules_tables_40; + rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0, + &null_prefix, 0); + rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX; + srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6); + srt6->rule_cmp_fn = rule_cmp_40; + + srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword)); + srt->tags_by_rules = hash_create (0, sizeof (uword)); } void session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt, - u8 transport_proto, ip46_address_t * lcl_ip, - u16 lcl_port, ip46_address_t * rmt_ip, - u16 rmt_port, u8 is_ip4) + ip46_address_t * lcl_ip, u16 lcl_port, + ip46_address_t * rmt_ip, u16 rmt_port, + u8 is_ip4) { mma_rules_table_16_t *srt4; mma_rules_table_40_t *srt6; @@ -352,7 +482,7 @@ session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt, if (is_ip4) { - srt4 = session_rules_table_get (srt, transport_proto, FIB_PROTOCOL_IP4); + srt4 = session_rules_table_get (srt, FIB_PROTOCOL_IP4); session_mask_or_match_4_t key = { .lcl_ip.as_u32 = lcl_ip->ip4.as_u32, .rmt_ip.as_u32 = rmt_ip->ip4.as_u32, @@ -364,41 +494,39 @@ session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt, (mma_mask_or_match_16_t *) & key, srt4->root_index); sr4 = mma_rules_table_get_rule_16 (srt4, ri); - vlib_cli_output (vm, "%U", format_session_rule4, srt4, sr4); + vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4); } else { - srt6 = session_rules_table_get (srt, transport_proto, FIB_PROTOCOL_IP6); + srt6 = session_rules_table_get (srt, FIB_PROTOCOL_IP6); session_mask_or_match_6_t key = { .lcl_port = lcl_port, .rmt_port = rmt_port, }; clib_memcpy (&key.lcl_ip, &lcl_ip->ip6, sizeof (lcl_ip->ip6)); clib_memcpy (&key.rmt_ip, &rmt_ip->ip6, sizeof (rmt_ip->ip6)); - ri = - mma_rules_table_lookup_rule_40 (srt6, - (mma_mask_or_match_40_t *) & - key, srt6->root_index); + ri = mma_rules_table_lookup_rule_40 (srt6, + (mma_mask_or_match_40_t *) & key, + srt6->root_index); sr6 = mma_rules_table_get_rule_40 (srt6, ri); - vlib_cli_output (vm, "%U", format_session_rule6, srt6, sr6); + vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6); } } void session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt, - u8 fib_proto, u8 transport_proto) + u8 fib_proto) { if (fib_proto == FIB_PROTOCOL_IP4) { mma_rules_table_16_t *srt4; mma_rule_16_t *sr4; - srt4 = &srt->session_rules_tables_16[transport_proto]; - vlib_cli_output (vm, "%U IP4 rules table", format_transport_proto, - transport_proto); + srt4 = &srt->session_rules_tables_16; + vlib_cli_output (vm, "IP4 rules"); /* *INDENT-OFF* */ pool_foreach(sr4, srt4->rules, ({ - vlib_cli_output (vm, "%U", format_session_rule4, srt4, sr4); + vlib_cli_output (vm, "%U", format_session_rule4, srt, sr4); })); /* *INDENT-ON* */ @@ -407,13 +535,12 @@ session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt, { mma_rules_table_40_t *srt6; mma_rule_40_t *sr6; - srt6 = &srt->session_rules_tables_40[transport_proto]; - vlib_cli_output (vm, "\n%U IP6 rules table", format_transport_proto, - transport_proto); + srt6 = &srt->session_rules_tables_40; + vlib_cli_output (vm, "IP6 rules"); /* *INDENT-OFF* */ pool_foreach(sr6, srt6->rules, ({ - vlib_cli_output (vm, "%U", format_session_rule6, srt6, sr6); + vlib_cli_output (vm, "%U", format_session_rule6, srt, sr6); })); /* *INDENT-ON* */ diff --git a/src/vnet/session/session_rules_table.h b/src/vnet/session/session_rules_table.h index 27b0f8856f5..9bab61e7539 100644 --- a/src/vnet/session/session_rules_table.h +++ b/src/vnet/session/session_rules_table.h @@ -54,50 +54,67 @@ typedef CLIB_PACKED (struct }) session_mask_or_match_6_t; /* *INDENT-ON* */ +#define SESSION_RULE_TAG_MAX_LEN 64 +#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1) +#define SESSION_RULES_TABLE_INVALID_INDEX MMA_TABLE_INVALID_INDEX + typedef struct _session_rules_table_add_del_args { - u8 transport_proto; fib_prefix_t lcl; fib_prefix_t rmt; u16 lcl_port; u16 rmt_port; u32 action_index; + u8 *tag; u8 is_add; } session_rule_table_add_del_args_t; -#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1) +typedef struct _rule_tag +{ + u8 *tag; +} session_rule_tag_t; typedef struct _session_rules_table_t { /** - * Per fib proto and transport proto session rules tables + * Per fib proto session rules tables + */ + mma_rules_table_16_t session_rules_tables_16; + mma_rules_table_40_t session_rules_tables_40; + /** + * Hash table that maps tags to rules + */ + uword *rules_by_tag; + /** + * Pool of rules tags + */ + session_rule_tag_t *rule_tags; + /** + * Hash table that maps rule indices to tags */ - mma_rules_table_16_t session_rules_tables_16[TRANSPORT_N_PROTO]; - mma_rules_table_40_t session_rules_tables_40[TRANSPORT_N_PROTO]; + uword *tags_by_rules; } session_rules_table_t; -void *session_rules_table_get (session_rules_table_t * srt, - u8 transport_proto, u8 fib_proto); u32 session_rules_table_lookup4 (session_rules_table_t * srt, - u8 transport_proto, ip4_address_t * lcl_ip, + ip4_address_t * lcl_ip, ip4_address_t * rmt_ip, u16 lcl_port, u16 rmt_port); u32 session_rules_table_lookup6 (session_rules_table_t * srt, - u8 transport_proto, ip6_address_t * lcl_ip, + ip6_address_t * lcl_ip, ip6_address_t * rmt_ip, u16 lcl_port, u16 rmt_port); void session_rules_table_cli_dump (vlib_main_t * vm, - session_rules_table_t * srt, u8 fib_proto, - u8 transport_proto); + session_rules_table_t * srt, u8 fib_proto); void session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt, - u8 transport_proto, ip46_address_t * lcl_ip, u16 lcl_port, ip46_address_t * rmt_ip, u16 rmt_port, u8 is_ip4); clib_error_t *session_rules_table_add_del (session_rules_table_t * srt, session_rule_table_add_del_args_t * args); +u8 *session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri, + u8 is_ip4); void session_rules_table_init (session_rules_table_t * srt); #endif /* SRC_VNET_SESSION_SESSION_RULES_TABLE_H_ */ /* diff --git a/src/vnet/session/session_table.c b/src/vnet/session/session_table.c index f0bd338ec64..5d160a4b2dc 100644 --- a/src/vnet/session/session_table.c +++ b/src/vnet/session/session_table.c @@ -70,6 +70,7 @@ void session_table_init (session_table_t * slt, u8 fib_proto) { u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0; + int i; #define _(af,table,parm,value) \ u32 configured_##af##_##table##_table_##parm = value; @@ -101,7 +102,9 @@ session_table_init (session_table_t * slt, u8 fib_proto) configured_v6_halfopen_table_buckets, configured_v6_halfopen_table_memory); } - session_rules_table_init (&slt->session_rules); + + for (i = 0; i < TRANSPORT_N_PROTO; i++) + session_rules_table_init (&slt->session_rules[i]); } typedef struct _ip4_session_table_walk_ctx_t diff --git a/src/vnet/session/session_table.h b/src/vnet/session/session_table.h index 6cf815991a9..636ee44a2fe 100644 --- a/src/vnet/session/session_table.h +++ b/src/vnet/session/session_table.h @@ -37,7 +37,7 @@ typedef struct _session_lookup_table /** * Per fib proto and transport proto session rules tables */ - session_rules_table_t session_rules; + session_rules_table_t session_rules[TRANSPORT_N_PROTO]; /** Flag that indicates if table has local scope */ u8 is_local; diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c index a3e76c25539..8d18619067f 100644 --- a/src/vnet/session/session_test.c +++ b/src/vnet/session/session_test.c @@ -506,8 +506,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) action_index - 1); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 1), "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d", res); @@ -561,8 +560,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) * and 3.3.3.3 1234 7.7.7.7 4321 */ res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 3), "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d", res); @@ -570,15 +568,14 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204); rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_lkup, + session_rules_table_lookup4 (srt, &lcl_lkup, &rmt_lkup, lcl_port, rmt_port); SESSION_TEST ((res == 1), "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d", res); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip3, &rmt_ip3, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port); SESSION_TEST ((res == 6), "Lookup 3.3.3.3 1234 7.7.7.7 4321, action " "should be 6 (updated): %d", res); @@ -598,13 +595,12 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d", action_index - 1); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 7), "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should" " be 7 (lpm dst): %d", res); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port + 1, rmt_port); SESSION_TEST ((res == 7), "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d", @@ -645,23 +641,21 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) action_index - 1); if (verbose) - session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4, - TRANSPORT_PROTO_TCP); + session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 3), "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d", res); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port + 1, rmt_port); SESSION_TEST ((res == 9), "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d", res); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port + 1, rmt_port + 1); SESSION_TEST ((res == 8), "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d", @@ -679,8 +673,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) error = session_rules_table_add_del (srt, &args); SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321"); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 3), "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d", res); @@ -691,8 +684,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) error = session_rules_table_add_del (srt, &args); SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *"); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 3), "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d", res); @@ -710,8 +702,7 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input) error = session_rules_table_add_del (srt, &args); SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24"); res = - session_rules_table_lookup4 (srt, TRANSPORT_PROTO_TCP, &lcl_ip, &rmt_ip, - lcl_port, rmt_port); + session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port); SESSION_TEST ((res == 2), "Action should be 2: %d", res); return 0; @@ -959,6 +950,32 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) &rmt_pref.fp_addr.ip4, lcl_port, rmt_port, TRANSPORT_PROTO_TCP, 0); SESSION_TEST ((tc == 0), "optimized lookup should not work (no-rule)"); + + /* + * Test tags. Add/del rule with tag + */ + args.table_args.is_add = 1; + args.table_args.lcl_port = 1234; + args.table_args.lcl.fp_addr.ip4 = lcl_ip; + args.table_args.lcl.fp_len = 16; + args.table_args.rmt.fp_addr.ip4 = rmt_ip; + args.table_args.rmt.fp_len = 16; + args.table_args.tag = format (0, "test_rule"); + error = vnet_session_rule_add_del (&args); + SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 drop " + "tag test_rule"); + 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); + } + args.table_args.is_add = 0; + args.table_args.lcl_port += 1; + SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop " + "tag test_rule"); + return 0; } diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index 1152fbb8e0d..4ec19e50408 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -3215,18 +3215,19 @@ static void *vl_api_session_rule_add_del_t_print u8 *s; char *proto = mp->transport_proto == 0 ? "tcp" : "udp"; s = format (0, "SCRIPT: session_rule_add_del "); + mp->tag[sizeof (mp->tag) - 1] = 0; if (mp->is_ip4) - s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u", + s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u tag %s", mp->appns_index, mp->scope, proto, format_ip4_address, (ip4_address_t *) mp->lcl_ip, mp->lcl_plen, format_ip4_address, (ip4_address_t *) mp->rmt_ip, - mp->rmt_plen, mp->action_index); + mp->rmt_plen, mp->action_index, mp->tag); else - s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u", + s = format (s, "appns %d scope %d %s %U/%d %d %U/%d %d action %u tag %s", mp->appns_index, mp->scope, proto, format_ip6_address, (ip6_address_t *) mp->lcl_ip, mp->lcl_plen, format_ip6_address, (ip6_address_t *) mp->rmt_ip, - mp->rmt_plen, mp->action_index); + mp->rmt_plen, mp->action_index, mp->tag); FINISH; } |