session: add api to dump rules
Change-Id: Ie42fd77e75e86a45cfe5951768c4638f27fdc3aa
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 9f76f8a..f27d51a 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -5626,7 +5626,8 @@
_(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 @@
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)
{
@@ -21641,6 +21711,31 @@
}
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)
{
#if VPP_API_TEST_BUILTIN == 0
@@ -22450,6 +22545,7 @@
_(dns_resolve_name, "<hostname>") \
_(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
"<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
+_(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 326b0c0..c8c5b7e 100644
--- a/src/vnet/session/application_namespace.c
+++ b/src/vnet/session/application_namespace.c
@@ -94,7 +94,9 @@
{
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 @@
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 e6f3b02..8de0922 100644
--- a/src/vnet/session/session.api
+++ b/src/vnet/session/session.api
@@ -397,6 +397,50 @@
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 32ef34b..7ca87a5 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -18,6 +18,7 @@
#include <vnet/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/session_rules_table.h>
+#include <vnet/session/session_table.h>
#include <vnet/vnet_msg_enum.h>
@@ -54,6 +55,7 @@
_(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 @@
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 c55712e..d537b9c 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -162,28 +162,36 @@
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)
{
u32 fib_proto = transport_connection_fib_proto (tc);
@@ -1131,6 +1139,25 @@
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_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 d8f0518..fa89727 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -19,6 +19,7 @@
#include <vnet/session/session_table.h>
#include <vnet/session/stream_session.h>
#include <vnet/session/transport.h>
+#include <vnet/session/application_namespace.h>
stream_session_t *session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl,
ip4_address_t * rmt, u16 lcl_port,
@@ -115,6 +116,7 @@
} 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 cd8502a..f0bd338 100644
--- a/src/vnet/session/session_table.c
+++ b/src/vnet/session/session_table.c
@@ -22,6 +22,12 @@
static session_table_t *lookup_tables;
session_table_t *
+_get_session_tables (void)
+{
+ return lookup_tables;
+}
+
+session_table_t *
session_table_alloc (void)
{
session_table_t *slt;
@@ -61,8 +67,10 @@
* 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 @@
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 6588a43..6cf8159 100644
--- a/src/vnet/session/session_table.h
+++ b/src/vnet/session/session_table.h
@@ -38,6 +38,17 @@
* 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 @@
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* */