X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Fdvr_dpo.c;h=6dd58108091112193cbc9e0ae96f7fc7e7eaec69;hb=282872127;hp=a362d23e890edf3f57b7c1b89e9e32b01a92afd8;hpb=47727c02df4c79c21c6ceffaff65222c32cf6996;p=vpp.git diff --git a/src/vnet/dpo/dvr_dpo.c b/src/vnet/dpo/dvr_dpo.c index a362d23e890..6dd58108091 100644 --- a/src/vnet/dpo/dvr_dpo.c +++ b/src/vnet/dpo/dvr_dpo.c @@ -17,7 +17,9 @@ #include #include #include +#include +#ifndef CLIB_MARCH_VARIANT dvr_dpo_t *dvr_dpo_pool; /** @@ -90,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], @@ -105,6 +108,17 @@ 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 (config->bridge || config->xconnect) + { + dd->dd_reinject = DVR_REINJECT_L2; + } + else + { + dd->dd_reinject = DVR_REINJECT_L3; + } + /* * enable the reinject into L2 path feature on the interface */ @@ -124,6 +138,7 @@ dvr_dpo_add_or_lock (u32 sw_if_index, dpo_set(dpo, DPO_DVR, dproto, dvr_dpo_get_index(dd)); } +#endif /* CLIB_MARCH_VARIANT */ static clib_error_t * @@ -164,7 +179,25 @@ dvr_dpo_interface_delete (vnet_main_t * vnm, VNET_SW_INTERFACE_ADD_DEL_FUNCTION( dvr_dpo_interface_delete); -u8* +#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) { index_t index = va_arg(*ap, index_t); @@ -172,10 +205,12 @@ 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", + return (format(s, "%U-dvr-%U-dpo %U", + format_dpo_proto, dd->dd_proto, format_vnet_sw_interface_name, vnm, - vnet_get_sw_interface(vnm, dd->dd_sw_if_index))); + vnet_get_sw_interface(vnm, dd->dd_sw_if_index), + format_dvr_reinject, dd->dd_reinject)); } static void @@ -226,6 +261,7 @@ dvr_dpo_module_init (void) &dvr_dpo_vft, dvr_dpo_nodes); } +#endif /* CLIB_MARCH_VARIANT */ /** * @brief Interface DPO trace data @@ -296,6 +332,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; @@ -397,16 +434,14 @@ format_dvr_dpo_trace (u8 * s, va_list * args) return s; } -static uword -ip4_dvr_dpo (vlib_main_t * vm, +VLIB_NODE_FN (ip4_dvr_dpo_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { return (dvr_dpo_inline(vm, node, from_frame, 0)); } -static uword -ip6_dvr_dpo (vlib_main_t * vm, +VLIB_NODE_FN (ip6_dvr_dpo_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { @@ -414,26 +449,22 @@ ip6_dvr_dpo (vlib_main_t * vm, } VLIB_REGISTER_NODE (ip4_dvr_dpo_node) = { - .function = ip4_dvr_dpo, .name = "ip4-dvr-dpo", .vector_size = sizeof (u32), .format_trace = format_dvr_dpo_trace, .sibling_of = "ip4-rewrite", }; VLIB_REGISTER_NODE (ip6_dvr_dpo_node) = { - .function = ip6_dvr_dpo, .name = "ip6-dvr-dpo", .vector_size = sizeof (u32), .format_trace = format_dvr_dpo_trace, .sibling_of = "ip6-rewrite", }; -VLIB_NODE_FUNCTION_MULTIARCH (ip4_dvr_dpo_node, ip4_dvr_dpo) -VLIB_NODE_FUNCTION_MULTIARCH (ip6_dvr_dpo_node, ip6_dvr_dpo) - 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 @@ -457,8 +488,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; @@ -473,12 +505,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); @@ -505,8 +549,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; @@ -518,7 +563,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); @@ -538,16 +589,14 @@ dvr_reinject_inline (vlib_main_t * vm, return from_frame->n_vectors; } -static uword -ip4_dvr_reinject (vlib_main_t * vm, +VLIB_NODE_FN (ip4_dvr_reinject_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { return (dvr_reinject_inline(vm, node, from_frame)); } -static uword -ip6_dvr_reinject (vlib_main_t * vm, +VLIB_NODE_FN (ip6_dvr_reinject_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) { @@ -555,26 +604,26 @@ ip6_dvr_reinject (vlib_main_t * vm, } VLIB_REGISTER_NODE (ip4_dvr_reinject_node) = { - .function = ip4_dvr_reinject, .name = "ip4-dvr-reinject", .vector_size = sizeof (u32), .format_trace = format_dvr_dpo_trace, .n_next_nodes = 1, .next_nodes = { - [DVR_REINJECT_OUTPUT] = "l2-output", + [DVR_REINJECT_NEXT_L2] = "l2-output", + [DVR_REINJECT_NEXT_L3] = "interface-output", }, }; VLIB_REGISTER_NODE (ip6_dvr_reinject_node) = { - .function = ip6_dvr_reinject, .name = "ip6-dvr-reinject", .vector_size = sizeof (u32), .format_trace = format_dvr_dpo_trace, .n_next_nodes = 1, .next_nodes = { - [DVR_REINJECT_OUTPUT] = "l2-output", + [DVR_REINJECT_NEXT_L2] = "l2-output", + [DVR_REINJECT_NEXT_L3] = "interface-output", }, }; @@ -592,5 +641,3 @@ VNET_FEATURE_INIT (ip6_dvr_reinject_feat_node, static) = .runs_after = VNET_FEATURES ("acl-plugin-out-ip6-fa"), }; -VLIB_NODE_FUNCTION_MULTIARCH (ip4_dvr_reinject_node, ip4_dvr_reinject) -VLIB_NODE_FUNCTION_MULTIARCH (ip6_dvr_reinject_node, ip6_dvr_reinject)