diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/session/application_namespace.c | 8 | ||||
-rw-r--r-- | src/vnet/session/session.api | 78 | ||||
-rw-r--r-- | src/vnet/session/session_api.c | 267 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.c | 29 | ||||
-rw-r--r-- | src/vnet/session/session_sdl.c | 6 | ||||
-rw-r--r-- | src/vnet/session/session_table.c | 11 | ||||
-rw-r--r-- | src/vnet/session/session_table.h | 4 | ||||
-rw-r--r-- | src/vnet/session/session_test.c | 23 |
8 files changed, 403 insertions, 23 deletions
diff --git a/src/vnet/session/application_namespace.c b/src/vnet/session/application_namespace.c index 8b06331d803..2507f37043c 100644 --- a/src/vnet/session/application_namespace.c +++ b/src/vnet/session/application_namespace.c @@ -127,7 +127,7 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a) st = session_table_alloc (); session_table_init (st, FIB_PROTOCOL_MAX); st->is_local = 1; - st->appns_index = app_namespace_index (app_ns); + vec_add1 (st->appns_index, app_namespace_index (app_ns)); app_ns->local_table_index = session_table_index (st); if (a->sock_name) { @@ -173,8 +173,10 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a) if (app_ns->sock_name) vec_free (app_ns->sock_name); - session_lookup_table_cleanup (FIB_PROTOCOL_IP4, app_ns->ip4_fib_index); - session_lookup_table_cleanup (FIB_PROTOCOL_IP6, app_ns->ip6_fib_index); + session_lookup_table_cleanup (FIB_PROTOCOL_IP4, app_ns->ip4_fib_index, + ns_index); + session_lookup_table_cleanup (FIB_PROTOCOL_IP6, app_ns->ip6_fib_index, + ns_index); app_namespace_free (app_ns); } diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api index f678f8bd80f..2805546db52 100644 --- a/src/vnet/session/session.api +++ b/src/vnet/session/session.api @@ -13,7 +13,7 @@ * limitations under the License. */ -option version = "4.0.2"; +option version = "4.0.3"; import "vnet/interface_types.api"; import "vnet/ip/ip_types.api"; @@ -411,6 +411,7 @@ autoreply define session_rule_add_del { */ define session_rules_dump { + option deprecated; u32 client_index; u32 context; }; @@ -434,6 +435,7 @@ define session_rules_dump */ define session_rules_details { + option deprecated; u32 context; vl_api_transport_proto_t transport_proto; vl_api_prefix_t lcl; @@ -446,6 +448,49 @@ define session_rules_details string tag[64]; }; +/** \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_v2_dump +{ + u32 client_index; + u32 context; +}; + +/** \brief Session rules details + @param context - sender context, to match reply w/ request + @param transport_proto - transport protocol + @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 scope - enum that indicates scope of the rule: global or local. + If 0, default is global, 1 is global 2 is local, 3 is both + @param tag - tag + @param count - count of the number of appns_index + @param appns_index - application namespaces where rule is to be applied to + */ +define session_rules_v2_details +{ + u32 context; + vl_api_transport_proto_t transport_proto; + vl_api_prefix_t lcl; + vl_api_prefix_t rmt; + u16 lcl_port; + u16 rmt_port; + u32 action_index; + vl_api_session_rule_scope_t scope; + string tag[64]; + u32 count; + u32 appns_index[count]; +}; + autoreply define session_sdl_add_del { option deprecated; u32 client_index; @@ -500,6 +545,7 @@ define session_sdl_details */ define session_sdl_v2_dump { + option deprecated; u32 client_index; u32 context; }; @@ -514,6 +560,7 @@ define session_sdl_v2_dump */ define session_sdl_v2_details { + option deprecated; u32 context; vl_api_prefix_t rmt; u32 action_index; @@ -521,6 +568,35 @@ define session_sdl_v2_details string tag[64]; }; +/** \brief Dump session sdl v3 + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define session_sdl_v3_dump +{ + u32 client_index; + u32 context; +}; + +/** \brief Session sdl details v3 + @param context - sender context, to match reply w/ request + @param rmt - remote prefix + @param action_index - the only action defined now is forward to + application with index action_index + @param tag - tag + @param count - count of the number of appns_index + @param appns_index - application namespaces where rule is to be applied to + */ +define session_sdl_v3_details +{ + u32 context; + vl_api_prefix_t rmt; + u32 action_index; + string tag[64]; + u32 count; + u32 appns_index[count]; +}; + /* * Local Variables: * eval: (c-set-style "gnu") diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index e54c9b35b4e..c6df47b412b 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -1333,6 +1333,7 @@ vl_api_session_rules_dump_t_handler (vl_api_session_rules_dump_t * mp) vl_api_registration_t *reg; session_table_t *st; u8 tp; + u32 appns_index; reg = vl_api_client_index_to_registration (mp->client_index); if (!reg) @@ -1344,8 +1345,183 @@ vl_api_session_rules_dump_t_handler (vl_api_session_rules_dump_t * mp) { session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, tp); + appns_index = *vec_elt_at_index ( + st->appns_index, + vec_len (st->appns_index) - 1); send_session_rules_table_details ( srt, st->active_fib_proto, tp, st->is_local, + appns_index, reg, mp->context); + } + })); +} + +/* + * session_rules_v2_dunp handler + */ +static void +send_session_rule_v2_details4 (mma_rule_16_t *rule, u8 is_local, + u8 transport_proto, u32 *appns_index, u8 *tag, + vl_api_registration_t *reg, u32 context) +{ + vl_api_session_rules_v2_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; + fib_prefix_t lcl, rmt; + u32 i, appns_index_count = vec_len (appns_index); + + rmp = vl_msg_api_alloc (sizeof (*rmp) + + appns_index_count * sizeof (*appns_index)); + if (!rmp) + return; + clib_memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = + ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_RULES_V2_DETAILS); + rmp->context = context; + + rmp->count = clib_host_to_net_u32 (appns_index_count); + vec_foreach_index (i, appns_index) + { + u32 index = *vec_elt_at_index (appns_index, i); + rmp->appns_index[i] = clib_host_to_net_u32 (index); + } + + clib_memset (&lcl, 0, sizeof (lcl)); + clib_memset (&rmt, 0, sizeof (rmt)); + ip_set (&lcl.fp_addr, &match->lcl_ip, 1); + ip_set (&rmt.fp_addr, &match->rmt_ip, 1); + lcl.fp_len = ip4_mask_to_preflen (&mask->lcl_ip); + rmt.fp_len = ip4_mask_to_preflen (&mask->rmt_ip); + lcl.fp_proto = FIB_PROTOCOL_IP4; + rmt.fp_proto = FIB_PROTOCOL_IP4; + + ip_prefix_encode (&lcl, &rmp->lcl); + ip_prefix_encode (&rmt, &rmp->rmt); + 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_API_LOCAL : SESSION_RULE_SCOPE_API_GLOBAL; + rmp->transport_proto = api_session_transport_proto_encode (transport_proto); + if (tag) + { + clib_memcpy_fast (rmp->tag, tag, vec_len (tag)); + rmp->tag[vec_len (tag)] = 0; + } + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void +send_session_rule_v2_details6 (mma_rule_40_t *rule, u8 is_local, + u8 transport_proto, u32 *appns_index, u8 *tag, + vl_api_registration_t *reg, u32 context) +{ + vl_api_session_rules_v2_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; + fib_prefix_t lcl, rmt; + u32 i, appns_index_count = vec_len (appns_index); + + rmp = vl_msg_api_alloc (sizeof (*rmp) + + appns_index_count * sizeof (*appns_index)); + if (!rmp) + return; + clib_memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = + ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_RULES_V2_DETAILS); + rmp->context = context; + + rmp->count = clib_host_to_net_u32 (appns_index_count); + vec_foreach_index (i, appns_index) + { + u32 index = *vec_elt_at_index (appns_index, i); + rmp->appns_index[i] = clib_host_to_net_u32 (index); + } + + clib_memset (&lcl, 0, sizeof (lcl)); + clib_memset (&rmt, 0, sizeof (rmt)); + ip_set (&lcl.fp_addr, &match->lcl_ip, 0); + ip_set (&rmt.fp_addr, &match->rmt_ip, 0); + lcl.fp_len = ip6_mask_to_preflen (&mask->lcl_ip); + rmt.fp_len = ip6_mask_to_preflen (&mask->rmt_ip); + lcl.fp_proto = FIB_PROTOCOL_IP6; + rmt.fp_proto = FIB_PROTOCOL_IP6; + + ip_prefix_encode (&lcl, &rmp->lcl); + ip_prefix_encode (&rmt, &rmp->rmt); + 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_API_LOCAL : SESSION_RULE_SCOPE_API_GLOBAL; + rmp->transport_proto = api_session_transport_proto_encode (transport_proto); + if (tag) + { + clib_memcpy_fast (rmp->tag, tag, vec_len (tag)); + rmp->tag[vec_len (tag)] = 0; + } + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void +send_session_rules_table_v2_details (session_rules_table_t *srt, u8 fib_proto, + u8 tp, u8 is_local, u32 *appns_index, + vl_api_registration_t *reg, u32 context) +{ + mma_rule_16_t *rule16; + mma_rule_40_t *rule40; + mma_rules_table_16_t *srt16; + mma_rules_table_40_t *srt40; + u32 ri; + + if (is_local || fib_proto == FIB_PROTOCOL_IP4) + { + u8 *tag = 0; + 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_v2_details4 (rule16, is_local, tp, appns_index, tag, + reg, context); + } + } + if (is_local || fib_proto == FIB_PROTOCOL_IP6) + { + u8 *tag = 0; + 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_v2_details6 (rule40, is_local, tp, appns_index, tag, + reg, context); + } + } +} + +static void +vl_api_session_rules_v2_dump_t_handler (vl_api_session_rules_dump_t *mp) +{ + vl_api_registration_t *reg; + session_table_t *st; + u8 tp; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + session_table_foreach (st, ({ + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) + for (tp = 0; tp < TRANSPORT_N_PROTOS; tp++) + { + session_rules_table_t *srt = + srtg_handle_to_srt (st->srtg_handle, tp); + send_session_rules_table_v2_details ( + srt, st->active_fib_proto, tp, st->is_local, st->appns_index, reg, mp->context); } })); @@ -1355,7 +1531,7 @@ typedef struct session_sdl_table_walk_ctx_ { vl_api_registration_t *reg; u32 mp_context; - u32 appns_index; + u32 *appns_index; } session_sdl_table_walk_ctx; static void @@ -1365,7 +1541,8 @@ send_session_sdl_v2_details (u32 fei, ip46_address_t *rmt_ip, u16 fp_len, { session_sdl_table_walk_ctx *ctx = args; vl_api_registration_t *reg = ctx->reg; - u32 appns_index = ctx->appns_index; + u32 appns_index = + *vec_elt_at_index (ctx->appns_index, vec_len (ctx->appns_index) - 1); u32 context = ctx->mp_context; vl_api_session_sdl_v2_details_t *rmp = 0; fib_prefix_t rmt; @@ -1414,7 +1591,6 @@ vl_api_session_sdl_v2_dump_t_handler (vl_api_session_sdl_v2_dump_t *mp) if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { ctx.appns_index = st->appns_index; - if (st->active_fib_proto == FIB_PROTOCOL_IP4) session_sdl_table_walk4 (st->srtg_handle, send_session_sdl_v2_details, &ctx); @@ -1426,12 +1602,90 @@ vl_api_session_sdl_v2_dump_t_handler (vl_api_session_sdl_v2_dump_t *mp) } static void +send_session_sdl_v3_details (u32 fei, ip46_address_t *rmt_ip, u16 fp_len, + u32 action_index, u32 fp_proto, u8 *tag, + void *args) +{ + session_sdl_table_walk_ctx *ctx = args; + vl_api_registration_t *reg = ctx->reg; + u32 context = ctx->mp_context; + vl_api_session_sdl_v3_details_t *rmp = 0; + fib_prefix_t rmt; + u32 appns_index_count, appns_index, i; + + appns_index_count = vec_len (ctx->appns_index); + rmp = vl_msg_api_alloc (sizeof (*rmp) + + appns_index_count * sizeof (appns_index)); + if (!rmp) + return; + clib_memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_V3_DETAILS); + rmp->context = context; + + rmp->count = clib_host_to_net_u32 (appns_index_count); + vec_foreach_index (i, ctx->appns_index) + { + appns_index = *vec_elt_at_index (ctx->appns_index, i); + rmp->appns_index[i] = clib_host_to_net_u32 (appns_index); + } + + clib_memset (&rmt, 0, sizeof (rmt)); + if (fp_proto == FIB_PROTOCOL_IP4) + ip_set (&rmt.fp_addr, &rmt_ip->ip4, 1); + else + ip_set (&rmt.fp_addr, &rmt_ip->ip6, 0); + rmt.fp_len = fp_len; + rmt.fp_proto = fp_proto, + + ip_prefix_encode (&rmt, &rmp->rmt); + rmp->action_index = clib_host_to_net_u32 (action_index); + + if (tag) + { + clib_memcpy_fast (rmp->tag, tag, vec_len (tag)); + rmp->tag[vec_len (tag)] = 0; + } + + vl_api_send_msg (reg, (u8 *) rmp); +} + +static void +vl_api_session_sdl_v3_dump_t_handler (vl_api_session_sdl_v2_dump_t *mp) +{ + vl_api_registration_t *reg; + session_table_t *st; + session_sdl_table_walk_ctx ctx; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + ctx.reg = reg; + ctx.mp_context = mp->context; + + session_table_foreach ( + st, ({ + if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) + { + ctx.appns_index = st->appns_index; + if (st->active_fib_proto == FIB_PROTOCOL_IP4) + session_sdl_table_walk4 (st->srtg_handle, + send_session_sdl_v3_details, &ctx); + else + session_sdl_table_walk6 (st->srtg_handle, + send_session_sdl_v3_details, &ctx); + } + })); +} + +static void send_session_sdl_details (u32 fei, ip46_address_t *lcl_ip, u16 fp_len, u32 action_index, u32 fp_proto, u8 *tag, void *args) { session_sdl_table_walk_ctx *ctx = args; vl_api_registration_t *reg = ctx->reg; - u32 appns_index = ctx->appns_index; + u32 appns_index = + *vec_elt_at_index (ctx->appns_index, vec_len (ctx->appns_index) - 1); u32 context = ctx->mp_context; vl_api_session_sdl_details_t *rmp = 0; fib_prefix_t lcl; @@ -1480,7 +1734,6 @@ vl_api_session_sdl_dump_t_handler (vl_api_session_sdl_dump_t *mp) if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID) { ctx.appns_index = st->appns_index; - if (st->active_fib_proto == FIB_PROTOCOL_IP4) session_sdl_table_walk4 (st->srtg_handle, send_session_sdl_details, &ctx); @@ -2209,6 +2462,10 @@ session_api_hookup (vlib_main_t *vm) am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_V2_DUMP, 1); vl_api_set_msg_thread_safe ( am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_V2_DETAILS, 1); + vl_api_set_msg_thread_safe ( + am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_V3_DUMP, 1); + vl_api_set_msg_thread_safe ( + am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_V3_DETAILS, 1); return 0; } diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 720b94d99e6..fa2051aa8ee 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -1455,7 +1455,7 @@ session_lookup_set_tables_appns (app_namespace_t * app_ns) st = session_table_get_or_alloc (fp, fib_index); if (st) { - st->appns_index = app_namespace_index (app_ns); + vec_add1 (st->appns_index, app_namespace_index (app_ns)); session_lookup_fib_table_lock (fib_index, fp); } } @@ -1945,23 +1945,30 @@ session_lookup_init (void) } void -session_lookup_table_cleanup (u32 fib_proto, u32 fib_index) +session_lookup_table_cleanup (u32 fib_proto, u32 fib_index, u32 ns_index) { session_table_t *st; - u32 table_index; + u32 table_index, appns_index; + int i; session_lookup_fib_table_unlock (fib_index, fib_proto); + table_index = session_lookup_get_index_for_fib (fib_proto, fib_index); + st = session_table_get (table_index); + if (st == 0) + return; if (fib_index_to_lock_count[fib_proto][fib_index] == 0) { - table_index = session_lookup_get_index_for_fib (fib_proto, fib_index); - st = session_table_get (table_index); - if (st) - { - session_table_free (st, fib_proto); - if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index) - fib_index_to_table_index[fib_proto][fib_index] = ~0; - } + session_table_free (st, fib_proto); + if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index) + fib_index_to_table_index[fib_proto][fib_index] = ~0; } + else + vec_foreach_index (i, st->appns_index) + { + appns_index = *vec_elt_at_index (st->appns_index, i); + if (ns_index == appns_index) + vec_del1 (st->appns_index, i); + } } /* diff --git a/src/vnet/session/session_sdl.c b/src/vnet/session/session_sdl.c index 2fd63d1ed8e..f1dfac4e1ab 100644 --- a/src/vnet/session/session_sdl.c +++ b/src/vnet/session/session_sdl.c @@ -244,13 +244,17 @@ session_sdl_table_init (session_table_t *st, u8 fib_proto) session_sdl_block_t *sdlb; u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0; char name[80]; - app_namespace_t *app_ns = app_namespace_get (st->appns_index); + u32 appns_index; + app_namespace_t *app_ns; session_rules_table_group_t *srtg; /* Don't support local table */ if (st->is_local == 1) return; + appns_index = + *vec_elt_at_index (st->appns_index, vec_len (st->appns_index) - 1); + app_ns = app_namespace_get (appns_index); srtg = srtg_instance_alloc (st, 0); srt = srtg->session_rules; sdlb = &srt->sdl_block; diff --git a/src/vnet/session/session_table.c b/src/vnet/session/session_table.c index 5dafe0e633c..f3ec1f90bf6 100644 --- a/src/vnet/session/session_table.c +++ b/src/vnet/session/session_table.c @@ -79,6 +79,7 @@ session_table_free (session_table_t *slt, u8 fib_proto) clib_bihash_free_48_8 (&slt->v6_half_open_hash); } + vec_free (slt->appns_index); pool_put (lookup_tables, slt); } @@ -222,7 +223,17 @@ u8 * format_session_table (u8 *s, va_list *args) { session_table_t *st = va_arg (*args, session_table_t *); + u32 appns_index, i; + s = format (s, "appns index: "); + vec_foreach_index (i, st->appns_index) + { + appns_index = *vec_elt_at_index (st->appns_index, i); + if (i > 0) + s = format (s, ", "); + s = format (s, "%d", appns_index); + } + s = format (s, "\n"); if (clib_bihash_is_initialised_16_8 (&st->v4_session_hash)) { s = format (s, "%U", format_bihash_16_8, &st->v4_session_hash, 0); diff --git a/src/vnet/session/session_table.h b/src/vnet/session/session_table.h index aae4a1c2af5..126e849beae 100644 --- a/src/vnet/session/session_table.h +++ b/src/vnet/session/session_table.h @@ -42,7 +42,7 @@ typedef struct _session_lookup_table u8 is_local; /** Namespace this table belongs to */ - u32 appns_index; + 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 @@ -77,7 +77,7 @@ session_table_t *_get_session_tables (); #define session_table_foreach(VAR, BODY) \ pool_foreach (VAR, _get_session_tables ()) BODY -void session_lookup_table_cleanup (u32 fib_proto, u32 fib_index); +void session_lookup_table_cleanup (u32 fib_proto, u32 fib_index, u32 ns_index); #endif /* SRC_VNET_SESSION_SESSION_TABLE_H_ */ /* diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c index e248dd7010c..14f17761e75 100644 --- a/src/vnet/session/session_test.c +++ b/src/vnet/session/session_test.c @@ -382,6 +382,11 @@ vl_api_session_sdl_v2_details_t_handler (vl_api_session_sdl_v2_details_t *mp) { } +static void +vl_api_session_sdl_v3_details_t_handler (vl_api_session_sdl_v3_details_t *mp) +{ +} + static int api_session_sdl_dump (vat_main_t *vam) { @@ -394,6 +399,24 @@ api_session_sdl_v2_dump (vat_main_t *vam) return -1; } +static int +api_session_sdl_v3_dump (vat_main_t *vam) +{ + return -1; +} + +static void +vl_api_session_rules_v2_details_t_handler ( + vl_api_session_rules_v2_details_t *mp) +{ +} + +static int +api_session_rules_v2_dump (vat_main_t *vam) +{ + return -1; +} + #include <vnet/session/session.api_test.c> /* |