diff options
Diffstat (limited to 'src/vnet/adj')
-rw-r--r-- | src/vnet/adj/adj.c | 19 | ||||
-rw-r--r-- | src/vnet/adj/adj.h | 10 | ||||
-rw-r--r-- | src/vnet/adj/adj_bfd.c | 53 | ||||
-rw-r--r-- | src/vnet/adj/adj_dp.h | 42 | ||||
-rw-r--r-- | src/vnet/adj/adj_glean.c | 121 | ||||
-rw-r--r-- | src/vnet/adj/adj_internal.h | 19 | ||||
-rw-r--r-- | src/vnet/adj/adj_mcast.c | 4 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain.c | 82 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain.h | 7 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain_delegate.c | 25 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain_node.c | 35 | ||||
-rw-r--r-- | src/vnet/adj/adj_nbr.c | 60 | ||||
-rw-r--r-- | src/vnet/adj/adj_nsh.c | 2 | ||||
-rw-r--r-- | src/vnet/adj/rewrite.h | 6 |
14 files changed, 294 insertions, 191 deletions
diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index 8808294f7a6..201561fe485 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -34,6 +34,11 @@ vlib_combined_counter_main_t adjacency_counters = { ip_adjacency_t *adj_pool; /** + * The adjacency logger + */ +vlib_log_class_t adj_logger; + +/** * @brief Global Config for enabling per-adjacency counters. * By default these are disabled. */ @@ -64,14 +69,12 @@ ip_adjacency_t * adj_alloc (fib_protocol_t proto) { ip_adjacency_t *adj; - u8 need_barrier_sync = 0; + u8 need_barrier_sync = pool_get_will_expand (adj_pool); vlib_main_t *vm; vm = vlib_get_main(); ASSERT (vm->thread_index == 0); - pool_get_aligned_will_expand (adj_pool, need_barrier_sync, - CLIB_CACHE_LINE_BYTES); /* If the adj_pool will expand, stop the parade. */ if (need_barrier_sync) vlib_worker_thread_barrier_sync (vm); @@ -309,12 +312,12 @@ adj_last_lock_gone (ip_adjacency_t *adj) break; } - vlib_worker_thread_barrier_release(vm); 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 @@ -350,7 +353,6 @@ adj_lock (adj_index_t adj_index) adj = adj_get(adj_index); ASSERT(adj); - ADJ_DBG(adj, "lock"); fib_node_lock(&adj->ia_node); } @@ -367,9 +369,6 @@ adj_unlock (adj_index_t adj_index) adj = adj_get(adj_index); ASSERT(adj); - ADJ_DBG(adj, "unlock"); - ASSERT(adj); - fib_node_unlock(&adj->ia_node); } @@ -650,6 +649,8 @@ adj_module_init (vlib_main_t * vm) vnet_feature_register(adj_feature_update, NULL); + adj_logger = vlib_log_register_class("adj", "adj"); + return (NULL); } @@ -703,7 +704,6 @@ adj_show (vlib_main_t * vm, } else { - /* *INDENT-OFF* */ pool_foreach_index (ai, adj_pool) { if (~0 != sw_if_index && @@ -718,7 +718,6 @@ adj_show (vlib_main_t * vm, FORMAT_IP_ADJACENCY_NONE); } } - /* *INDENT-ON* */ } } return 0; diff --git a/src/vnet/adj/adj.h b/src/vnet/adj/adj.h index c1922c755ec..860193c04ad 100644 --- a/src/vnet/adj/adj.h +++ b/src/vnet/adj/adj.h @@ -165,14 +165,6 @@ typedef enum adj_attr_t_ ADJ_ATTR_SYNC_WALK_ACTIVE = 0, /** - * Packets TX through the midchain do not increment the interface - * counters. This should be used when the adj is associated with an L2 - * interface and that L2 interface is in a bridge domain. In that case - * the packet will have traversed the interface's TX node, and hence have - * been counted, before it traverses ths midchain - */ - ADJ_ATTR_MIDCHAIN_NO_COUNT, - /** * When stacking midchains on a fib-entry extract the choice from the * load-balance returned based on an IP hash of the adj's rewrite */ @@ -195,7 +187,6 @@ typedef enum adj_attr_t_ #define ADJ_ATTR_NAMES { \ [ADJ_ATTR_SYNC_WALK_ACTIVE] = "walk-active", \ - [ADJ_ATTR_MIDCHAIN_NO_COUNT] = "midchain-no-count", \ [ADJ_ATTR_MIDCHAIN_IP_STACK] = "midchain-ip-stack", \ [ADJ_ATTR_MIDCHAIN_LOOPED] = "midchain-looped", \ [ADJ_ATTR_MIDCHAIN_FIXUP_IP4O4_HDR] = "midchain-ip4o4-hdr-fixup", \ @@ -214,7 +205,6 @@ typedef enum adj_flags_t_ { ADJ_FLAG_NONE = 0, ADJ_FLAG_SYNC_WALK_ACTIVE = (1 << ADJ_ATTR_SYNC_WALK_ACTIVE), - ADJ_FLAG_MIDCHAIN_NO_COUNT = (1 << ADJ_ATTR_MIDCHAIN_NO_COUNT), ADJ_FLAG_MIDCHAIN_IP_STACK = (1 << ADJ_ATTR_MIDCHAIN_IP_STACK), ADJ_FLAG_MIDCHAIN_LOOPED = (1 << ADJ_ATTR_MIDCHAIN_LOOPED), ADJ_FLAG_MIDCHAIN_FIXUP_IP4O4_HDR = (1 << ADJ_ATTR_MIDCHAIN_FIXUP_IP4O4_HDR), diff --git a/src/vnet/adj/adj_bfd.c b/src/vnet/adj/adj_bfd.c index 2d787d41ab6..e54ba6d74ae 100644 --- a/src/vnet/adj/adj_bfd.c +++ b/src/vnet/adj/adj_bfd.c @@ -114,9 +114,7 @@ void adj_bfd_notify (bfd_listen_event_e event, const bfd_session_t *session) { - const bfd_udp_key_t *key; adj_bfd_delegate_t *abd; - fib_protocol_t fproto; adj_delegate_t *aed; adj_index_t ai; @@ -129,19 +127,28 @@ adj_bfd_notify (bfd_listen_event_e event, return; } - key = &session->udp.key; - - fproto = (ip46_address_is_ip4 (&key->peer_addr) ? - FIB_PROTOCOL_IP4: - FIB_PROTOCOL_IP6); + switch (session->transport) + { + case BFD_TRANSPORT_UDP4: + case BFD_TRANSPORT_UDP6: + /* + * pick up the same adjacency that the BFD session is using + * to send. The BFD session is holding a lock on this adj. + */ + ai = session->udp.adj_index; + break; + default: + /* + * Don't know what adj this session uses + */ + return; + } - /* - * find the adj that corresponds to the BFD session. - */ - ai = adj_nbr_add_or_lock(fproto, - fib_proto_to_link(fproto), - &key->peer_addr, - key->sw_if_index); + if (INDEX_INVALID == ai) + { + /* No associated Adjacency with the session */ + return; + } switch (event) { @@ -160,13 +167,6 @@ adj_bfd_notify (bfd_listen_event_e event, else { /* - * lock the adj. add the delegate. - * Locking the adj prevents it being removed and thus maintains - * the BFD derived states - */ - adj_lock(ai); - - /* * allocate and init a new delegate struct */ pool_get(abd_pool, abd); @@ -213,14 +213,12 @@ adj_bfd_notify (bfd_listen_event_e event, { /* * has an associated BFD tracking delegate - * remove the BFD tracking delegate, update children, then - * unlock the adj + * remove the BFD tracking delegate, update children */ adj_delegate_remove(ai, ADJ_DELEGATE_BFD); pool_put(abd_pool, abd); adj_bfd_update_walk(ai); - adj_unlock(ai); } /* * else @@ -228,11 +226,6 @@ adj_bfd_notify (bfd_listen_event_e event, */ break; } - - /* - * unlock match of the add-or-lock at the start - */ - adj_unlock(ai); } int @@ -287,9 +280,7 @@ adj_bfd_main_init (vlib_main_t * vm) return (0); } -/* *INDENT-OFF* */ VLIB_INIT_FUNCTION (adj_bfd_main_init)= { .runs_after = VLIB_INITS("bfd_main_init"), }; -/* *INDENT-ON* */ diff --git a/src/vnet/adj/adj_dp.h b/src/vnet/adj/adj_dp.h index aff1a2b1f43..186044b90ad 100644 --- a/src/vnet/adj/adj_dp.h +++ b/src/vnet/adj/adj_dp.h @@ -36,22 +36,36 @@ adj_midchain_ipip44_fixup (vlib_main_t * vm, ip4->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b)); if (PREDICT_TRUE(TUNNEL_ENCAP_DECAP_FLAG_NONE == flags)) - { - ip_csum_t sum; - u16 old,new; - - old = 0; - new = ip4->length; - - sum = ip4->checksum; - sum = ip_csum_update (sum, old, new, ip4_header_t, length); - ip4->checksum = ip_csum_fold (sum); - } + { + if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO)) + { + vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip4 - b->data; + vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TNL_IPIP | + VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM); + } + else + { + ip_csum_t sum; + u16 old,new; + old = 0; + new = ip4->length; + sum = ip4->checksum; + sum = ip_csum_update (sum, old, new, ip4_header_t, length); + ip4->checksum = ip_csum_fold (sum); + } + } else - { + { tunnel_encap_fixup_4o4 (flags, ip4 + 1, ip4); - ip4->checksum = ip4_header_checksum (ip4); - } + if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_GSO)) + { + vnet_buffer2 (b)->outer_l3_hdr_offset = (u8 *) ip4 - b->data; + vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TNL_IPIP | + VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM); + } + else + ip4->checksum = ip4_header_checksum (ip4); + } } static_always_inline void diff --git a/src/vnet/adj/adj_glean.c b/src/vnet/adj/adj_glean.c index e8ca043662f..ceece0d74ed 100644 --- a/src/vnet/adj/adj_glean.c +++ b/src/vnet/adj/adj_glean.c @@ -45,7 +45,7 @@ adj_glean_db_lookup (fib_protocol_t proto, { uword *p; - if (vec_len(adj_gleans[proto]) <= sw_if_index) + if ((proto >= FIB_PROTOCOL_IP_MAX) || vec_len(adj_gleans[proto]) <= sw_if_index) return (ADJ_INDEX_INVALID); p = hash_get_mem (adj_gleans[proto][sw_if_index], nh_addr); @@ -66,6 +66,7 @@ adj_glean_db_insert (fib_protocol_t proto, vlib_worker_thread_barrier_sync(vm); + ASSERT(proto < FIB_PROTOCOL_IP_MAX); vec_validate(adj_gleans[proto], sw_if_index); if (NULL == adj_gleans[proto][sw_if_index]) @@ -186,6 +187,38 @@ adj_glean_update_rewrite_walk (adj_index_t ai, return (ADJ_WALK_RC_CONTINUE); } +static void +adj_glean_walk_proto (fib_protocol_t proto, + u32 sw_if_index, + adj_walk_cb_t cb, + void *data) +{ + adj_index_t ai, *aip, *ais = NULL; + ip46_address_t *conn; + + ASSERT(proto < FIB_PROTOCOL_IP_MAX); + if (vec_len(adj_gleans[proto]) <= sw_if_index || + NULL == adj_gleans[proto][sw_if_index]) + return; + + /* + * Walk first to collect the indices + * then walk the collection. This is safe + * to modifications of the hash table + */ + hash_foreach_mem(conn, ai, adj_gleans[proto][sw_if_index], + ({ + vec_add1(ais, ai); + })); + + vec_foreach(aip, ais) + { + if (ADJ_WALK_RC_STOP == cb(*aip, data)) + break; + } + vec_free(ais); +} + void adj_glean_walk (u32 sw_if_index, adj_walk_cb_t cb, @@ -195,29 +228,7 @@ adj_glean_walk (u32 sw_if_index, FOR_EACH_FIB_IP_PROTOCOL(proto) { - adj_index_t ai, *aip, *ais = NULL; - ip46_address_t *conn; - - if (vec_len(adj_gleans[proto]) <= sw_if_index || - NULL == adj_gleans[proto][sw_if_index]) - continue; - - /* - * Walk first to collect the indices - * then walk the collection. This is safe - * to modifications of the hash table - */ - hash_foreach_mem(conn, ai, adj_gleans[proto][sw_if_index], - ({ - vec_add1(ais, ai); - })); - - vec_foreach(aip, ais) - { - if (ADJ_WALK_RC_STOP == cb(*aip, data)) - break; - } - vec_free(ais); + adj_glean_walk_proto (proto, sw_if_index, cb, data); } } @@ -235,6 +246,7 @@ adj_glean_get (fib_protocol_t proto, ip46_address_t *conn; adj_index_t ai; + ASSERT(proto < FIB_PROTOCOL_IP_MAX); if (vec_len(adj_gleans[proto]) <= sw_if_index || NULL == adj_gleans[proto][sw_if_index]) return (ADJ_INDEX_INVALID); @@ -256,6 +268,7 @@ adj_glean_get_src (fib_protocol_t proto, const ip_adjacency_t *adj; adj_index_t ai; + ASSERT(proto < FIB_PROTOCOL_IP_MAX); if (vec_len(adj_gleans[proto]) <= sw_if_index || NULL == adj_gleans[proto][sw_if_index]) return (NULL); @@ -424,11 +437,59 @@ VNET_SW_INTERFACE_ADD_DEL_FUNCTION(adj_glean_interface_delete); */ static void adj_glean_ethernet_change_mac (ethernet_main_t * em, - u32 sw_if_index, uword opaque) + u32 sw_if_index, + uword opaque) { adj_glean_walk (sw_if_index, adj_glean_update_rewrite_walk, NULL); } +static void +adj_glean_table_bind (fib_protocol_t fproto, + u32 sw_if_index, + u32 itf_fib_index) +{ + /* + * for each glean on the interface trigger a walk back to the children + */ + fib_node_back_walk_ctx_t bw_ctx = { + .fnbw_reason = FIB_NODE_BW_REASON_FLAG_INTERFACE_BIND, + .interface_bind = { + .fnbw_to_fib_index = itf_fib_index, + }, + }; + + adj_glean_walk_proto (fproto, sw_if_index, adj_glean_start_backwalk, &bw_ctx); +} + + +/** + * Callback function invoked when an interface's IPv6 Table + * binding changes + */ +static void +adj_glean_ip6_table_bind (ip6_main_t * im, + uword opaque, + u32 sw_if_index, + u32 new_fib_index, + u32 old_fib_index) +{ + adj_glean_table_bind (FIB_PROTOCOL_IP6, sw_if_index, new_fib_index); +} + +/** + * Callback function invoked when an interface's IPv4 Table + * binding changes + */ +static void +adj_glean_ip4_table_bind (ip4_main_t * im, + uword opaque, + u32 sw_if_index, + u32 new_fib_index, + u32 old_fib_index) +{ + adj_glean_table_bind (FIB_PROTOCOL_IP4, sw_if_index, new_fib_index); +} + u8* format_adj_glean (u8* s, va_list *ap) { @@ -519,4 +580,14 @@ adj_glean_module_init (void) .function_opaque = 0, }; vec_add1 (ethernet_main.address_change_callbacks, ctx); + + ip6_table_bind_callback_t cbt6 = { + .function = adj_glean_ip6_table_bind, + }; + vec_add1 (ip6_main.table_bind_callbacks, cbt6); + + ip4_table_bind_callback_t cbt4 = { + .function = adj_glean_ip4_table_bind, + }; + vec_add1 (ip4_main.table_bind_callbacks, cbt4); } diff --git a/src/vnet/adj/adj_internal.h b/src/vnet/adj/adj_internal.h index 3dbf7e2a371..380af46e22a 100644 --- a/src/vnet/adj/adj_internal.h +++ b/src/vnet/adj/adj_internal.h @@ -31,24 +31,20 @@ /* * Debug macro */ -#ifdef ADJ_DEBUG -#define ADJ_DBG(_adj, _fmt, _args...) \ -{ \ - clib_warning("adj:[%d:%p]:" _fmt, \ - _adj - adj_pool, _adj, \ - ##_args); \ +extern vlib_log_class_t adj_logger; +#define ADJ_DBG(_adj, _fmt, _args...) \ +{ \ + vlib_log_debug(adj_logger, "adj:[%d:%p]:" _fmt, \ + _adj - adj_pool, _adj, \ + ##_args); \ } -#else -#define ADJ_DBG(_e, _fmt, _args...) -#endif /* * Vlib nodes */ extern vlib_node_registration_t adj_nsh_midchain_node; extern vlib_node_registration_t adj_nsh_rewrite_node; -extern vlib_node_registration_t adj_midchain_tx_no_count_node; -extern vlib_node_registration_t adj_midchain_tx_node; +extern vlib_node_registration_t adj_midchain_tx; static inline u32 adj_get_rewrite_node (vnet_link_t linkt) @@ -128,6 +124,7 @@ extern void adj_nbr_remove(adj_index_t ai, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index); +extern u32 adj_nbr_get_n_adjs(vnet_link_t link_type, u32 sw_if_index); extern void adj_glean_remove(ip_adjacency_t *adj); extern void adj_mcast_remove(fib_protocol_t proto, u32 sw_if_index); diff --git a/src/vnet/adj/adj_mcast.c b/src/vnet/adj/adj_mcast.c index a20f61f6f6b..573105b7228 100644 --- a/src/vnet/adj/adj_mcast.c +++ b/src/vnet/adj/adj_mcast.c @@ -82,6 +82,8 @@ adj_mcast_add_or_lock (fib_protocol_t proto, */ vnet_update_adjacency_for_sw_interface(vnm, sw_if_index, adj_get_index(adj)); + + adj_delegate_adj_created(adj); } else { @@ -89,8 +91,6 @@ adj_mcast_add_or_lock (fib_protocol_t proto, adj_lock(adj_get_index(adj)); } - adj_delegate_adj_created(adj); - return (adj_get_index(adj)); } diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c index 9f709ad13be..8e6a940befa 100644 --- a/src/vnet/adj/adj_midchain.c +++ b/src/vnet/adj/adj_midchain.c @@ -75,52 +75,37 @@ adj_get_midchain_node (vnet_link_t link) } static u8 -adj_midchain_get_feature_arc_index_for_link_type (const ip_adjacency_t *adj) +adj_midchain_get_feature_arc_index (const ip_adjacency_t *adj) { - u8 arc = (u8) ~0; switch (adj->ia_link) { case VNET_LINK_IP4: - { - arc = ip4_main.lookup_main.output_feature_arc_index; - break; - } + return ip4_main.lookup_main.output_feature_arc_index; case VNET_LINK_IP6: - { - arc = ip6_main.lookup_main.output_feature_arc_index; - break; - } + return ip6_main.lookup_main.output_feature_arc_index; case VNET_LINK_MPLS: - { - arc = mpls_main.output_feature_arc_index; - break; - } + return mpls_main.output_feature_arc_index; case VNET_LINK_ETHERNET: - { - arc = ethernet_main.output_feature_arc_index; - break; - } + return ethernet_main.output_feature_arc_index; case VNET_LINK_NSH: - { - arc = nsh_main_placeholder.output_feature_arc_index; - break; - } case VNET_LINK_ARP: - ASSERT(0); break; } - - ASSERT (arc != (u8) ~0); - - return (arc); + ASSERT (0); + return (0); } static u32 adj_nbr_midchain_get_tx_node (ip_adjacency_t *adj) { - return ((adj->ia_flags & ADJ_FLAG_MIDCHAIN_NO_COUNT) ? - adj_midchain_tx_no_count_node.index : - adj_midchain_tx_node.index); + return (adj_midchain_tx.index); +} + +static u32 +adj_nbr_midchain_get_next_node (ip_adjacency_t *adj) +{ + return (vnet_feature_get_end_node(adj_midchain_get_feature_arc_index(adj), + adj->rewrite_header.sw_if_index)); } /** @@ -131,17 +116,7 @@ adj_nbr_midchain_get_tx_node (ip_adjacency_t *adj) void adj_midchain_teardown (ip_adjacency_t *adj) { - vlib_main_t *vm = vlib_get_main(); - dpo_reset(&adj->sub_type.midchain.next_dpo); - - vlib_worker_thread_barrier_sync(vm); - adj->ia_cfg_index = vnet_feature_modify_end_node( - adj_midchain_get_feature_arc_index_for_link_type (adj), - adj->rewrite_header.sw_if_index, - vlib_get_node_by_name (vlib_get_main(), - (u8*) "interface-output")->index); - vlib_worker_thread_barrier_release(vm); } /** @@ -155,9 +130,7 @@ adj_midchain_setup (adj_index_t adj_index, const void *data, adj_flags_t flags) { - vlib_main_t *vm = vlib_get_main(); ip_adjacency_t *adj; - u32 tx_node; ASSERT(ADJ_INDEX_INVALID != adj_index); @@ -181,15 +154,6 @@ adj_midchain_setup (adj_index_t adj_index, adj->rewrite_header.flags &= ~VNET_REWRITE_FIXUP_FLOW_HASH; } - tx_node = adj_nbr_midchain_get_tx_node(adj); - - vlib_worker_thread_barrier_sync(vm); - adj->ia_cfg_index = vnet_feature_modify_end_node( - adj_midchain_get_feature_arc_index_for_link_type (adj), - adj->rewrite_header.sw_if_index, - tx_node); - vlib_worker_thread_barrier_release(vm); - /* * stack the midchain on the drop so it's ready to forward in the adj-midchain-tx. * The graph arc used/created here is from the midchain-tx node to the @@ -197,7 +161,7 @@ adj_midchain_setup (adj_index_t adj_index, * node are any output features, then the midchain-tx. from there we * need to get to the stacked child's node. */ - dpo_stack_from_node(tx_node, + dpo_stack_from_node(adj_nbr_midchain_get_tx_node(adj), &adj->sub_type.midchain.next_dpo, drop_dpo_get(vnet_link_to_dpo_proto(adj->ia_link))); } @@ -238,7 +202,7 @@ adj_nbr_midchain_update_rewrite (adj_index_t adj_index, adj_nbr_update_rewrite_internal(adj, IP_LOOKUP_NEXT_MIDCHAIN, adj_get_midchain_node(adj->ia_link), - adj_nbr_midchain_get_tx_node(adj), + adj_nbr_midchain_get_next_node(adj), rewrite); } @@ -260,11 +224,6 @@ adj_nbr_midchain_update_next_node (adj_index_t adj_index, adj->ia_node_index, next_node); - adj->ia_cfg_index = vnet_feature_modify_end_node( - adj_midchain_get_feature_arc_index_for_link_type (adj), - adj->rewrite_header.sw_if_index, - next_node); - vlib_worker_thread_barrier_release(vm); } @@ -284,12 +243,7 @@ adj_nbr_midchain_reset_next_node (adj_index_t adj_index) adj->rewrite_header.next_index = vlib_node_add_next(vlib_get_main(), adj->ia_node_index, - adj_nbr_midchain_get_tx_node(adj)); - - adj->ia_cfg_index = vnet_feature_modify_end_node( - adj_midchain_get_feature_arc_index_for_link_type (adj), - adj->rewrite_header.sw_if_index, - adj_nbr_midchain_get_tx_node(adj)); + adj_nbr_midchain_get_next_node(adj)); vlib_worker_thread_barrier_release(vm); } diff --git a/src/vnet/adj/adj_midchain.h b/src/vnet/adj/adj_midchain.h index 5fb0ee8efb3..eee8c99ae40 100644 --- a/src/vnet/adj/adj_midchain.h +++ b/src/vnet/adj/adj_midchain.h @@ -99,7 +99,7 @@ extern void adj_nbr_midchain_stack(adj_index_t adj_index, * The FIB entry to stack on * * @param fct - * The chain type to use from the fib entry fowarding + * The chain type to use from the fib entry forwarding */ extern void adj_nbr_midchain_stack_on_fib_entry(adj_index_t adj_index, fib_node_index_t fei, @@ -160,6 +160,11 @@ extern void adj_midchain_delegate_restack(adj_index_t ai); */ extern void adj_midchain_delegate_unstack(adj_index_t ai); +/** + * @brief remove a midchain delegate (this stacks it on a drop) + */ +extern void adj_midchain_delegate_remove (adj_index_t ai); + extern u8 adj_is_midchain (adj_index_t ai); #endif diff --git a/src/vnet/adj/adj_midchain_delegate.c b/src/vnet/adj/adj_midchain_delegate.c index 9e788432640..16129ff86ac 100644 --- a/src/vnet/adj/adj_midchain_delegate.c +++ b/src/vnet/adj/adj_midchain_delegate.c @@ -132,6 +132,31 @@ adj_midchain_delegate_stack (adj_index_t ai, } void +adj_midchain_delegate_remove (adj_index_t ai) +{ + adj_midchain_delegate_t *amd; + ip_adjacency_t *adj; + adj_delegate_t *ad; + + /* + * if there's a delegate, it can be removed + */ + adj = adj_get(ai); + ad = adj_delegate_get(adj, ADJ_DELEGATE_MIDCHAIN); + + if (NULL != ad) + { + adj_nbr_midchain_unstack(ai); + + amd = pool_elt_at_index(amd_pool, ad->ad_index); + fib_entry_untrack(amd->amd_fei, amd->amd_sibling); + pool_put(amd_pool, amd); + + adj_delegate_remove (ai, ADJ_DELEGATE_MIDCHAIN); + } +} + +void adj_midchain_delegate_unstack (adj_index_t ai) { adj_nbr_midchain_unstack(ai); diff --git a/src/vnet/adj/adj_midchain_node.c b/src/vnet/adj/adj_midchain_node.c index 170ed19855e..fcc2c6c7647 100644 --- a/src/vnet/adj/adj_midchain_node.c +++ b/src/vnet/adj/adj_midchain_node.c @@ -202,16 +202,20 @@ format_adj_midchain_tx_trace (u8 * s, va_list * args) return (s); } -static uword -adj_midchain_tx (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VLIB_NODE_FN (adj_midchain_tx) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) +{ + return (adj_midchain_tx_inline(vm, node, frame, 1)); +} +VLIB_NODE_FN (tunnel_output) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return (adj_midchain_tx_inline(vm, node, frame, 1)); } -VLIB_REGISTER_NODE (adj_midchain_tx_node) = { - .function = adj_midchain_tx, +VLIB_REGISTER_NODE (adj_midchain_tx) = { .name = "adj-midchain-tx", .vector_size = sizeof (u32), @@ -222,20 +226,23 @@ VLIB_REGISTER_NODE (adj_midchain_tx_node) = { [0] = "error-drop", }, }; +VLIB_REGISTER_NODE (tunnel_output) = { + .name = "tunnel-output", + .vector_size = sizeof (u32), + .format_trace = format_adj_midchain_tx_trace, + .sibling_of = "adj-midchain-tx", +}; -static uword -adj_midchain_tx_no_count (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VLIB_NODE_FN (tunnel_output_no_count) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { return (adj_midchain_tx_inline(vm, node, frame, 0)); } -VLIB_REGISTER_NODE (adj_midchain_tx_no_count_node) = { - .function = adj_midchain_tx_no_count, - .name = "adj-midchain-tx-no-count", +VLIB_REGISTER_NODE (tunnel_output_no_count) = { + .name = "tunnel-output-no-count", .vector_size = sizeof (u32), - .format_trace = format_adj_midchain_tx_trace, .sibling_of = "adj-midchain-tx", }; diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c index 8524c6c83ae..b3a027b7af4 100644 --- a/src/vnet/adj/adj_nbr.c +++ b/src/vnet/adj/adj_nbr.c @@ -105,6 +105,46 @@ adj_nbr_remove (adj_index_t ai, } } +typedef struct adj_nbr_get_n_adjs_walk_ctx_t_ +{ + vnet_link_t linkt; + u32 count; +} adj_nbr_get_n_adjs_walk_ctx_t; + +static adj_walk_rc_t +adj_nbr_get_n_adjs_walk (adj_index_t ai, + void *data) +{ + adj_nbr_get_n_adjs_walk_ctx_t *ctx = data; + const ip_adjacency_t *adj; + + adj = adj_get(ai); + + if (ctx->linkt == adj->ia_link) + ctx->count++; + + return (ADJ_WALK_RC_CONTINUE); +} + +u32 +adj_nbr_get_n_adjs (vnet_link_t link_type, u32 sw_if_index) +{ + adj_nbr_get_n_adjs_walk_ctx_t ctx = { + .linkt = link_type, + }; + fib_protocol_t fproto; + + FOR_EACH_FIB_IP_PROTOCOL(fproto) + { + adj_nbr_walk (sw_if_index, + fproto, + adj_nbr_get_n_adjs_walk, + &ctx); + } + + return (ctx.count); +} + adj_index_t adj_nbr_find (fib_protocol_t nh_proto, vnet_link_t link_type, @@ -492,7 +532,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, fib_walk_sync(FIB_NODE_TYPE_ADJ, walk_ai, &bw_ctx); /* - * fib_walk_sync may allocate a new adjacency and potentially cuase a + * fib_walk_sync may allocate a new adjacency and potentially cause a * realloc for adj_pool. When that happens, adj pointer is no longer * valid here. We refresh the adj pointer accordingly. */ @@ -560,7 +600,7 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj, walk_adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE; } - adj_delegate_adj_modified(adj); + adj_delegate_adj_modified(adj_get(ai)); adj_unlock(ai); adj_unlock(walk_ai); } @@ -753,9 +793,15 @@ adj_nbr_interface_state_change_one (adj_index_t ai, adj_lock (ai); adj = adj_get(ai); - adj->ia_flags |= ADJ_FLAG_SYNC_WALK_ACTIVE; fib_walk_sync(FIB_NODE_TYPE_ADJ, ai, &bw_ctx); + + /* + * fib_walk_sync may allocate a new adjacency and potentially cause a + * realloc for adj_pool. When that happens, adj pointer is no longer + * valid here. We refresh the adj pointer accordingly. + */ + adj = adj_get(ai); adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE; adj_unlock (ai); @@ -863,9 +909,15 @@ adj_nbr_interface_delete_one (adj_index_t ai, adj_lock(ai); adj = adj_get(ai); - adj->ia_flags |= ADJ_FLAG_SYNC_WALK_ACTIVE; fib_walk_sync(FIB_NODE_TYPE_ADJ, ai, &bw_ctx); + + /* + * fib_walk_sync may allocate a new adjacency and potentially cause a + * realloc for adj_pool. When that happens, adj pointer is no longer + * valid here. We refresh the adj pointer accordingly. + */ + adj = adj_get(ai); adj->ia_flags &= ~ADJ_FLAG_SYNC_WALK_ACTIVE; adj_unlock(ai); diff --git a/src/vnet/adj/adj_nsh.c b/src/vnet/adj/adj_nsh.c index 00d945729d8..1b4fa6c15b9 100644 --- a/src/vnet/adj/adj_nsh.c +++ b/src/vnet/adj/adj_nsh.c @@ -190,7 +190,6 @@ VLIB_REGISTER_NODE (adj_nsh_midchain_node) = { }; /* Built-in ip4 tx feature path definition */ -/* *INDENT-OFF* */ VNET_FEATURE_ARC_INIT (nsh_output, static) = { .arc_name = "nsh-output", @@ -204,4 +203,3 @@ VNET_FEATURE_INIT (nsh_tx_drop, static) = .node_name = "error-drop", .runs_before = 0, /* not before any other features */ }; -/* *INDENT-ON* */ diff --git a/src/vnet/adj/rewrite.h b/src/vnet/adj/rewrite.h index 4234986dc37..06b1b00882e 100644 --- a/src/vnet/adj/rewrite.h +++ b/src/vnet/adj/rewrite.h @@ -136,7 +136,7 @@ always_inline void vnet_rewrite_clear_data_internal (vnet_rewrite_header_t * rw, int max_size) { /* Sanity check values carefully for this clib_memset operation */ - ASSERT ((max_size > 0) && (max_size < VLIB_BUFFER_PRE_DATA_SIZE)); + ASSERT ((max_size > 0) && (max_size < VNET_REWRITE_TOTAL_BYTES)); rw->data_bytes = 0; clib_memset (rw->data, 0xfe, max_size); @@ -147,8 +147,8 @@ vnet_rewrite_set_data_internal (vnet_rewrite_header_t * rw, int max_size, void *data, int data_bytes) { /* Sanity check values carefully for this clib_memset operation */ - ASSERT ((max_size > 0) && (max_size < VLIB_BUFFER_PRE_DATA_SIZE)); - ASSERT ((data_bytes >= 0) && (data_bytes < max_size)); + ASSERT ((max_size > 0) && (max_size <= VNET_REWRITE_TOTAL_BYTES)); + ASSERT ((data_bytes >= 0) && (data_bytes <= max_size)); rw->data_bytes = data_bytes; clib_memcpy_fast (rw->data, data, data_bytes); |