X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fsession_lookup.c;h=986832346fc00609d9df5def5a43227fab994d94;hb=07063b8ea;hp=931c3d0f9e2fa27c014b96a8a49dc795cccb2dde;hpb=b5e55a27a46f166f466c7996675542de645eff66;p=vpp.git diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 931c3d0f9e2..986832346fc 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Cisco and/or its affiliates. + * Copyright (c) 2017-2019 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -29,11 +29,6 @@ #include #include -/** - * External vector of per transport virtual functions table - */ -extern transport_proto_vft_t *tp_vfts; - /** * Network namespace index (i.e., fib index) to session lookup table. We * should have one per network protocol type but for now we only support IP4/6 @@ -305,6 +300,32 @@ session_lookup_del_session_endpoint (u32 table_index, } } +int +session_lookup_del_session_endpoint2 (session_endpoint_t * sep) +{ + fib_protocol_t fib_proto; + session_table_t *st; + session_kv4_t kv4; + session_kv6_t kv6; + + fib_proto = sep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + st = session_table_get_for_fib_index (fib_proto, sep->fib_index); + if (!st) + return -1; + if (sep->is_ip4) + { + make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port, + sep->transport_proto); + return clib_bihash_add_del_16_8 (&st->v4_session_hash, &kv4, 0); + } + else + { + make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port, + sep->transport_proto); + return clib_bihash_add_del_48_8 (&st->v6_session_hash, &kv6, 0); + } +} + /** * Delete transport connection from session table * @@ -338,11 +359,13 @@ session_lookup_del_connection (transport_connection_t * tc) } int -session_lookup_del_session (stream_session_t * s) +session_lookup_del_session (session_t * s) { - transport_proto_t tp = session_get_transport_proto (s); transport_connection_t *ts; - ts = tp_vfts[tp].get_connection (s->connection_index, s->thread_index); + ts = transport_get_connection (session_get_transport_proto (s), + s->connection_index, s->thread_index); + if (!ts || (ts->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP)) + return 0; return session_lookup_del_connection (ts); } @@ -371,7 +394,7 @@ session_lookup_action_to_handle (u32 action_index) } } -static stream_session_t * +static session_t * session_lookup_app_listen_session (u32 app_index, u8 fib_proto, u8 transport_proto) { @@ -384,7 +407,7 @@ session_lookup_app_listen_session (u32 app_index, u8 fib_proto, fib_proto, transport_proto); } -static stream_session_t * +static session_t * session_lookup_action_to_session (u32 action_index, u8 fib_proto, u8 transport_proto) { @@ -396,7 +419,7 @@ session_lookup_action_to_session (u32 action_index, u8 fib_proto, } /** UNUSED */ -stream_session_t * +session_t * session_lookup_rules_table_session4 (session_table_t * st, u8 proto, ip4_address_t * lcl, u16 lcl_port, ip4_address_t * rmt, u16 rmt_port) @@ -412,7 +435,7 @@ session_lookup_rules_table_session4 (session_table_t * st, u8 proto, } /** UNUSED */ -stream_session_t * +session_t * session_lookup_rules_table_session6 (session_table_t * st, u8 proto, ip6_address_t * lcl, u16 lcl_port, ip6_address_t * rmt, u16 rmt_port) @@ -614,7 +637,7 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep) return SESSION_INVALID_HANDLE; } -static inline stream_session_t * +static inline session_t * session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl, u16 lcl_port, u8 proto, u8 use_wildcard) { @@ -655,18 +678,18 @@ session_lookup_listener4_i (session_table_t * st, ip4_address_t * lcl, return 0; } -stream_session_t * +session_t * session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl, u16 lcl_port, - u8 proto) + u8 proto, u8 use_wildcard) { session_table_t *st; st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index); if (!st) return 0; - return session_lookup_listener4_i (st, lcl, lcl_port, proto, 0); + return session_lookup_listener4_i (st, lcl, lcl_port, proto, use_wildcard); } -static stream_session_t * +static session_t * session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl, u16 lcl_port, u8 proto, u8 ip_wildcard) { @@ -698,21 +721,21 @@ session_lookup_listener6_i (session_table_t * st, ip6_address_t * lcl, return 0; } -stream_session_t * +session_t * session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl, u16 lcl_port, - u8 proto) + u8 proto, u8 use_wildcard) { session_table_t *st; st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index); if (!st) return 0; - return session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); + return session_lookup_listener6_i (st, lcl, lcl_port, proto, use_wildcard); } /** * Lookup listener, exact or proxy (inaddr_any:0) match */ -stream_session_t * +session_t * session_lookup_listener (u32 table_index, session_endpoint_t * sep) { session_table_t *st; @@ -728,6 +751,27 @@ session_lookup_listener (u32 table_index, session_endpoint_t * sep) return 0; } +/** + * Lookup listener wildcard match + */ +session_t * +session_lookup_listener_wildcard (u32 table_index, session_endpoint_t * sep) +{ + session_table_t *st; + st = session_table_get (table_index); + if (!st) + return 0; + if (sep->is_ip4) + return session_lookup_listener4_i (st, &sep->ip.ip4, sep->port, + sep->transport_proto, + 1 /* use_wildcard */ ); + else + return session_lookup_listener6_i (st, &sep->ip.ip6, sep->port, + sep->transport_proto, + 1 /* use_wildcard */ ); + return 0; +} + int session_lookup_add_half_open (transport_connection_t * tc, u64 value) { @@ -812,12 +856,10 @@ session_lookup_half_open_handle (transport_connection_t * tc) transport_connection_t * session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4) { - u32 sst; - if (handle != HALF_OPEN_LOOKUP_INVALID_VALUE) { - sst = session_type_from_proto_and_ip (proto, is_ip4); - return tp_vfts[sst].get_half_open (handle & 0xFFFFFFFF); + u32 sst = session_type_from_proto_and_ip (proto, is_ip4); + return transport_get_half_open (sst, handle & 0xFFFFFFFF); } return 0; } @@ -856,7 +898,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, { session_table_t *st; session_kv4_t kv4; - stream_session_t *s; + session_t *s; u32 action_index; int rv; @@ -877,8 +919,8 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, return 0; } s = session_get (kv4.value & 0xFFFFFFFFULL, thread_index); - return tp_vfts[proto].get_connection (s->connection_index, - thread_index); + return transport_get_connection (proto, s->connection_index, + thread_index); } /* @@ -886,7 +928,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, */ rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4); if (rv == 0) - return tp_vfts[proto].get_half_open (kv4.value & 0xFFFFFFFF); + return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF); /* * Check the session rules table @@ -902,7 +944,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, } if ((s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4, proto))) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -911,7 +953,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl, */ s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1); if (s) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -938,7 +980,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, { session_table_t *st; session_kv4_t kv4; - stream_session_t *s; + session_t *s; u32 action_index; int rv; @@ -954,8 +996,8 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, if (rv == 0) { s = session_get_from_handle (kv4.value); - return tp_vfts[proto].get_connection (s->connection_index, - s->thread_index); + return transport_get_connection (proto, s->connection_index, + s->thread_index); } /* @@ -963,7 +1005,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, */ rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4); if (rv == 0) - return tp_vfts[proto].get_half_open (kv4.value & 0xFFFFFFFF); + return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF); /* * Check the session rules table @@ -976,7 +1018,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, return 0; if ((s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4, proto))) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -985,7 +1027,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, */ s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1); if (s) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -1003,13 +1045,13 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl, * * Typically used by dgram connections */ -stream_session_t * +session_t * session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt, u16 lcl_port, u16 rmt_port, u8 proto) { session_table_t *st; session_kv4_t kv4; - stream_session_t *s; + session_t *s; u32 action_index; int rv; @@ -1079,7 +1121,7 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, u8 * result) { session_table_t *st; - stream_session_t *s; + session_t *s; session_kv6_t kv6; u32 action_index; int rv; @@ -1099,14 +1141,14 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, return 0; } s = session_get (kv6.value & 0xFFFFFFFFULL, thread_index); - return tp_vfts[proto].get_connection (s->connection_index, - thread_index); + return transport_get_connection (proto, s->connection_index, + thread_index); } /* Try half-open connections */ rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6); if (rv == 0) - return tp_vfts[proto].get_half_open (kv6.value & 0xFFFFFFFF); + return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF); /* Check the session rules table */ action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl, @@ -1120,14 +1162,14 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl, } if ((s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6, proto))) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } /* If nothing is found, check if any listener is available */ s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); if (s) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -1154,7 +1196,7 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, u8 proto) { session_table_t *st; - stream_session_t *s; + session_t *s; session_kv6_t kv6; u32 action_index; int rv; @@ -1168,14 +1210,14 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, if (rv == 0) { s = session_get_from_handle (kv6.value); - return tp_vfts[proto].get_connection (s->connection_index, - s->thread_index); + return transport_get_connection (proto, s->connection_index, + s->thread_index); } /* Try half-open connections */ rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6); if (rv == 0) - return tp_vfts[proto].get_half_open (kv6.value & 0xFFFFFFFF); + return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF); /* Check the session rules table */ action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl, @@ -1186,14 +1228,14 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, return 0; if ((s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6, proto))) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } /* If nothing is found, check if any listener is available */ s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1); if (s) - return tp_vfts[proto].get_listener (s->connection_index); + return transport_get_listener (proto, s->connection_index); return 0; } @@ -1211,13 +1253,13 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl, * * Typically used by dgram connections */ -stream_session_t * +session_t * session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt, u16 lcl_port, u16 rmt_port, u8 proto) { session_table_t *st; session_kv6_t kv6; - stream_session_t *s; + session_t *s; u32 action_index; int rv; @@ -1247,7 +1289,7 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt, return 0; } -clib_error_t * +int vnet_session_rule_add_del (session_rule_add_del_args_t * args) { app_namespace_t *app_ns = app_namespace_get (args->appns_index); @@ -1255,29 +1297,26 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args) session_table_t *st; u32 fib_index; u8 fib_proto; - clib_error_t *error; + int rv = 0; if (!app_ns) - return clib_error_return_code (0, VNET_API_ERROR_APP_INVALID_NS, 0, - "invalid app ns"); + return VNET_API_ERROR_APP_INVALID_NS; + if (args->scope > 3) - return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0, - "invalid scope"); + return VNET_API_ERROR_INVALID_VALUE; + 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"); + return VNET_API_ERROR_INVALID_VALUE; + 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); 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 ((rv = session_rules_table_add_del (srt, &args->table_args))) + return rv; } if (args->scope & SESSION_RULE_SCOPE_LOCAL) { @@ -1286,9 +1325,9 @@ vnet_session_rule_add_del (session_rule_add_del_args_t * args) args->table_args.lcl_port = 0; st = app_namespace_get_local_table (app_ns); srt = &st->session_rules[args->transport_proto]; - error = session_rules_table_add_del (srt, &args->table_args); + rv = session_rules_table_add_del (srt, &args->table_args); } - return error; + return rv; } /** @@ -1304,7 +1343,7 @@ session_lookup_set_tables_appns (app_namespace_t * app_ns) 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); + st = session_table_get_or_alloc (fp, fib_index); if (st) st->appns_index = app_namespace_index (app_ns); } @@ -1314,9 +1353,9 @@ u8 * format_ip4_session_lookup_kvp (u8 * s, va_list * args) { clib_bihash_kv_16_8_t *kvp = va_arg (*args, clib_bihash_kv_16_8_t *); - u32 is_local = va_arg (*args, u32), app_wrk_index, session_index; + u32 is_local = va_arg (*args, u32); v4_connection_key_t *key = (v4_connection_key_t *) kvp->key; - stream_session_t *session; + session_t *session; app_worker_t *app_wrk; const u8 *app_name; u8 *str = 0; @@ -1334,8 +1373,8 @@ format_ip4_session_lookup_kvp (u8 * s, va_list * args) } else { - local_session_parse_handle (kvp->value, &app_wrk_index, &session_index); - app_wrk = app_worker_get (app_wrk_index); + session = session_get_from_handle (kvp->value); + app_wrk = app_worker_get (session->app_wrk_index); app_name = application_name_from_index (app_wrk->app_index); str = format (0, "[%U] %U:%d", format_transport_proto_short, key->proto, format_ip4_address, &key->src, @@ -1395,7 +1434,9 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, u8 fib_proto, is_add = 1, *ns_id = 0; u8 *tag = 0; app_namespace_t *app_ns; - clib_error_t *error; + int rv; + + session_cli_return_if_not_enabled (); clib_memset (&lcl_ip, 0, sizeof (lcl_ip)); clib_memset (&rmt_ip, 0, sizeof (rmt_ip)); @@ -1478,6 +1519,7 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; session_rule_add_del_args_t args = { + .transport_proto = proto, .table_args.lcl.fp_addr = lcl_ip, .table_args.lcl.fp_len = lcl_plen, .table_args.lcl.fp_proto = fib_proto, @@ -1492,9 +1534,11 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input, .appns_index = appns_index, .scope = scope, }; - error = vnet_session_rule_add_del (&args); + if ((rv = vnet_session_rule_add_del (&args))) + return clib_error_return (0, "rule add del returned %u", rv); + vec_free (tag); - return error; + return 0; } /* *INDENT-OFF* */ @@ -1544,6 +1588,8 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input, session_table_t *st; u8 *ns_id = 0, fib_proto; + session_cli_return_if_not_enabled (); + clib_memset (&lcl_ip, 0, sizeof (lcl_ip)); clib_memset (&rmt_ip, 0, sizeof (rmt_ip)); while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)