From 6c36f53ff0419d27f3e5720a42e0b43d5e7157f0 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 3 Nov 2017 18:32:34 -0700 Subject: [PATCH] session: add api to dump rules Change-Id: Ie42fd77e75e86a45cfe5951768c4638f27fdc3aa Signed-off-by: Florin Coras --- src/vat/api_format.c | 98 ++++++++++++++++++++++++- src/vnet/session/application_namespace.c | 5 +- src/vnet/session/session.api | 44 ++++++++++++ src/vnet/session/session_api.c | 120 +++++++++++++++++++++++++++++++ src/vnet/session/session_lookup.c | 47 +++++++++--- src/vnet/session/session_lookup.h | 2 + src/vnet/session/session_table.c | 41 +++++++---- src/vnet/session/session_table.h | 19 ++++- 8 files changed, 350 insertions(+), 26 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 9f76f8a51ca..f27d51ab7c7 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -5626,7 +5626,8 @@ _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply) \ _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply) \ _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply) \ _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply) \ -_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) +_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \ +_(SESSION_RULES_DETAILS, session_rules_details) #define foreach_standalone_reply_msg \ _(SW_INTERFACE_EVENT, sw_interface_event) \ @@ -21552,6 +21553,75 @@ api_dns_name_server_add_del (vat_main_t * vam) return ret; } +static void +vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp) +{ + vat_main_t *vam = &vat_main; + + if (mp->is_ip4) + { + print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d", + 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); + } + else + { + print (vam->ofp, "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d", + 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); + } +} + +static void +vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t * + mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t *node = NULL; + struct in6_addr ip6; + struct in_addr ip4; + + if (VAT_JSON_ARRAY != vam->json_tree.type) + { + ASSERT (VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array (&vam->json_tree); + } + node = vat_json_array_add (&vam->json_tree); + vat_json_init_object (node); + + vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0); + vat_json_object_add_uint (node, "appns_index", + clib_net_to_host_u32 (mp->appns_index)); + vat_json_object_add_uint (node, "transport_proto", mp->transport_proto); + vat_json_object_add_uint (node, "scope", mp->scope); + vat_json_object_add_uint (node, "action_index", + clib_net_to_host_u32 (mp->action_index)); + vat_json_object_add_uint (node, "lcl_port", + clib_net_to_host_u16 (mp->lcl_port)); + vat_json_object_add_uint (node, "rmt_port", + 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); + if (mp->is_ip4) + { + clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4)); + vat_json_object_add_ip4 (node, "lcl_ip", ip4); + clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4)); + vat_json_object_add_ip4 (node, "rmt_ip", ip4); + } + else + { + clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6)); + vat_json_object_add_ip6 (node, "lcl_ip", ip6); + clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6)); + vat_json_object_add_ip6 (node, "rmt_ip", ip6); + } +} + static int api_session_rule_add_del (vat_main_t * vam) { @@ -21640,6 +21710,31 @@ api_session_rule_add_del (vat_main_t * vam) return ret; } +static int +api_session_rules_dump (vat_main_t * vam) +{ + vl_api_session_rules_dump_t *mp; + vl_api_control_ping_t *mp_ping; + int ret; + + if (!vam->json_output) + { + print (vam->ofp, "%=20s", "Session Rules"); + } + + M (SESSION_RULES_DUMP, mp); + /* send it... */ + S (mp); + + /* Use a control ping for synchronization */ + MPING (CONTROL_PING, mp_ping); + S (mp_ping); + + /* Wait for a reply... */ + W (ret); + return ret; +} + static int q_or_quit (vat_main_t * vam) { @@ -22450,6 +22545,7 @@ _(dns_name_server_add_del, " [del]") \ _(dns_resolve_name, "") \ _(session_rule_add_del, "[add|del] proto / " \ " / action ") \ +_(session_rules_dump, "") \ /* List of command functions, CLI names map directly to functions */ #define foreach_cli_function \ diff --git a/src/vnet/session/application_namespace.c b/src/vnet/session/application_namespace.c index 326b0c0146f..c8c5b7edd23 100644 --- a/src/vnet/session/application_namespace.c +++ b/src/vnet/session/application_namespace.c @@ -94,7 +94,9 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t * a) { app_ns = app_namespace_alloc (a->ns_id); st = session_table_alloc (); - session_table_init (st); + session_table_init (st, FIB_PROTOCOL_MAX); + st->is_local = 1; + st->appns_index = app_namespace_index (app_ns); app_ns->local_table_index = session_table_index (st); } app_ns->ns_secret = a->secret; @@ -103,6 +105,7 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t * a) fib_table_find (FIB_PROTOCOL_IP4, a->ip4_fib_id); app_ns->ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, a->ip6_fib_id); + session_lookup_set_tables_appns (app_ns); } else { diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api index e6f3b02005d..8de09226365 100644 --- a/src/vnet/session/session.api +++ b/src/vnet/session/session.api @@ -397,6 +397,50 @@ autoreply define session_rule_add_del { u8 scope; }; +/** \brief Dump session rules + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define session_rules_dump +{ + u32 client_index; + u32 context; +}; + +/** \brief Session rules details + @param context - sender context, to match reply w/ request + @param transport_proto - transport protocol (0 - tcp 1 - udp) + @param is_ip4 - flag to indicate if ip addresses are ip4 or 6 + @param lcl_ip - local ip + @param lcl_plen - local prefix length + @param rmt_ip - remote ip + @param rmt_ple - remote prefix length + @param lcl_port - local port + @param rmt_port - remote port + @param action_index - the only action defined now is forward to + application with index action_index + @param appns_index - application namespace where rule is to be applied + to + @param scope - flag that indicates scope of the rule: global or local. + If 0, default is global, 1 is global 2 is local, 3 is + both + */ +define session_rules_details +{ + u32 context; + u8 transport_proto; + u8 is_ip4; + u8 lcl_ip[16]; + u8 lcl_plen; + u8 rmt_ip[16]; + u8 rmt_plen; + u16 lcl_port; + u16 rmt_port; + u32 action_index; + u32 appns_index; + u8 scope; +}; + /* * Local Variables: * eval: (c-set-style "gnu") diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 32ef34b0952..7ca87a512a3 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -54,6 +55,7 @@ _(CONNECT_SOCK, connect_sock) \ _(SESSION_ENABLE_DISABLE, session_enable_disable) \ _(APP_NAMESPACE_ADD_DEL, app_namespace_add_del) \ _(SESSION_RULE_ADD_DEL, session_rule_add_del) \ +_(SESSION_RULES_DUMP, session_rules_dump) \ static int send_add_segment_callback (u32 api_client_index, const u8 * segment_name, @@ -816,6 +818,124 @@ vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp) 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, + unix_shared_memory_queue_t * q, u32 context) +{ + vl_api_session_rules_details_t *rmp = 0; + session_mask_or_match_4_t *match = + (session_mask_or_match_4_t *) & rule->match; + session_mask_or_match_4_t *mask = + (session_mask_or_match_4_t *) & rule->mask; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS); + rmp->context = context; + + rmp->is_ip4 = 1; + clib_memcpy (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip)); + clib_memcpy (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip)); + rmp->lcl_plen = ip4_mask_to_preflen (&mask->lcl_ip); + rmp->rmt_plen = ip4_mask_to_preflen (&mask->rmt_ip); + 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 = + 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); + + 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, + unix_shared_memory_queue_t * q, u32 context) +{ + vl_api_session_rules_details_t *rmp = 0; + session_mask_or_match_6_t *match = + (session_mask_or_match_6_t *) & rule->match; + session_mask_or_match_6_t *mask = + (session_mask_or_match_6_t *) & rule->mask; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS); + rmp->context = context; + + rmp->is_ip4 = 0; + clib_memcpy (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip)); + clib_memcpy (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip)); + rmp->lcl_plen = ip6_mask_to_preflen (&mask->lcl_ip); + rmp->rmt_plen = ip6_mask_to_preflen (&mask->rmt_ip); + 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->transport_proto = transport_proto; + rmp->appns_index = clib_host_to_net_u32 (appns_index); + + 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, + 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; + + for (tp = 0; tp < TRANSPORT_N_PROTO; tp++) + { + 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* */ + } + } +} + +static void +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; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + /* *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); + })); + /* *INDENT-ON* */ +} + static clib_error_t * application_reaper_cb (u32 client_index) { diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index c55712ea850..d537b9c1c82 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -162,27 +162,35 @@ make_v6_ss_kv_from_tc (session_kv6_t * kv, transport_connection_t * t) session_type_from_proto_and_ip (t->proto, 0)); } - static session_table_t * -session_table_get_or_alloc_for_connection (transport_connection_t * tc) +session_table_get_or_alloc (u8 fib_proto, u8 fib_index) { session_table_t *st; - u32 table_index, fib_proto = transport_connection_fib_proto (tc); - if (vec_len (fib_index_to_table_index[fib_proto]) <= tc->fib_index) + u32 table_index; + if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index) { st = session_table_alloc (); table_index = session_table_index (st); - vec_validate (fib_index_to_table_index[fib_proto], tc->fib_index); - fib_index_to_table_index[fib_proto][tc->fib_index] = table_index; + vec_validate (fib_index_to_table_index[fib_proto], fib_index); + fib_index_to_table_index[fib_proto][fib_index] = table_index; + st->active_fib_proto = fib_proto; return st; } else { - table_index = fib_index_to_table_index[fib_proto][tc->fib_index]; + table_index = fib_index_to_table_index[fib_proto][fib_index]; return session_table_get (table_index); } } +static session_table_t * +session_table_get_or_alloc_for_connection (transport_connection_t * tc) +{ + u32 fib_proto; + fib_proto = transport_connection_fib_proto (tc); + return session_table_get_or_alloc (fib_proto, tc->fib_index); +} + static session_table_t * session_table_get_for_connection (transport_connection_t * tc) { @@ -1131,6 +1139,25 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args) return error; } +/** + * Mark (global) tables as pertaining to app ns + */ +void +session_lookup_set_tables_appns (app_namespace_t * app_ns) +{ + session_table_t *st; + u32 fib_index; + u8 fp; + + for (fp = 0; fp < ARRAY_LEN (fib_index_to_table_index); fp++) + { + fib_index = app_namespace_get_fib_index (app_ns, fp); + st = session_table_get_for_fib_index (fp, fib_index); + if (st) + st->appns_index = app_namespace_index (app_ns); + } +} + u8 * format_ip4_session_lookup_kvp (u8 * s, va_list * args) { @@ -1430,11 +1457,13 @@ session_lookup_init (void) session_table_t *st = session_table_alloc (); vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP4], 0); fib_index_to_table_index[FIB_PROTOCOL_IP4][0] = session_table_index (st); - session_table_init (st); + st->active_fib_proto = FIB_PROTOCOL_IP4; + session_table_init (st, FIB_PROTOCOL_IP4); st = session_table_alloc (); vec_validate (fib_index_to_table_index[FIB_PROTOCOL_IP6], 0); fib_index_to_table_index[FIB_PROTOCOL_IP6][0] = session_table_index (st); - session_table_init (st); + st->active_fib_proto = FIB_PROTOCOL_IP6; + session_table_init (st, FIB_PROTOCOL_IP6); } /* diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h index d8f0518c192..fa89727e2fe 100644 --- a/src/vnet/session/session_lookup.h +++ b/src/vnet/session/session_lookup.h @@ -19,6 +19,7 @@ #include #include #include +#include stream_session_t *session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt, u16 lcl_port, @@ -115,6 +116,7 @@ typedef struct _session_rule_add_del_args } session_rule_add_del_args_t; clib_error_t *vnet_session_rule_add_del (session_rule_add_del_args_t * args); +void session_lookup_set_tables_appns (app_namespace_t * app_ns); void session_lookup_init (void); diff --git a/src/vnet/session/session_table.c b/src/vnet/session/session_table.c index cd8502aa13d..f0bd338ec64 100644 --- a/src/vnet/session/session_table.c +++ b/src/vnet/session/session_table.c @@ -21,6 +21,12 @@ */ static session_table_t *lookup_tables; +session_table_t * +_get_session_tables (void) +{ + return lookup_tables; +} + session_table_t * session_table_alloc (void) { @@ -61,8 +67,10 @@ session_table_get (u32 table_index) * otherwise it uses defaults above. */ void -session_table_init (session_table_t * slt) +session_table_init (session_table_t * slt, u8 fib_proto) { + u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0; + #define _(af,table,parm,value) \ u32 configured_##af##_##table##_table_##parm = value; foreach_hash_table_parameter; @@ -75,19 +83,24 @@ session_table_init (session_table_t * slt) foreach_hash_table_parameter; #undef _ - clib_bihash_init_16_8 (&slt->v4_session_hash, "v4 session table", - configured_v4_session_table_buckets, - configured_v4_session_table_memory); - clib_bihash_init_48_8 (&slt->v6_session_hash, "v6 session table", - configured_v6_session_table_buckets, - configured_v6_session_table_memory); - clib_bihash_init_16_8 (&slt->v4_half_open_hash, "v4 half-open table", - configured_v4_halfopen_table_buckets, - configured_v4_halfopen_table_memory); - clib_bihash_init_48_8 (&slt->v6_half_open_hash, "v6 half-open table", - configured_v6_halfopen_table_buckets, - configured_v6_halfopen_table_memory); - + if (fib_proto == FIB_PROTOCOL_IP4 || all) + { + clib_bihash_init_16_8 (&slt->v4_session_hash, "v4 session table", + configured_v4_session_table_buckets, + configured_v4_session_table_memory); + clib_bihash_init_16_8 (&slt->v4_half_open_hash, "v4 half-open table", + configured_v4_halfopen_table_buckets, + configured_v4_halfopen_table_memory); + } + if (fib_proto == FIB_PROTOCOL_IP6 || all) + { + clib_bihash_init_48_8 (&slt->v6_session_hash, "v6 session table", + configured_v6_session_table_buckets, + configured_v6_session_table_memory); + clib_bihash_init_48_8 (&slt->v6_half_open_hash, "v6 half-open table", + configured_v6_halfopen_table_buckets, + configured_v6_halfopen_table_memory); + } session_rules_table_init (&slt->session_rules); } diff --git a/src/vnet/session/session_table.h b/src/vnet/session/session_table.h index 6588a43aa14..6cf815991a9 100644 --- a/src/vnet/session/session_table.h +++ b/src/vnet/session/session_table.h @@ -38,6 +38,17 @@ typedef struct _session_lookup_table * Per fib proto and transport proto session rules tables */ session_rules_table_t session_rules; + + /** Flag that indicates if table has local scope */ + u8 is_local; + + /** Namespace this table belongs to */ + u32 appns_index; + + /** For global tables only one fib proto is active. This is a + * byproduct of fib table ids not necessarily being the same for + * identical fib idices of v4 and v6 fib protos */ + u8 active_fib_proto; } session_table_t; #define SESSION_TABLE_INVALID_INDEX ((u32)~0) @@ -55,7 +66,13 @@ void ip4_session_table_walk (clib_bihash_16_8_t * hash, session_table_t *session_table_alloc (void); session_table_t *session_table_get (u32 table_index); u32 session_table_index (session_table_t * slt); -void session_table_init (session_table_t * slt); +void session_table_init (session_table_t * slt, u8 fib_proto); + +/* Internal, try not to use it! */ +session_table_t *_get_session_tables (); + +#define session_table_foreach(VAR, BODY) \ + pool_foreach(VAR, _get_session_tables (), BODY) #endif /* SRC_VNET_SESSION_SESSION_TABLE_H_ */ /* *INDENT-ON* */ -- 2.16.6