X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Fdvr_dpo.c;h=2b66467837ca16a020dde72a0815fa1ae113cd85;hb=e8ea6be8dfb626b5bb4ff3355ce8037724ce1d83;hp=877f42a9893a1137aafdd4223783d1521c0aa458;hpb=eb9a27f247e521a80ce5a3ab31b1e3a483afefab;p=vpp.git diff --git a/src/vnet/dpo/dvr_dpo.c b/src/vnet/dpo/dvr_dpo.c index 877f42a9893..2b66467837c 100644 --- a/src/vnet/dpo/dvr_dpo.c +++ b/src/vnet/dpo/dvr_dpo.c @@ -17,6 +17,7 @@ #include #include #include +#include #ifndef CLIB_MARCH_VARIANT dvr_dpo_t *dvr_dpo_pool; @@ -91,6 +92,7 @@ dvr_dpo_add_or_lock (u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo) { + l2_input_config_t *config; dvr_dpo_t *dd; vec_validate_init_empty(dvr_dpo_db[dproto], @@ -106,6 +108,18 @@ dvr_dpo_add_or_lock (u32 sw_if_index, dvr_dpo_db[dproto][sw_if_index] = dvr_dpo_get_index(dd); + config = l2input_intf_config (sw_if_index); + + if (l2_input_is_bridge(config) || + l2_input_is_xconnect(config)) + { + dd->dd_reinject = DVR_REINJECT_L2; + } + else + { + dd->dd_reinject = DVR_REINJECT_L3; + } + /* * enable the reinject into L2 path feature on the interface */ @@ -167,6 +181,23 @@ VNET_SW_INTERFACE_ADD_DEL_FUNCTION( dvr_dpo_interface_delete); #ifndef CLIB_MARCH_VARIANT +static u8* +format_dvr_reinject (u8* s, va_list *ap) +{ + dvr_dpo_reinject_t ddr = va_arg(*ap, int); + + switch (ddr) + { + case DVR_REINJECT_L2: + s = format (s, "l2"); + break; + case DVR_REINJECT_L3: + s = format (s, "l3"); + break; + } + return (s); +} + static u8* format_dvr_dpo (u8* s, va_list *ap) { @@ -175,10 +206,9 @@ format_dvr_dpo (u8* s, va_list *ap) vnet_main_t * vnm = vnet_get_main(); dvr_dpo_t *dd = dvr_dpo_get(index); - return (format(s, "dvr-%U-dpo", - format_vnet_sw_interface_name, - vnm, - vnet_get_sw_interface(vnm, dd->dd_sw_if_index))); + return format (s, "%U-dvr-%U-dpo %U", format_dpo_proto, dd->dd_proto, + format_vnet_sw_if_index_name, vnm, dd->dd_sw_if_index, + format_dvr_reinject, dd->dd_reinject); } static void @@ -300,6 +330,7 @@ dvr_dpo_inline (vlib_main_t * vm, vnet_buffer(b1)->l2.l2_len = vnet_buffer(b1)->ip.save_rewrite_length = len1; + b0->flags |= VNET_BUFFER_F_IS_DVR; b1->flags |= VNET_BUFFER_F_IS_DVR; @@ -430,7 +461,8 @@ VLIB_REGISTER_NODE (ip6_dvr_dpo_node) = { typedef enum dvr_reinject_next_t_ { - DVR_REINJECT_OUTPUT = 0, + DVR_REINJECT_NEXT_L2, + DVR_REINJECT_NEXT_L3, } dvr_reinject_next_t; always_inline uword @@ -454,8 +486,9 @@ dvr_reinject_inline (vlib_main_t * vm, while (n_left_from >= 4 && n_left_to_next > 2) { dvr_reinject_next_t next0, next1; + const dvr_dpo_t *dd0, *dd1; + u32 bi0, bi1, ddi0, ddi1; vlib_buffer_t *b0, *b1; - u32 bi0, bi1; bi0 = from[0]; to_next[0] = bi0; @@ -470,12 +503,24 @@ dvr_reinject_inline (vlib_main_t * vm, b1 = vlib_get_buffer (vm, bi1); if (b0->flags & VNET_BUFFER_F_IS_DVR) - next0 = DVR_REINJECT_OUTPUT; + { + ddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; + dd0 = dvr_dpo_get(ddi0); + next0 = (dd0->dd_reinject == DVR_REINJECT_L2 ? + DVR_REINJECT_NEXT_L2 : + DVR_REINJECT_NEXT_L3); + } else vnet_feature_next( &next0, b0); if (b1->flags & VNET_BUFFER_F_IS_DVR) - next1 = DVR_REINJECT_OUTPUT; + { + ddi1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX]; + dd1 = dvr_dpo_get(ddi1); + next1 = (dd1->dd_reinject == DVR_REINJECT_L2 ? + DVR_REINJECT_NEXT_L2 : + DVR_REINJECT_NEXT_L3); + } else vnet_feature_next( &next1, b1); @@ -502,8 +547,9 @@ dvr_reinject_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { dvr_reinject_next_t next0; + const dvr_dpo_t *dd0; vlib_buffer_t * b0; - u32 bi0; + u32 bi0, ddi0; bi0 = from[0]; to_next[0] = bi0; @@ -515,7 +561,13 @@ dvr_reinject_inline (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); if (b0->flags & VNET_BUFFER_F_IS_DVR) - next0 = DVR_REINJECT_OUTPUT; + { + ddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; + dd0 = dvr_dpo_get(ddi0); + next0 = (dd0->dd_reinject == DVR_REINJECT_L2 ? + DVR_REINJECT_NEXT_L2 : + DVR_REINJECT_NEXT_L3); + } else vnet_feature_next( &next0, b0); @@ -556,7 +608,8 @@ VLIB_REGISTER_NODE (ip4_dvr_reinject_node) = { .n_next_nodes = 1, .next_nodes = { - [DVR_REINJECT_OUTPUT] = "l2-output", + [DVR_REINJECT_NEXT_L2] = "l2-output", + [DVR_REINJECT_NEXT_L3] = "interface-output", }, }; @@ -567,7 +620,8 @@ VLIB_REGISTER_NODE (ip6_dvr_reinject_node) = { .n_next_nodes = 1, .next_nodes = { - [DVR_REINJECT_OUTPUT] = "l2-output", + [DVR_REINJECT_NEXT_L2] = "l2-output", + [DVR_REINJECT_NEXT_L3] = "interface-output", }, }; @@ -575,13 +629,10 @@ VNET_FEATURE_INIT (ip4_dvr_reinject_feat_node, static) = { .arc_name = "ip4-output", .node_name = "ip4-dvr-reinject", - .runs_after = VNET_FEATURES ("nat44-in2out-output", - "acl-plugin-out-ip4-fa"), }; VNET_FEATURE_INIT (ip6_dvr_reinject_feat_node, static) = { .arc_name = "ip6-output", .node_name = "ip6-dvr-reinject", - .runs_after = VNET_FEATURES ("acl-plugin-out-ip6-fa"), };