diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/adj/adj.h | 10 | ||||
-rw-r--r-- | src/vnet/adj/adj_internal.h | 4 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain.c | 82 | ||||
-rw-r--r-- | src/vnet/adj/adj_midchain_node.c | 35 | ||||
-rw-r--r-- | src/vnet/adj/adj_nbr.c | 40 | ||||
-rw-r--r-- | src/vnet/config.c | 27 | ||||
-rw-r--r-- | src/vnet/config.h | 6 | ||||
-rw-r--r-- | src/vnet/feature/feature.c | 60 | ||||
-rw-r--r-- | src/vnet/feature/feature.h | 4 | ||||
-rw-r--r-- | src/vnet/gre/gre.c | 3 | ||||
-rw-r--r-- | src/vnet/gre/interface.c | 9 | ||||
-rw-r--r-- | src/vnet/interface.c | 31 | ||||
-rw-r--r-- | src/vnet/interface_funcs.h | 4 | ||||
-rw-r--r-- | src/vnet/ipip/ipip.c | 6 | ||||
-rw-r--r-- | src/vnet/ipip/sixrd.c | 3 | ||||
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 162 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.c | 4 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.h | 8 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_itf.c | 8 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_itf.h | 1 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.h | 3 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_tun.c | 128 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_tun.h | 1 | ||||
-rw-r--r-- | src/vnet/mpls/mpls_tunnel.c | 4 |
24 files changed, 352 insertions, 291 deletions
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_internal.h b/src/vnet/adj/adj_internal.h index 3dbf7e2a371..6842bc4147e 100644 --- a/src/vnet/adj/adj_internal.h +++ b/src/vnet/adj/adj_internal.h @@ -47,8 +47,7 @@ */ 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 +127,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_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_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..293badefd7d 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, diff --git a/src/vnet/config.c b/src/vnet/config.c index c9d4909cdeb..4ff001a17f8 100644 --- a/src/vnet/config.c +++ b/src/vnet/config.c @@ -119,6 +119,12 @@ find_config_with_features (vlib_main_t * vm, vec_add1 (config_string, next_index); } + /* Add the end node index to the config string so that it is part of + * the key used to detect string sharing. If this is not included then + * a modification of the end node would affect all the user of a shared + * string. */ + vec_add1 (config_string, end_node_index); + /* See if config string is unique. */ p = hash_get_mem (cm->config_string_hash, config_string); if (p) @@ -250,6 +256,15 @@ vnet_config_del (vnet_config_main_t * cm, u32 config_id) } u32 +vnet_config_reset_end_node (vlib_main_t *vm, vnet_config_main_t *cm, u32 ci) +{ + cm->end_node_indices_by_user_index[ci] = cm->default_end_node_index; + + return ( + vnet_config_modify_end_node (vm, cm, ci, cm->default_end_node_index)); +} + +u32 vnet_config_modify_end_node (vlib_main_t * vm, vnet_config_main_t * cm, u32 config_string_heap_index, u32 end_node_index) @@ -304,6 +319,18 @@ vnet_config_modify_end_node (vlib_main_t * vm, } u32 +vnet_config_get_end_node (vlib_main_t *vm, vnet_config_main_t *cm, + u32 config_string_heap_index) +{ + if (config_string_heap_index >= vec_len (cm->end_node_indices_by_user_index)) + return cm->default_end_node_index; + if (~0 == cm->end_node_indices_by_user_index[config_string_heap_index]) + return cm->default_end_node_index; + + return (cm->end_node_indices_by_user_index[config_string_heap_index]); +} + +u32 vnet_config_add_feature (vlib_main_t * vm, vnet_config_main_t * cm, u32 config_string_heap_index, diff --git a/src/vnet/config.h b/src/vnet/config.h index ccbbbf433e2..9b01b4a433e 100644 --- a/src/vnet/config.h +++ b/src/vnet/config.h @@ -169,6 +169,12 @@ u32 vnet_config_modify_end_node (vlib_main_t * vm, u32 config_string_heap_index, u32 end_node_index); +u32 vnet_config_reset_end_node (vlib_main_t *vm, vnet_config_main_t *cm, + u32 config_string_heap_index); + +u32 vnet_config_get_end_node (vlib_main_t *vm, vnet_config_main_t *cm, + u32 config_string_heap_index); + u8 *vnet_config_format_features (vlib_main_t * vm, vnet_config_main_t * cm, u32 config_index, u8 * s); diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c index c93f586c349..1750612783b 100644 --- a/src/vnet/feature/feature.c +++ b/src/vnet/feature/feature.c @@ -293,9 +293,10 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, fm->sw_if_index_has_features[arc_index] = clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index, (feature_count > 0)); + fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count; + vnet_feature_reg_invoke (sw_if_index, arc_index, (feature_count > 0)); - fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count; return 0; } @@ -375,6 +376,52 @@ vnet_feature_is_enabled (const char *arc_name, const char *feature_node_name, return 0; } +u32 +vnet_feature_get_end_node (u8 arc_index, u32 sw_if_index) +{ + vnet_feature_main_t *fm = &feature_main; + vnet_feature_config_main_t *cm; + u32 ci; + + if (arc_index == (u8) ~0) + return VNET_API_ERROR_INVALID_VALUE; + + cm = &fm->feature_config_mains[arc_index]; + vec_validate_init_empty (cm->config_index_by_sw_if_index, sw_if_index, ~0); + ci = cm->config_index_by_sw_if_index[sw_if_index]; + + return (vnet_config_get_end_node (vlib_get_main (), &cm->config_main, ci)); +} + +u32 +vnet_feature_reset_end_node (u8 arc_index, u32 sw_if_index) +{ + vnet_feature_main_t *fm = &feature_main; + vnet_feature_config_main_t *cm; + u32 ci; + + cm = &fm->feature_config_mains[arc_index]; + vec_validate_init_empty (cm->config_index_by_sw_if_index, sw_if_index, ~0); + ci = cm->config_index_by_sw_if_index[sw_if_index]; + + ci = vnet_config_reset_end_node (vlib_get_main (), &cm->config_main, ci); + + if (ci != ~0) + cm->config_index_by_sw_if_index[sw_if_index] = ci; + + i16 feature_count; + + if (NULL == fm->feature_count_by_sw_if_index || + vec_len (fm->feature_count_by_sw_if_index) <= arc_index || + vec_len (fm->feature_count_by_sw_if_index[arc_index]) <= sw_if_index) + feature_count = 0; + else + feature_count = fm->feature_count_by_sw_if_index[arc_index][sw_if_index]; + + vnet_feature_reg_invoke (sw_if_index, arc_index, (feature_count > 0)); + + return ci; +} u32 vnet_feature_modify_end_node (u8 arc_index, @@ -400,6 +447,17 @@ vnet_feature_modify_end_node (u8 arc_index, if (ci != ~0) cm->config_index_by_sw_if_index[sw_if_index] = ci; + i16 feature_count; + + if (NULL == fm->feature_count_by_sw_if_index || + vec_len (fm->feature_count_by_sw_if_index) <= arc_index || + vec_len (fm->feature_count_by_sw_if_index[arc_index]) <= sw_if_index) + feature_count = 0; + else + feature_count = fm->feature_count_by_sw_if_index[arc_index][sw_if_index]; + + vnet_feature_reg_invoke (sw_if_index, arc_index, (feature_count > 0)); + return ci; } diff --git a/src/vnet/feature/feature.h b/src/vnet/feature/feature.h index 9aa32182ef6..a8235d3d9ee 100644 --- a/src/vnet/feature/feature.h +++ b/src/vnet/feature/feature.h @@ -222,6 +222,10 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name, u32 vnet_feature_modify_end_node (u8 arc_index, u32 sw_if_index, u32 node_index); +u32 vnet_feature_get_end_node (u8 arc_index, u32 sw_if_index); + +u32 vnet_feature_reset_end_node (u8 arc_index, u32 sw_if_index); + static_always_inline u32 vnet_get_feature_count (u8 arc, u32 sw_if_index) { diff --git a/src/vnet/gre/gre.c b/src/vnet/gre/gre.c index fcdf9c0d6bc..dc735e6a77b 100644 --- a/src/vnet/gre/gre.c +++ b/src/vnet/gre/gre.c @@ -420,9 +420,6 @@ gre_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) if (!(t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)) af |= ADJ_FLAG_MIDCHAIN_IP_STACK; - if (VNET_LINK_ETHERNET == adj_get_link_type (ai)) - af |= ADJ_FLAG_MIDCHAIN_NO_COUNT; - adj_nbr_midchain_update_rewrite (ai, gre_get_fixup (t->tunnel_dst.fp_proto, adj_get_link_type (ai)), diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c index 0251ced598f..3b566b6ea81 100644 --- a/src/vnet/gre/interface.c +++ b/src/vnet/gre/interface.c @@ -504,9 +504,15 @@ vnet_gre_tunnel_add (vnet_gre_tunnel_add_del_args_t * a, { t->l2_adj_index = adj_nbr_add_or_lock (t->tunnel_dst.fp_proto, VNET_LINK_ETHERNET, &zero_addr, sw_if_index); + vnet_set_interface_l3_output_node (gm->vlib_main, sw_if_index, + (u8 *) "tunnel-output-no-count"); gre_update_adj (vnm, t->sw_if_index, t->l2_adj_index); } - + else + { + vnet_set_interface_l3_output_node (gm->vlib_main, sw_if_index, + (u8 *) "tunnel-output"); + } if (sw_if_indexp) *sw_if_indexp = sw_if_index; @@ -562,6 +568,7 @@ vnet_gre_tunnel_delete (vnet_gre_tunnel_add_del_args_t * a, clib_mem_free (t->gre_sn); } + vnet_reset_interface_l3_output_node (gm->vlib_main, sw_if_index); hash_unset (gm->instance_used, t->user_instance); gre_tunnel_db_remove (t, &key); pool_put (gm->tunnels, t); diff --git a/src/vnet/interface.c b/src/vnet/interface.c index ab12da563a5..ce024993826 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -804,6 +804,36 @@ setup_output_node (vlib_main_t * vm, n->unformat_buffer = hw_class->unformat_header; } +void +vnet_reset_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index) +{ + vnet_set_interface_l3_output_node (vm, sw_if_index, + (u8 *) "interface-output"); +} + +void +vnet_set_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index, + u8 *output_node) +{ + vlib_node_t *l3_node; + + l3_node = vlib_get_node_by_name (vm, output_node); + + static char *arcs[] = { + "ip4-output", + "ip6-output", + "mpls-output", + "ethernet-output", + }; + u8 a; + + for (a = 0; a < ARRAY_LEN (arcs); a++) + { + u8 arc = vnet_get_feature_arc_index (arcs[a]); + vnet_feature_modify_end_node (arc, sw_if_index, l3_node->index); + } +} + /* Register an interface instance. */ u32 vnet_register_interface (vnet_main_t * vnm, @@ -1106,7 +1136,6 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) dn->tx_node_index = hw->tx_node_index; dn->output_node_index = hw->output_node_index; } - hash_unset_mem (im->hw_interface_by_name, hw->name); vec_free (hw->name); vec_free (hw->hw_address); diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h index 28312d4c85a..f253b23f819 100644 --- a/src/vnet/interface_funcs.h +++ b/src/vnet/interface_funcs.h @@ -231,6 +231,10 @@ u32 vnet_register_interface (vnet_main_t * vnm, void vnet_set_interface_output_node (vnet_main_t * vnm, u32 hw_if_index, u32 node_index); +void vnet_set_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index, + u8 *output_node); +void vnet_reset_interface_l3_output_node (vlib_main_t *vm, u32 sw_if_index); + /* Creates a software interface given template. */ clib_error_t *vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template, diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c index 5dbe85a1c5b..2ac234eb7ca 100644 --- a/src/vnet/ipip/ipip.c +++ b/src/vnet/ipip/ipip.c @@ -348,9 +348,6 @@ ipip_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) if (!(t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)) af |= ADJ_FLAG_MIDCHAIN_IP_STACK; - if (VNET_LINK_ETHERNET == adj_get_link_type (ai)) - af |= ADJ_FLAG_MIDCHAIN_NO_COUNT; - fixup = ipip_get_fixup (t, adj_get_link_type (ai), &af); adj_nbr_midchain_update_rewrite (ai, fixup, @@ -795,6 +792,8 @@ ipip_add_tunnel (ipip_transport_t transport, /* Standard default ipip MTU. */ vnet_sw_interface_set_mtu (vnm, sw_if_index, 9000); + vnet_set_interface_l3_output_node (gm->vlib_main, sw_if_index, + (u8 *) "tunnel-output"); t->tunnel_src = *src; t->tunnel_dst = *dst; @@ -840,6 +839,7 @@ ipip_del_tunnel (u32 sw_if_index) teib_walk_itf (t->sw_if_index, ipip_tunnel_delete_teib_walk, t); vnet_sw_interface_set_flags (vnm, sw_if_index, 0 /* down */ ); + vnet_reset_interface_l3_output_node (gm->vlib_main, t->sw_if_index); gm->tunnel_index_by_sw_if_index[sw_if_index] = ~0; vnet_delete_hw_interface (vnm, t->hw_if_index); hash_unset (gm->instance_used, t->user_instance); diff --git a/src/vnet/ipip/sixrd.c b/src/vnet/ipip/sixrd.c index 492b4f83260..c6c855df6e3 100644 --- a/src/vnet/ipip/sixrd.c +++ b/src/vnet/ipip/sixrd.c @@ -325,6 +325,8 @@ sixrd_add_tunnel (ip6_address_t * ip6_prefix, u8 ip6_prefix_len, t->user_instance = t_idx; vnet_sw_interface_set_mtu (vnet_get_main (), t->sw_if_index, 1480); + vnet_set_interface_l3_output_node (gm->vlib_main, hi->sw_if_index, + (u8 *) "tunnel-output"); ipip_tunnel_db_add (t, &key); @@ -403,6 +405,7 @@ sixrd_del_tunnel (u32 sw_if_index) vnet_sw_interface_set_flags (vnet_get_main (), t->sw_if_index, 0 /* down */ ); + vnet_reset_interface_l3_output_node (gm->vlib_main, t->sw_if_index); ip6_sw_interface_enable_disable (t->sw_if_index, false); gm->tunnel_index_by_sw_if_index[t->sw_if_index] = ~0; diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 33484e9cf43..0d29604e61f 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -50,7 +50,9 @@ typedef enum _ (SEQ_CYCLED, "sequence number cycled (packet dropped)") \ _ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") \ _ (CRYPTO_QUEUE_FULL, "crypto queue full (packet dropped)") \ - _ (NO_BUFFERS, "no buffers (packet dropped)") + _ (NO_BUFFERS, "no buffers (packet dropped)") \ + _ (NO_PROTECTION, "no protecting SA (packet dropped)") \ + _ (NO_ENCRYPTION, "no Encrypting SA (packet dropped)") typedef enum { @@ -640,6 +642,14 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vnet_buffer (b[0])->ipsec.sad_index = sa_index0 = ipsec_tun_protect_get_sa_out (vnet_buffer (b[0])->ip.adj_index[VLIB_TX]); + + if (PREDICT_FALSE (INDEX_INVALID == sa_index0)) + { + err = ESP_ENCRYPT_ERROR_NO_PROTECTION; + esp_set_next_index (b[0], node, err, n_noop, noop_nexts, + drop_next); + goto trace; + } } else sa_index0 = vnet_buffer (b[0])->ipsec.sad_index; @@ -655,6 +665,15 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, sa0 = ipsec_sa_get (sa_index0); + if (PREDICT_FALSE ((sa0->crypto_alg == IPSEC_CRYPTO_ALG_NONE && + sa0->integ_alg == IPSEC_INTEG_ALG_NONE) && + !ipsec_sa_is_set_NO_ALGO_NO_DROP (sa0))) + { + err = ESP_ENCRYPT_ERROR_NO_ENCRYPTION; + esp_set_next_index (b[0], node, err, n_noop, noop_nexts, + drop_next); + goto trace; + } /* fetch the second cacheline ASAP */ clib_prefetch_load (sa0->cacheline1); @@ -970,13 +989,19 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, { esp_encrypt_trace_t *tr = vlib_add_trace (vm, node, b[0], sizeof (*tr)); - tr->sa_index = sa_index0; - tr->spi = sa0->spi; - tr->seq = sa0->seq; - tr->sa_seq_hi = sa0->seq_hi; - tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0); - tr->crypto_alg = sa0->crypto_alg; - tr->integ_alg = sa0->integ_alg; + if (INDEX_INVALID == sa_index0) + clib_memset_u8 (tr, 0xff, sizeof (*tr)); + else + { + tr->sa_index = sa_index0; + tr->spi = sa0->spi; + tr->spi = sa0->spi; + tr->seq = sa0->seq; + tr->sa_seq_hi = sa0->seq_hi; + tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0); + tr->crypto_alg = sa0->crypto_alg; + tr->integ_alg = sa0->integ_alg; + } } /* next */ @@ -1002,9 +1027,10 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node, b += 1; } - vlib_increment_combined_counter (&ipsec_sa_counters, thread_index, - current_sa_index, current_sa_packets, - current_sa_bytes); + if (INDEX_INVALID != current_sa_index) + vlib_increment_combined_counter (&ipsec_sa_counters, thread_index, + current_sa_index, current_sa_packets, + current_sa_bytes); if (n_sync) { esp_process_ops (vm, node, ptd->crypto_ops, sync_bufs, sync_nexts, @@ -1368,120 +1394,6 @@ VLIB_REGISTER_NODE (esp_mpls_encrypt_tun_post_node) = { .error_strings = esp_encrypt_error_strings, }; -typedef struct -{ - u32 sa_index; -} esp_no_crypto_trace_t; - -static u8 * -format_esp_no_crypto_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - esp_no_crypto_trace_t *t = va_arg (*args, esp_no_crypto_trace_t *); - - s = format (s, "esp-no-crypto: sa-index %u", t->sa_index); - - return s; -} - -enum -{ - ESP_NO_CRYPTO_NEXT_DROP, - ESP_NO_CRYPTO_N_NEXT, -}; - -enum -{ - ESP_NO_CRYPTO_ERROR_RX_PKTS, -}; - -static char *esp_no_crypto_error_strings[] = { - "Outbound ESP packets received", -}; - -always_inline uword -esp_no_crypto_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs; - u32 *from = vlib_frame_vector_args (frame); - u32 n_left = frame->n_vectors; - - vlib_get_buffers (vm, from, b, n_left); - - while (n_left > 0) - { - u32 sa_index0; - - /* packets are always going to be dropped, but get the sa_index */ - sa_index0 = ipsec_tun_protect_get_sa_out - (vnet_buffer (b[0])->ip.adj_index[VLIB_TX]); - - if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED)) - { - esp_no_crypto_trace_t *tr = vlib_add_trace (vm, node, b[0], - sizeof (*tr)); - tr->sa_index = sa_index0; - } - - n_left -= 1; - b += 1; - } - - vlib_node_increment_counter (vm, node->node_index, - ESP_NO_CRYPTO_ERROR_RX_PKTS, frame->n_vectors); - - vlib_buffer_enqueue_to_single_next (vm, node, from, - ESP_NO_CRYPTO_NEXT_DROP, - frame->n_vectors); - - return frame->n_vectors; -} - -VLIB_NODE_FN (esp4_no_crypto_tun_node) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) -{ - return esp_no_crypto_inline (vm, node, from_frame); -} - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (esp4_no_crypto_tun_node) = -{ - .name = "esp4-no-crypto", - .vector_size = sizeof (u32), - .format_trace = format_esp_no_crypto_trace, - .n_errors = ARRAY_LEN(esp_no_crypto_error_strings), - .error_strings = esp_no_crypto_error_strings, - .n_next_nodes = ESP_NO_CRYPTO_N_NEXT, - .next_nodes = { - [ESP_NO_CRYPTO_NEXT_DROP] = "ip4-drop", - }, -}; - -VLIB_NODE_FN (esp6_no_crypto_tun_node) (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) -{ - return esp_no_crypto_inline (vm, node, from_frame); -} - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (esp6_no_crypto_tun_node) = -{ - .name = "esp6-no-crypto", - .vector_size = sizeof (u32), - .format_trace = format_esp_no_crypto_trace, - .n_errors = ARRAY_LEN(esp_no_crypto_error_strings), - .error_strings = esp_no_crypto_error_strings, - .n_next_nodes = ESP_NO_CRYPTO_N_NEXT, - .next_nodes = { - [ESP_NO_CRYPTO_NEXT_DROP] = "ip6-drop", - }, -}; -/* *INDENT-ON* */ - #ifndef CLIB_MARCH_VARIANT static clib_error_t * diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c index 30774ec10ff..5cc8044e3d4 100644 --- a/src/vnet/ipsec/ipsec.c +++ b/src/vnet/ipsec/ipsec.c @@ -25,6 +25,7 @@ #include <vnet/ipsec/esp.h> #include <vnet/ipsec/ah.h> #include <vnet/ipsec/ipsec_tun.h> +#include <vnet/ipsec/ipsec_itf.h> /* Flow cache is sized for 1 million flows with a load factor of .25. */ @@ -254,6 +255,9 @@ ipsec_rsc_in_use (ipsec_main_t * im) if (pool_elts (ipsec_sa_pool) > 0) return clib_error_return (0, "%d SA entries configured", pool_elts (ipsec_sa_pool)); + if (ipsec_itf_count () > 0) + return clib_error_return (0, "%d IPSec interface configured", + ipsec_itf_count ()); return (NULL); } diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index 968d377cea0..38feaed6f77 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -181,14 +181,6 @@ typedef struct u32 ah6_encrypt_next_index; u32 ah6_decrypt_next_index; - /* tun nodes to drop packets when no crypto alg set on outbound SA */ - u32 esp4_no_crypto_tun_node_index; - u32 esp6_no_crypto_tun_node_index; - - /* tun nodes for encrypt on L2 interfaces */ - u32 esp4_encrypt_l2_tun_node_index; - u32 esp6_encrypt_l2_tun_node_index; - /* pool of ah backends */ ipsec_ah_backend_t *ah_backends; /* pool of esp backends */ diff --git a/src/vnet/ipsec/ipsec_itf.c b/src/vnet/ipsec/ipsec_itf.c index 532d5be4c07..fc0bf85a517 100644 --- a/src/vnet/ipsec/ipsec_itf.c +++ b/src/vnet/ipsec/ipsec_itf.c @@ -36,6 +36,12 @@ ipsec_itf_get (index_t ii) return (pool_elt_at_index (ipsec_itf_pool, ii)); } +u32 +ipsec_itf_count (void) +{ + return (pool_elts (ipsec_itf_pool)); +} + static ipsec_itf_t * ipsec_itf_find_by_sw_if_index (u32 sw_if_index) { @@ -336,6 +342,8 @@ ipsec_itf_delete (u32 sw_if_index) if (ipsec_itf_instance_free (hw->dev_instance) < 0) return VNET_API_ERROR_INVALID_SW_IF_INDEX; + vnet_reset_interface_l3_output_node (vnm->vlib_main, sw_if_index); + vnet_delete_hw_interface (vnm, hw->hw_if_index); pool_put (ipsec_itf_pool, ipsec_itf); diff --git a/src/vnet/ipsec/ipsec_itf.h b/src/vnet/ipsec/ipsec_itf.h index 4958d102b65..7de02745b81 100644 --- a/src/vnet/ipsec/ipsec_itf.h +++ b/src/vnet/ipsec/ipsec_itf.h @@ -109,6 +109,7 @@ extern void ipsec_itf_adj_unstack (adj_index_t ai); extern u8 *format_ipsec_itf (u8 * s, va_list * a); extern ipsec_itf_t *ipsec_itf_get (index_t ii); +extern u32 ipsec_itf_count (void); typedef walk_rc_t (*ipsec_itf_walk_cb_t) (ipsec_itf_t *itf, void *ctx); extern void ipsec_itf_walk (ipsec_itf_walk_cb_t cd, void *ctx); diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index 2cc64e19546..ec5ca11b179 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -102,7 +102,8 @@ typedef struct ipsec_key_t_ _ (64, IS_INBOUND, "inbound") \ _ (128, IS_AEAD, "aead") \ _ (256, IS_CTR, "ctr") \ - _ (512, IS_ASYNC, "async") + _ (512, IS_ASYNC, "async") \ + _ (1024, NO_ALGO_NO_DROP, "no-algo-no-drop") typedef enum ipsec_sad_flags_t_ { diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c index 1a9a25783ae..ef84d13a373 100644 --- a/src/vnet/ipsec/ipsec_tun.c +++ b/src/vnet/ipsec/ipsec_tun.c @@ -22,6 +22,7 @@ #include <vnet/adj/adj_delegate.h> #include <vnet/adj/adj_midchain.h> #include <vnet/teib/teib.h> +#include <vnet/mpls/mpls.h> /* instantiate the bihash functions */ #include <vppinfra/bihash_8_16.h> @@ -137,12 +138,14 @@ ipsec_tun_protect_from_const_base (const adj_delegate_t * ad) static u32 ipsec_tun_protect_get_adj_next (vnet_link_t linkt, - const ipsec_tun_protect_t * itp) + const ipsec_tun_protect_t *itp) { ipsec_main_t *im; - ipsec_sa_t *sa; u32 next; + im = &ipsec_main; + next = 0; + if (!(itp->itp_flags & IPSEC_PROTECT_ITF)) { if (ip46_address_is_ip4 (&itp->itp_tun.src)) @@ -151,42 +154,48 @@ ipsec_tun_protect_get_adj_next (vnet_link_t linkt, linkt = VNET_LINK_IP6; } - sa = ipsec_sa_get (itp->itp_out_sa); - im = &ipsec_main; - next = 0; - - if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_NONE && - sa->integ_alg == IPSEC_INTEG_ALG_NONE) && - !(itp->itp_flags & IPSEC_PROTECT_ITF)) - next = (VNET_LINK_IP4 == linkt ? im->esp4_no_crypto_tun_node_index : - im->esp6_no_crypto_tun_node_index); - else if (itp->itp_flags & IPSEC_PROTECT_L2) - next = (VNET_LINK_IP4 == linkt ? im->esp4_encrypt_l2_tun_node_index : - im->esp6_encrypt_l2_tun_node_index); - else + switch (linkt) { - switch (linkt) - { - case VNET_LINK_IP4: - next = im->esp4_encrypt_tun_node_index; - break; - case VNET_LINK_IP6: - next = im->esp6_encrypt_tun_node_index; - break; - case VNET_LINK_MPLS: - next = im->esp_mpls_encrypt_tun_node_index; - break; - case VNET_LINK_ARP: - case VNET_LINK_NSH: - case VNET_LINK_ETHERNET: - ASSERT (0); - break; - } + case VNET_LINK_IP4: + next = im->esp4_encrypt_tun_node_index; + break; + case VNET_LINK_IP6: + next = im->esp6_encrypt_tun_node_index; + break; + case VNET_LINK_MPLS: + next = im->esp_mpls_encrypt_tun_node_index; + break; + case VNET_LINK_ARP: + case VNET_LINK_NSH: + case VNET_LINK_ETHERNET: + ASSERT (0); + break; } + return (next); } static void +ipsec_tun_reset_tx_nodes (u32 sw_if_index) +{ + vnet_reset_interface_l3_output_node (vlib_get_main (), sw_if_index); +} + +static void +ipsec_tun_setup_tx_nodes (u32 sw_if_index, const ipsec_tun_protect_t *itp) +{ + vnet_feature_modify_end_node ( + ip4_main.lookup_main.output_feature_arc_index, sw_if_index, + ipsec_tun_protect_get_adj_next (VNET_LINK_IP4, itp)); + vnet_feature_modify_end_node ( + ip6_main.lookup_main.output_feature_arc_index, sw_if_index, + ipsec_tun_protect_get_adj_next (VNET_LINK_IP6, itp)); + vnet_feature_modify_end_node ( + mpls_main.output_feature_arc_index, sw_if_index, + ipsec_tun_protect_get_adj_next (VNET_LINK_MPLS, itp)); +} + +static void ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp) { vec_validate_init_empty (ipsec_tun_protect_sa_by_adj_index, ai, @@ -200,8 +209,8 @@ ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp) else { ipsec_tun_protect_sa_by_adj_index[ai] = itp->itp_out_sa; - adj_nbr_midchain_update_next_node - (ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp)); + adj_nbr_midchain_update_next_node ( + ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp)); } } @@ -329,7 +338,7 @@ ipsec_tun_protect_tx_db_add (ipsec_tun_protect_t * itp) { if (INDEX_INVALID == idi->id_itp) { - // ipsec_tun_protect_feature_set (itp, 1); + ipsec_tun_setup_tx_nodes (itp->itp_sw_if_index, itp); } idi->id_itp = itp - ipsec_tun_protect_pool; @@ -347,7 +356,7 @@ ipsec_tun_protect_tx_db_add (ipsec_tun_protect_t * itp) * enable the encrypt feature for egress if this is the first addition * on this interface */ - // ipsec_tun_protect_feature_set (itp, 1); + ipsec_tun_setup_tx_nodes (itp->itp_sw_if_index, itp); } hash_set_mem (idi->id_hash, itp->itp_key, itp - ipsec_tun_protect_pool); @@ -435,7 +444,7 @@ ipsec_tun_protect_tx_db_remove (ipsec_tun_protect_t * itp) if (vnet_sw_interface_is_p2p (vnet_get_main (), itp->itp_sw_if_index)) { - // ipsec_tun_protect_feature_set (itp, 0); + ipsec_tun_reset_tx_nodes (itp->itp_sw_if_index); idi->id_itp = INDEX_INVALID; FOR_EACH_FIB_IP_PROTOCOL (nh_proto) @@ -451,7 +460,7 @@ ipsec_tun_protect_tx_db_remove (ipsec_tun_protect_t * itp) if (0 == hash_elts (idi->id_hash)) { - // ipsec_tun_protect_feature_set (itp, 0); + ipsec_tun_reset_tx_nodes (itp->itp_sw_if_index); hash_free (idi->id_hash); idi->id_hash = NULL; } @@ -502,6 +511,9 @@ ipsec_tun_protect_config (ipsec_main_t * im, ipsec_sa_lock (itp->itp_out_sa); + if (itp->itp_flags & IPSEC_PROTECT_ITF) + ipsec_sa_set_NO_ALGO_NO_DROP (ipsec_sa_get (itp->itp_out_sa)); + /* *INDENT-OFF* */ FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai, ({ @@ -534,6 +546,7 @@ ipsec_tun_protect_unconfig (ipsec_main_t * im, ipsec_tun_protect_t * itp) ipsec_tun_protect_rx_db_remove (im, itp); ipsec_tun_protect_tx_db_remove (itp); + ipsec_sa_unset_NO_ALGO_NO_DROP (ipsec_sa_get (itp->itp_out_sa)); ipsec_sa_unlock(itp->itp_out_sa); FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai, @@ -802,19 +815,27 @@ ipsec_tun_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable, ipsec_main.esp4_decrypt_tun_node_index : ipsec_main.esp6_decrypt_tun_node_index; - vnet_feature_modify_end_node ( - feature_main.device_input_feature_arc_index, sw_if_index, decrypt_tun); - itp->itp_flags |= IPSEC_PROTECT_FEAT; + if (!(itp->itp_flags & IPSEC_PROTECT_FEAT)) + { + itp->itp_flags |= IPSEC_PROTECT_FEAT; + vnet_feature_modify_end_node ( + feature_main.device_input_feature_arc_index, sw_if_index, + decrypt_tun); + } } else { - u32 eth_in = - vlib_get_node_by_name (vlib_get_main (), (u8 *) "ethernet-input") - ->index; + if (itp->itp_flags & IPSEC_PROTECT_FEAT) + { + itp->itp_flags &= ~IPSEC_PROTECT_FEAT; + + u32 eth_in = + vlib_get_node_by_name (vlib_get_main (), (u8 *) "ethernet-input") + ->index; - vnet_feature_modify_end_node ( - feature_main.device_input_feature_arc_index, sw_if_index, eth_in); - itp->itp_flags &= ~IPSEC_PROTECT_FEAT; + vnet_feature_modify_end_node ( + feature_main.device_input_feature_arc_index, sw_if_index, eth_in); + } } /* Propagate flag change into lookup entries */ @@ -848,6 +869,9 @@ ipsec_tun_protect_adj_delegate_adj_created (adj_index_t ai) if (!adj_is_midchain (ai)) return; + vec_validate_init_empty (ipsec_tun_protect_sa_by_adj_index, ai, + INDEX_INVALID); + adj = adj_get (ai); ip_address_from_46 (&adj->sub_type.midchain.next_hop, @@ -956,16 +980,6 @@ ipsec_tunnel_protect_init (vlib_main_t *vm) IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); - /* set up feature nodes to drop outbound packets with no crypto alg set */ - im->esp4_no_crypto_tun_node_index = - vlib_get_node_by_name (vm, (u8 *) "esp4-no-crypto")->index; - im->esp6_no_crypto_tun_node_index = - vlib_get_node_by_name (vm, (u8 *) "esp6-no-crypto")->index; - im->esp6_encrypt_l2_tun_node_index = - vlib_get_node_by_name (vm, (u8 *) "esp6-encrypt-tun")->index; - im->esp4_encrypt_l2_tun_node_index = - vlib_get_node_by_name (vm, (u8 *) "esp4-encrypt-tun")->index; - ipsec_tun_adj_delegate_type = adj_delegate_register_new_type (&ipsec_tun_adj_delegate_vft); diff --git a/src/vnet/ipsec/ipsec_tun.h b/src/vnet/ipsec/ipsec_tun.h index f452fa4354c..9d8a124443d 100644 --- a/src/vnet/ipsec/ipsec_tun.h +++ b/src/vnet/ipsec/ipsec_tun.h @@ -182,7 +182,6 @@ always_inline index_t ipsec_tun_protect_get_sa_out (adj_index_t ai) { ASSERT (vec_len (ipsec_tun_protect_sa_by_adj_index) > ai); - ASSERT (INDEX_INVALID != ipsec_tun_protect_sa_by_adj_index[ai]); return (ipsec_tun_protect_sa_by_adj_index[ai]); } diff --git a/src/vnet/mpls/mpls_tunnel.c b/src/vnet/mpls/mpls_tunnel.c index 54458eacdf8..4715958e99c 100644 --- a/src/vnet/mpls/mpls_tunnel.c +++ b/src/vnet/mpls/mpls_tunnel.c @@ -638,6 +638,7 @@ vnet_mpls_tunnel_del (u32 sw_if_index) mt->mt_sibling_index); dpo_reset(&mt->mt_l2_lb); + vnet_reset_interface_l3_output_node (vlib_get_main (), mt->mt_sw_if_index); vnet_delete_hw_interface (vnet_get_main(), mt->mt_hw_if_index); pool_put(mpls_tunnel_pool, mt); @@ -685,6 +686,9 @@ vnet_mpls_tunnel_create (u8 l2_only, if (mt->mt_flags & MPLS_TUNNEL_FLAG_L2) vnet_set_interface_output_node (vnm, mt->mt_hw_if_index, mpls_tunnel_tx.index); + else + vnet_set_interface_l3_output_node (vnm->vlib_main, hi->sw_if_index, + (u8 *) "tunnel-output"); /* Standard default MPLS tunnel MTU. */ vnet_sw_interface_set_mtu (vnm, hi->sw_if_index, 9000); |