summaryrefslogtreecommitdiffstats
path: root/src/vnet/tls
AgeCommit message (Collapse)AuthorFilesLines
2020-01-08tls: improve connection formatingFlorin Coras1-13/+43
Type: feature Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: Iea8abe33cf33036267ccaf58760abc2f48470202
2020-01-03tls: add features.yamlFlorin Coras1-0/+14
Type: docs Signed-off-by: Florin Coras <fcoras@cisco.com> Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com> Change-Id: I847463fd38b9d569d2607b8a17f6d45a04b6fe09
2020-01-02session: fix listener global endpoint lookupFlorin Coras1-1/+1
Type: fix Ensure listeners for app transport protocols are added to lookup tables using their session endpoints instead of their transport connections, which can override the network connection id in the transport connection. Change-Id: I56fa3666bb1422c0799fc7143cd099751ff6e2e6 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-11-18session: extra checks in session validationSrikanth Akula1-2/+2
Type: fix Adding few extra checks while doign session validationwq! Signed-off-by: Srikanth Akula <srakula@cisco.com> Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I4d18b5ad97d1802ce38a07aeb56b5f35939c1187
2019-10-30tls: fifo size is u32Dave Wallace1-3/+10
- unformat_memory_size() writes to a uword * - Limit cli input to u32 Type: fix Signed-off-by: Dave Wallace <dwallacelf@gmail.com> Change-Id: I453a5633e04f9ee6f2f1a843634f99063a81579b
2019-10-30tls: fix on tcp connection resetZeyu Zhang1-2/+10
VPP would fail in tcp_connection_reset() if the tls or app session was just created. Type: fix Change-Id: I45d107f57e4f3fc468c15ca3392d5e1c413bd690 Signed-off-by: Zeyu Zhang <zeyu.zhang@intel.com>
2019-10-12tls: allow disconnects from main threadFlorin Coras1-1/+4
Type: fix Use api with explicit thread index to retrieve tls contex on close. Change-Id: Ibdc4338747300b7fc8f91ef3e10bcd48ce7ae366 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-10-09hsa: use crypto_engine_type_t for TLSNathan Skrzypczak2-12/+12
Type: refactor This patch does the following conversions TLS_ENGINE_X -> CRYPTO_ENGINE_X tls_engine_type_t -> crypto_engine_t It does not change numbering of engines Change-Id: I872dfaec3a6713bf4229c84d1ffd98b8b2419995 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
2019-10-09session: Add certificate storeNathan Skrzypczak2-0/+3
Type: feature This changes the behavior of both API calls APPLICATION_TLS_CERT_ADD & APPLICATION_TLS_KEY_ADD certificates and keys aren't bound to an app, they are passed to it via connect / listen using the message queue. This should be followed by a per protocol (QUIC/TLS) crypto_context store to save devrived structs Change-Id: I36873bc8b63b5c72776c69e8cd9febc9cae31882 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
2019-08-09tls: mark as no lookup transportFlorin Coras1-0/+2
Type:fix Also fix transport close while handshake is ongoing. Change-Id: I004c56d2297d0847c2cb77202f8fba3edaacad29 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-08-09tls: handle transport resetFlorin Coras1-1/+6
Type:fix Change-Id: I5994fb53dc4b9fd58920b3d67472c38b41db27c2 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-08-08tls: fix close with dataFlorin Coras2-1/+20
Type:fix Also changes the way the ctx is freed. TLS now waits for tcp delete notification before freeing the ctx. Change-Id: I2f606a9ce7b3755ae9d11d6fe714fe11b65dcb98 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-07-27session: define connection id lengthFlorin Coras1-4/+5
Type:feature To be used by transports overwriting the connection id. Change-Id: Ia5dbd9dccc2e3eb62e602514b24882ddc12ff1f2 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-07-26session tcp: handle rxt and acks as custom eventsFlorin Coras1-1/+1
Type: feature Control ack generation and retransmissions with session layer scheduler. Change-Id: Iacdf9f84ab81f44851980aa45a83e75f29be2b7b Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-07-24tls: handle engine listen failureFlorin Coras1-1/+12
Type:fix Change-Id: I528b7cfcb7a6aada94ee3649378e6fbe84d2e4e6 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-07-12tls quic: reduce default segment sizesAloys Augustin1-1/+1
This reduces the memory required by tls and quic, allowing to run them (and their tests) in more constrained environments by default. Change-Id: I954081c725fb4f5f173db1f8e76922d957c5b0a2 Signed-off-by: Aloys Augustin <aloaugus@cisco.com> Type: fix
2019-07-12session: add thread index to all formattersAloys Augustin1-0/+2
Add a thread_index argument to half-open and listener session formatters because QUIC can have listeners and half-open sessions in any thread. Change-Id: I1de60e35ece4c68ba8cfdd6b63f211bc620d687b Signed-off-by: Aloys Augustin <aloaugus@cisco.com> Type: feature
2019-06-27session: Add transport vft protocol optionsNathan Skrzypczak1-3/+5
Type: refactor Change-Id: I4e0afc206e4871596c2ed8a6ca00914a379f1526 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
2019-06-17session: use listener_handle instead of listener_indexNathan Skrzypczak1-2/+3
Type: refactor Change-Id: I97fa59a0ba0b6b7a98698926020ffffcf6ae6ba3 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
2019-05-07add TLS endpoint functionYu Ping1-0/+26
a bit like QUIC, and the added function can get the endpoint info in TLS, so that the VCL layer can get those info correctly Change-Id: Ied7aa3077087c1814499364dfa7654a088ad9910 Signed-off-by: Yu Ping <ping.yu@intel.com>
2019-04-18tls: allow engines to customize closeFlorin Coras2-18/+26
Change-Id: I11ac3e4f59206902e5dfc326f815c877c5dd6643 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-04-02session: use app cb function wrappersFlorin Coras1-7/+3
Change-Id: I77ad9eb4d4c7699397aa4be6a973ef37c60db4c5 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-03-25tls: make first segment and fifo size configurableFlorin Coras2-5/+14
Change-Id: I6169ebdd3ac2d5d77fd2e12068c8aab6d8072c03 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-03-11tls: fixes and improvementsFlorin Coras1-27/+32
- disconnect sessions through session layer apis instead of directly notifying the app worker. - improve cli - increase fifo sizes for tls app Change-Id: I8a7d2865b3b00724e2a9da29fa4a906ea867da9b Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-03-07session/tls: remove unused t_app_index fieldFlorin Coras1-2/+0
Change-Id: Idbf7f3a57dc399798b8dba9463daeb7d66470ab1 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-03-07session: use transport custom tx for app transportsFlorin Coras1-12/+13
Change-Id: I675f7090fa6b2ffdfb4ee748df858bfb7e39ce5a Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-03-07session: cleanup instances of deprecated io evtsFlorin Coras1-5/+5
Change-Id: Iad119e05ae5e570fbfcf66747c95822cee647c99 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-20tls: add vcl testFlorin Coras1-0/+5
Change-Id: If4c7efaf6506a827e7a95a56c2f6b6060df03fa1 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-18tls: fix openssl/mbedtls use of app_wrk indexFlorin Coras2-15/+15
Change-Id: I7ccc948357d815a1bd4279a7079cf4db2949183c Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-18session: move fifo allocation logic to app workerFlorin Coras1-31/+16
Change-Id: I1662ec4b5503cb64a8a86a2441842311d959b3a6 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-11session: cleanup application interfaceFlorin Coras2-6/+8
Change-Id: I89d240753b3f3c5e984aa303a7c8fa35fa59bf7f Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-09tls: move test certificates to separate header fileFlorin Coras2-9/+88
Change-Id: I543cb78e268d7a4a7fba590d305351ec79f4e4da Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-09session: refactor listen logicFlorin Coras2-5/+6
Make app-listener the handle for app listens. Consequently transport and local listen sessions are now associated to the app-listener. Change-Id: I9397a26d42cccb100970b6b4794c15bac2e11465 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-06transport: cleanupFlorin Coras1-3/+3
- move transport specific types to transport_types - add transport wrapper functions for interaction with transport protocol vfts Change-Id: I93f70d884585fc2f41c4a605e310c80e8a8972f2 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-02-04session: cleanup part 1Florin Coras2-38/+38
Rename core data structures. This will break compatibility for out of tree builtin apps. - stream_session_t to session_t - server_rx/tx_fifo to rx/tx_fifo - stream_session.h to session_types.h - update copyright Change-Id: I414097c6e28bcbea866fbf13b8773c7db3f49325 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-01-17tls: preallocate app sessions on connect/acceptFlorin Coras2-10/+22
Avoid allocating session and possibly reallocating thread session pool on builtin session rx. Change-Id: I70e7c604678b44ce8d22603489e247a2c5faa439 Signed-off-by: Florin Coras <fcoras@cisco.com>
2019-01-03Fix an issue in tls.cPing Yu1-1/+3
Curernt code will overwrite parent_app_api_context, and defer the setting after this value is used in callback. Change-Id: Ie16e432fd0f4214e6deff3aa3b58b3be824b0331 Signed-off-by: Ping Yu <ping.yu@intel.com>
2018-12-28session: free session after transport and app confirmFlorin Coras1-2/+2
In addition to that, a bit of refactoring. Change-Id: Iea1eabc2167bcdef185ec53bc09bae087c5398e6 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-11-30session: segment handle in accept/connect notificationsFlorin Coras1-2/+2
Change-Id: I03884b6cde9d4c38ae13d1994fd8d37d44016ef0 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-11-14Remove c-11 memcpy checks from perf-critical codeDave Barach1-2/+2
Change-Id: Id4f37f5d4a03160572954a416efa1ef9b3d79ad1 Signed-off-by: Dave Barach <dave@barachs.net>
2018-10-28session: extend connect api for internal appsFlorin Coras1-5/+5
Change-Id: Ie4c5cfc4c97acb321a46b4df589dc44de1b616ba Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-10-23c11 safe string handling supportDave Barach1-5/+5
Change-Id: Ied34720ca5a6e6e717eea4e86003e854031b6eab Signed-off-by: Dave Barach <dave@barachs.net>
2018-10-18tls: fix connection failures/interrupts at scale (VPP-1464)Florin Coras1-12/+18
Change-Id: I0bc4062c1fd3202ee201acb36a2bb14fc6ee1543 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-10-16tls: fix multi threaded medium scale test (VPP-1457)Florin Coras1-1/+4
- ensure session enqueue epoch does not wrap between two enqueues - use 3 states for echo clients app, to distinguish between starting and closing phases - force tcp fin retransmit if out of buffers while sending a fin Change-Id: I6f2cab46affd1148aba2a33fb6d58bcc54f32805 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-10-02tls: fix disconnects for sessions with pending dataFlorin Coras2-13/+59
TLS can enqueue events to itself when app session queue cannot be entirely drained. If a pending disconnect is handled before any such event, session layer may try to dequeue data on deallocated sessions. Change-Id: I5bfc4d53ce95bc16b6a01e1b0e644aafa1ca311b Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-09-15tls: use application interface apisFlorin Coras1-15/+23
This also exposes app to tls sessions. As a result "sh session verbose" will show for each tls session both the application's session (app to tls) and the tls session (tls to tcp). Change-Id: I1e65c63362ce58f314e762d7db78b44479e1e3a5 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-09-10session: lock app worker mq for io eventsFlorin Coras1-1/+1
Also fixes vcl client/server stats and closing procedure. Change-Id: I7d5a274ea0a3c8ea13062bf61bf402248dfe1a19 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-09-08session: detect namespace for transport appsFlorin Coras1-0/+1
Change-Id: I770607cb213d538a29d7bd5762682981b01e9d18 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-09-07session: fix reentrant listensFlorin Coras1-8/+9
Change-Id: I72d400401a308012b43513179870823f6f921e44 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-09-06session: support multiple worker bindsFlorin Coras1-8/+8
Allows app workers to listen on the same session endpoint. Incoming connects are spread across the workers in a round-robin fashion Change-Id: Ib5f5817230d9abc6127a85cdbdcad70d980c0f7f Signed-off-by: Florin Coras <fcoras@cisco.com>
an class="k">return (adj); } static int adj_index_is_special (adj_index_t adj_index) { if (ADJ_INDEX_INVALID == adj_index) return (!0); return (0); } u8* format_adj_flags (u8 * s, va_list * args) { adj_flags_t af; adj_attr_t at; af = va_arg (*args, int); if (ADJ_FLAG_NONE == af) { return (format(s, "None")); } FOR_EACH_ADJ_ATTR(at) { if (af & (1 << at)) { s = format(s, "%s ", adj_attr_names[at]); } } return (s); } /** * @brief Pretty print helper function for formatting specific adjacencies. * @param s - input string to format * @param args - other args passed to format function such as: * - vnet_main_t * - ip_lookup_main_t * - adj_index */ u8 * format_ip_adjacency (u8 * s, va_list * args) { format_ip_adjacency_flags_t fiaf; ip_adjacency_t * adj; u32 adj_index; adj_index = va_arg (*args, u32); fiaf = va_arg (*args, format_ip_adjacency_flags_t); if (!adj_is_valid(adj_index)) return format(s, "<invalid adjacency>"); adj = adj_get(adj_index); switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_REWRITE: case IP_LOOKUP_NEXT_BCAST: s = format (s, "%U", format_adj_nbr, adj_index, 0); break; case IP_LOOKUP_NEXT_ARP: s = format (s, "%U", format_adj_nbr_incomplete, adj_index, 0); break; case IP_LOOKUP_NEXT_GLEAN: s = format (s, "%U", format_adj_glean, adj_index, 0); break; case IP_LOOKUP_NEXT_MIDCHAIN: s = format (s, "%U", format_adj_midchain, adj_index, 2); break; case IP_LOOKUP_NEXT_MCAST: s = format (s, "%U", format_adj_mcast, adj_index, 0); break; case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: s = format (s, "%U", format_adj_mcast_midchain, adj_index, 0); break; case IP_LOOKUP_NEXT_DROP: case IP_LOOKUP_NEXT_PUNT: case IP_LOOKUP_NEXT_LOCAL: case IP_LOOKUP_NEXT_ICMP_ERROR: case IP_LOOKUP_N_NEXT: break; } if (fiaf & FORMAT_IP_ADJACENCY_DETAIL) { vlib_counter_t counts; vlib_get_combined_counter(&adjacency_counters, adj_index, &counts); s = format (s, "\n flags:%U", format_adj_flags, adj->ia_flags); s = format (s, "\n counts:[%Ld:%Ld]", counts.packets, counts.bytes); s = format (s, "\n locks:%d", adj->ia_node.fn_locks); s = format(s, "\n delegates:"); s = adj_delegate_format(s, adj); s = format(s, "\n children:"); if (fib_node_list_get_size(adj->ia_node.fn_children)) { s = format(s, "\n "); s = fib_node_children_format(adj->ia_node.fn_children, s); } } return s; } int adj_recursive_loop_detect (adj_index_t ai, fib_node_index_t **entry_indicies) { ip_adjacency_t * adj; adj = adj_get(ai); switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_REWRITE: case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_GLEAN: case IP_LOOKUP_NEXT_MCAST: case IP_LOOKUP_NEXT_BCAST: case IP_LOOKUP_NEXT_DROP: case IP_LOOKUP_NEXT_PUNT: case IP_LOOKUP_NEXT_LOCAL: case IP_LOOKUP_NEXT_ICMP_ERROR: case IP_LOOKUP_N_NEXT: /* * these adjacency types are terminal graph nodes, so there's no * possibility of a loop down here. */ break; case IP_LOOKUP_NEXT_MIDCHAIN: case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: return (adj_ndr_midchain_recursive_loop_detect(ai, entry_indicies)); } return (0); } /* * adj_last_lock_gone * * last lock/reference to the adj has gone, we no longer need it. */ static void adj_last_lock_gone (ip_adjacency_t *adj) { vlib_main_t * vm = vlib_get_main(); ASSERT(0 == fib_node_list_get_size(adj->ia_node.fn_children)); ADJ_DBG(adj, "last-lock-gone"); adj_delegate_adj_deleted(adj); vlib_worker_thread_barrier_sync (vm); switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_MIDCHAIN: adj_midchain_teardown(adj); /* FALL THROUGH */ case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_REWRITE: case IP_LOOKUP_NEXT_BCAST: /* * complete and incomplete nbr adjs */ adj_nbr_remove(adj_get_index(adj), adj->ia_nh_proto, adj->ia_link, &adj->sub_type.nbr.next_hop, adj->rewrite_header.sw_if_index); break; case IP_LOOKUP_NEXT_GLEAN: adj_glean_remove(adj); break; case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: adj_midchain_teardown(adj); /* FALL THROUGH */ case IP_LOOKUP_NEXT_MCAST: adj_mcast_remove(adj->ia_nh_proto, adj->rewrite_header.sw_if_index); break; case IP_LOOKUP_NEXT_DROP: case IP_LOOKUP_NEXT_PUNT: case IP_LOOKUP_NEXT_LOCAL: case IP_LOOKUP_NEXT_ICMP_ERROR: case IP_LOOKUP_N_NEXT: /* * type not stored in any DB from which we need to remove it */ break; } fib_node_deinit(&adj->ia_node); ASSERT(0 == vec_len(adj->ia_delegates)); vec_free(adj->ia_delegates); pool_put(adj_pool, adj); vlib_worker_thread_barrier_release(vm); } u32 adj_dpo_get_urpf (const dpo_id_t *dpo) { ip_adjacency_t *adj; adj = adj_get(dpo->dpoi_index); return (adj->rewrite_header.sw_if_index); } u16 adj_dpo_get_mtu (const dpo_id_t *dpo) { ip_adjacency_t *adj; adj = adj_get(dpo->dpoi_index); return (adj->rewrite_header.max_l3_packet_bytes); } void adj_lock (adj_index_t adj_index) { ip_adjacency_t *adj; if (adj_index_is_special(adj_index)) { return; } adj = adj_get(adj_index); ASSERT(adj); fib_node_lock(&adj->ia_node); } void adj_unlock (adj_index_t adj_index) { ip_adjacency_t *adj; if (adj_index_is_special(adj_index)) { return; } adj = adj_get(adj_index); ASSERT(adj); fib_node_unlock(&adj->ia_node); } u32 adj_child_add (adj_index_t adj_index, fib_node_type_t child_type, fib_node_index_t child_index) { ASSERT(ADJ_INDEX_INVALID != adj_index); if (adj_index_is_special(adj_index)) { return (~0); } return (fib_node_child_add(FIB_NODE_TYPE_ADJ, adj_index, child_type, child_index)); } void adj_child_remove (adj_index_t adj_index, u32 sibling_index) { if (adj_index_is_special(adj_index)) { return; } fib_node_child_remove(FIB_NODE_TYPE_ADJ, adj_index, sibling_index); } /* * Context for the walk to update the cached feature flags. */ typedef struct adj_feature_update_t_ { u8 arc; u8 enable; } adj_feature_update_ctx_t; static adj_walk_rc_t adj_feature_update_walk_cb (adj_index_t ai, void *arg) { adj_feature_update_ctx_t *ctx = arg; ip_adjacency_t *adj; adj = adj_get(ai); /* * this ugly mess matches the feature arc that is changing with affected * adjacencies */ if (((ctx->arc == ip6_main.lookup_main.output_feature_arc_index) && (VNET_LINK_IP6 == adj->ia_link)) || ((ctx->arc == ip4_main.lookup_main.output_feature_arc_index) && (VNET_LINK_IP4 == adj->ia_link)) || ((ctx->arc == mpls_main.output_feature_arc_index) && (VNET_LINK_MPLS == adj->ia_link))) { vnet_feature_main_t *fm = &feature_main; vnet_feature_config_main_t *cm; cm = &fm->feature_config_mains[ctx->arc]; if (ctx->enable) adj->rewrite_header.flags |= VNET_REWRITE_HAS_FEATURES; else adj->rewrite_header.flags &= ~VNET_REWRITE_HAS_FEATURES; adj->ia_cfg_index = vec_elt (cm->config_index_by_sw_if_index, adj->rewrite_header.sw_if_index); } return (ADJ_WALK_RC_CONTINUE); } static void adj_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable, void *data) { /* * Walk all the adjacencies on the interface to update the cached * 'has-features' flag */ adj_feature_update_ctx_t ctx = { .arc = arc_index, .enable = is_enable, }; adj_walk (sw_if_index, adj_feature_update_walk_cb, &ctx); } static adj_walk_rc_t adj_mtu_update_walk_cb (adj_index_t ai, void *arg) { ip_adjacency_t *adj; adj = adj_get(ai); vnet_rewrite_update_mtu (vnet_get_main(), adj->ia_link, &adj->rewrite_header); adj_delegate_adj_modified(adj); /** * Backwalk to all Path MTU trackers, casual like .. */ { fib_node_back_walk_ctx_t bw_ctx = { .fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_MTU, }; fib_walk_async(FIB_NODE_TYPE_ADJ, ai, FIB_WALK_PRIORITY_LOW, &bw_ctx); } return (ADJ_WALK_RC_CONTINUE); } static clib_error_t * adj_mtu_update (vnet_main_t * vnm, u32 sw_if_index, u32 flags) { adj_walk (sw_if_index, adj_mtu_update_walk_cb, NULL); return (NULL); } VNET_SW_INTERFACE_MTU_CHANGE_FUNCTION(adj_mtu_update); /** * @brief Walk the Adjacencies on a given interface */ void adj_walk (u32 sw_if_index, adj_walk_cb_t cb, void *ctx) { /* * walk all the neighbor adjacencies */ fib_protocol_t proto; FOR_EACH_FIB_IP_PROTOCOL(proto) { adj_nbr_walk(sw_if_index, proto, cb, ctx); adj_mcast_walk(sw_if_index, proto, cb, ctx); } } /** * @brief Return the link type of the adjacency */ vnet_link_t adj_get_link_type (adj_index_t ai) { const ip_adjacency_t *adj; adj = adj_get(ai); return (adj->ia_link); } /** * @brief Return the sw interface index of the adjacency. */ u32 adj_get_sw_if_index (adj_index_t ai) { const ip_adjacency_t *adj; adj = adj_get(ai); return (adj->rewrite_header.sw_if_index); } /** * @brief Return true if the adjacency is 'UP', i.e. can be used for forwarding * 0 is down, !0 is up. */ int adj_is_up (adj_index_t ai) { return (adj_bfd_is_up(ai)); } /** * @brief Return the rewrite string of the adjacency */ const u8* adj_get_rewrite (adj_index_t ai) { vnet_rewrite_header_t *rw; ip_adjacency_t *adj; adj = adj_get(ai); rw = &adj->rewrite_header; ASSERT (rw->data_bytes != 0xfefe); return (rw->data - rw->data_bytes); } static fib_node_t * adj_get_node (fib_node_index_t index) { ip_adjacency_t *adj; adj = adj_get(index); return (&adj->ia_node); } #define ADJ_FROM_NODE(_node) \ ((ip_adjacency_t*)((char*)_node - STRUCT_OFFSET_OF(ip_adjacency_t, ia_node))) static void adj_node_last_lock_gone (fib_node_t *node) { adj_last_lock_gone(ADJ_FROM_NODE(node)); } static fib_node_back_walk_rc_t adj_back_walk_notify (fib_node_t *node, fib_node_back_walk_ctx_t *ctx) { ip_adjacency_t *adj; adj = ADJ_FROM_NODE(node); switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_MIDCHAIN: adj_midchain_delegate_restack(adj_get_index(adj)); break; case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_REWRITE: case IP_LOOKUP_NEXT_BCAST: case IP_LOOKUP_NEXT_GLEAN: case IP_LOOKUP_NEXT_MCAST: case IP_LOOKUP_NEXT_MCAST_MIDCHAIN: case IP_LOOKUP_NEXT_DROP: case IP_LOOKUP_NEXT_PUNT: case IP_LOOKUP_NEXT_LOCAL: case IP_LOOKUP_NEXT_ICMP_ERROR: case IP_LOOKUP_N_NEXT: /* * Que pasa. yo soj en el final! */ ASSERT(0); break; } return (FIB_NODE_BACK_WALK_CONTINUE); } /* * Adjacency's graph node virtual function table */ static const fib_node_vft_t adj_vft = { .fnv_get = adj_get_node, .fnv_last_lock = adj_node_last_lock_gone, .fnv_back_walk = adj_back_walk_notify, }; static clib_error_t * adj_module_init (vlib_main_t * vm) { fib_node_register_type(FIB_NODE_TYPE_ADJ, &adj_vft); adj_nbr_module_init(); adj_glean_module_init(); adj_midchain_module_init(); adj_mcast_module_init(); vnet_feature_register(adj_feature_update, NULL); adj_logger = vlib_log_register_class("adj", "adj"); return (NULL); } VLIB_INIT_FUNCTION (adj_module_init); static clib_error_t * adj_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { adj_index_t ai = ADJ_INDEX_INVALID; u32 sw_if_index = ~0; int summary = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%d", &ai)) ; else if (unformat (input, "summary") || unformat (input, "sum")) summary = 1; else if (unformat (input, "%U", unformat_vnet_sw_interface, vnet_get_main(), &sw_if_index)) ; else break; } if (summary) { vlib_cli_output (vm, "Number of adjacencies: %d", pool_elts(adj_pool)); vlib_cli_output (vm, "Per-adjacency counters: %s", (adj_are_counters_enabled() ? "enabled": "disabled")); } else { if (ADJ_INDEX_INVALID != ai) { if (pool_is_free_index(adj_pool, ai)) { vlib_cli_output (vm, "adjacency %d invalid", ai); return 0; } vlib_cli_output (vm, "[@%d] %U", ai, format_ip_adjacency, ai, FORMAT_IP_ADJACENCY_DETAIL); } else { /* *INDENT-OFF* */ pool_foreach_index (ai, adj_pool) { if (~0 != sw_if_index && sw_if_index != adj_get_sw_if_index(ai)) { } else { vlib_cli_output (vm, "[@%d] %U", ai, format_ip_adjacency, ai, FORMAT_IP_ADJACENCY_NONE); } } /* *INDENT-ON* */ } } return 0; } /*? * Show all adjacencies. * @cliexpar * @cliexstart{sh adj} * [@0] * [@1] glean: loop0 * [@2] ipv4 via 1.0.0.2 loop0: IP4: 00:00:22:aa:bb:cc -> 00:00:11:aa:bb:cc * [@3] mpls via 1.0.0.2 loop0: MPLS: 00:00:22:aa:bb:cc -> 00:00:11:aa:bb:cc * [@4] ipv4 via 1.0.0.3 loop0: IP4: 00:00:22:aa:bb:cc -> 00:00:11:aa:bb:cc * [@5] mpls via 1.0.0.3 loop0: MPLS: 00:00:22:aa:bb:cc -> 00:00:11:aa:bb:cc * @cliexend ?*/ VLIB_CLI_COMMAND (adj_show_command, static) = { .path = "show adj", .short_help = "show adj [<adj_index>] [interface] [summary]", .function = adj_show, }; /** * @brief CLI invoked function to enable/disable per-adj counters */ static clib_error_t * adj_cli_counters_set (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { clib_error_t *error = NULL; int enable = ~0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "enable")) enable = 1; else if (unformat (input, "disable")) enable = 0; else break; } if (enable != ~0) { /* user requested something sensible */ adj_per_adj_counters = enable; } else { error = clib_error_return (0, "specify 'enable' or 'disable'"); } return (error); } /*? * Enable/disable per-adjacency counters. This is optional because it comes * with a non-negligible performance cost. ?*/ VLIB_CLI_COMMAND (adj_cli_counters_set_command, static) = { .path = "adjacency counters", .short_help = "adjacency counters [enable|disable]", .function = adj_cli_counters_set, };