X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdpo%2Fmpls_disposition.c;h=7bc2cb65f87d475de22536799f04ac760818952e;hb=097fa66b986f06281f603767d321ab13ab6c88c3;hp=77429de411618f9ebdab896a8bf5d9b2b38e2cec;hpb=4c7c8e55b03e21787cafb11cd49b9488c5ffef70;p=vpp.git diff --git a/src/vnet/dpo/mpls_disposition.c b/src/vnet/dpo/mpls_disposition.c index 77429de4116..7bc2cb65f87 100644 --- a/src/vnet/dpo/mpls_disposition.c +++ b/src/vnet/dpo/mpls_disposition.c @@ -18,6 +18,7 @@ #include #include +#ifndef CLIB_MARCH_VARIANT /* * pool of all MPLS Label DPOs */ @@ -29,7 +30,7 @@ mpls_disp_dpo_alloc (void) mpls_disp_dpo_t *mdd; pool_get_aligned(mpls_disp_dpo_pool, mdd, CLIB_CACHE_LINE_BYTES); - memset(mdd, 0, sizeof(*mdd)); + clib_memset(mdd, 0, sizeof(*mdd)); dpo_reset(&mdd->mdd_dpo); @@ -42,38 +43,59 @@ mpls_disp_dpo_get_index (mpls_disp_dpo_t *mdd) return (mdd - mpls_disp_dpo_pool); } -index_t +void mpls_disp_dpo_create (dpo_proto_t payload_proto, fib_rpf_id_t rpf_id, - const dpo_id_t *dpo) + fib_mpls_lsp_mode_t mode, + const dpo_id_t *parent, + dpo_id_t *dpo) { mpls_disp_dpo_t *mdd; + dpo_type_t dtype; mdd = mpls_disp_dpo_alloc(); mdd->mdd_payload_proto = payload_proto; mdd->mdd_rpf_id = rpf_id; - - dpo_stack(DPO_MPLS_DISPOSITION, + mdd->mdd_mode = mode; + dtype = (FIB_MPLS_LSP_MODE_PIPE == mode ? + DPO_MPLS_DISPOSITION_PIPE : + DPO_MPLS_DISPOSITION_UNIFORM); + + /* + * stack this disposition object on the parent given + */ + dpo_stack(dtype, mdd->mdd_payload_proto, &mdd->mdd_dpo, - dpo); - - return (mpls_disp_dpo_get_index(mdd)); + parent); + + /* + * set up the return DPO to refer to this object + */ + dpo_set(dpo, + dtype, + payload_proto, + mpls_disp_dpo_get_index(mdd)); } u8* format_mpls_disp_dpo (u8 *s, va_list *args) { - index_t index = va_arg (*args, index_t); - u32 indent = va_arg (*args, u32); + index_t index = va_arg(*args, index_t); + u32 indent = va_arg(*args, u32); mpls_disp_dpo_t *mdd; mdd = mpls_disp_dpo_get(index); - s = format(s, "mpls-disposition:[%d]:[%U]", - index, - format_dpo_proto, mdd->mdd_payload_proto); + s = format(s, "mpls-disposition:[%d]:[", index); + + if (0 != mdd->mdd_rpf_id) + s = format(s, "rpf-id:%d ", mdd->mdd_rpf_id); + + s = format(s, "%U, %U]", + format_dpo_proto, mdd->mdd_payload_proto, + format_fib_mpls_lsp_mode, mdd->mdd_mode); s = format(s, "\n%U", format_white_space, indent); s = format(s, "%U", format_dpo_id, &mdd->mdd_dpo, indent+2); @@ -106,6 +128,7 @@ mpls_disp_dpo_unlock (dpo_id_t *dpo) pool_put(mpls_disp_dpo_pool, mdd); } } +#endif /* CLIB_MARCH_VARIANT */ /** * @brief A struct to hold tracing information for the MPLS label disposition @@ -113,28 +136,46 @@ mpls_disp_dpo_unlock (dpo_id_t *dpo) */ typedef struct mpls_label_disposition_trace_t_ { - index_t mdd; + dpo_proto_t mddt_payload_proto; + fib_rpf_id_t mddt_rpf_id; + fib_mpls_lsp_mode_t mddt_mode; } mpls_label_disposition_trace_t; -extern vlib_node_registration_t ip4_mpls_label_disposition_node; -extern vlib_node_registration_t ip6_mpls_label_disposition_node; +extern vlib_node_registration_t ip4_mpls_label_disposition_pipe_node; +extern vlib_node_registration_t ip6_mpls_label_disposition_pipe_node; +extern vlib_node_registration_t ip4_mpls_label_disposition_uniform_node; +extern vlib_node_registration_t ip6_mpls_label_disposition_uniform_node; always_inline uword mpls_label_disposition_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame, - u8 payload_is_ip4, - u8 payload_is_ip6) + vlib_node_runtime_t * node, + vlib_frame_t * from_frame, + u8 payload_is_ip4, + u8 payload_is_ip6, + fib_mpls_lsp_mode_t mode) { u32 n_left_from, next_index, * from, * to_next; vlib_node_runtime_t *error_node; if (payload_is_ip4) - error_node = vlib_node_get_runtime (vm, ip4_mpls_label_disposition_node.index); + { + if (FIB_MPLS_LSP_MODE_PIPE == mode) + error_node = + vlib_node_get_runtime(vm, ip4_mpls_label_disposition_pipe_node.index); + else + error_node = + vlib_node_get_runtime(vm, ip4_mpls_label_disposition_uniform_node.index); + } else - error_node = vlib_node_get_runtime (vm, ip6_mpls_label_disposition_node.index); - - from = vlib_frame_vector_args (from_frame); + { + if (FIB_MPLS_LSP_MODE_PIPE == mode) + error_node = + vlib_node_get_runtime(vm, ip6_mpls_label_disposition_pipe_node.index); + else + error_node = + vlib_node_get_runtime(vm, ip6_mpls_label_disposition_uniform_node.index); + } + from = vlib_frame_vector_args(from_frame); n_left_from = from_frame->n_vectors; next_index = node->cached_next_index; @@ -159,14 +200,14 @@ mpls_label_disposition_inline (vlib_main_t * vm, { vlib_buffer_t * p2, * p3; - p2 = vlib_get_buffer (vm, from[2]); - p3 = vlib_get_buffer (vm, from[3]); + p2 = vlib_get_buffer(vm, from[2]); + p3 = vlib_get_buffer(vm, from[3]); - vlib_prefetch_buffer_header (p2, STORE); - vlib_prefetch_buffer_header (p3, STORE); + vlib_prefetch_buffer_header(p2, STORE); + vlib_prefetch_buffer_header(p3, STORE); - CLIB_PREFETCH (p2->data, sizeof (ip6_header_t), STORE); - CLIB_PREFETCH (p3->data, sizeof (ip6_header_t), STORE); + CLIB_PREFETCH(p2->data, sizeof(ip6_header_t), STORE); + CLIB_PREFETCH(p3->data, sizeof(ip6_header_t), STORE); } from += 2; @@ -174,8 +215,8 @@ mpls_label_disposition_inline (vlib_main_t * vm, n_left_from -= 2; n_left_to_next -= 2; - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); + b0 = vlib_get_buffer(vm, bi0); + b1 = vlib_get_buffer(vm, bi1); /* dst lookup was done by ip4 lookup */ mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; @@ -190,30 +231,62 @@ mpls_label_disposition_inline (vlib_main_t * vm, { ip4_header_t *ip0, *ip1; - ip0 = vlib_buffer_get_current (b0); - ip1 = vlib_buffer_get_current (b1); + ip0 = vlib_buffer_get_current(b0); + ip1 = vlib_buffer_get_current(b1); /* * IPv4 input checks on the exposed IP header * including checksum */ - ip4_input_check_x2 (vm, error_node, - b0, b1, ip0, ip1, - &next0, &next1, 1); + ip4_input_check_x2(vm, error_node, + b0, b1, ip0, ip1, + &next0, &next1, 1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP. recalc the chksum + */ + ip0->ttl = vnet_buffer(b0)->mpls.ttl; + ip1->ttl = vnet_buffer(b1)->mpls.ttl; + ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp); + ip1->tos = mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp); + + ip0->checksum = ip4_header_checksum(ip0); + ip1->checksum = ip4_header_checksum(ip1); + } } else if (payload_is_ip6) { ip6_header_t *ip0, *ip1; - ip0 = vlib_buffer_get_current (b0); - ip1 = vlib_buffer_get_current (b1); + ip0 = vlib_buffer_get_current(b0); + ip1 = vlib_buffer_get_current(b1); /* * IPv6 input checks on the exposed IP header */ - ip6_input_check_x2 (vm, error_node, - b0, b1, ip0, ip1, - &next0, &next1); + ip6_input_check_x2(vm, error_node, + b0, b1, ip0, ip1, + &next0, &next1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP + */ + ip0->hop_limit = vnet_buffer(b0)->mpls.ttl; + ip1->hop_limit = vnet_buffer(b1)->mpls.ttl; + + ip6_set_traffic_class_network_order( + ip0, + mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp)); + ip6_set_traffic_class_network_order( + ip1, + mpls_exp_to_ip_dscp(vnet_buffer(b1)->mpls.exp)); + } } vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index; @@ -224,15 +297,19 @@ mpls_label_disposition_inline (vlib_main_t * vm, if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { mpls_label_disposition_trace_t *tr = - vlib_add_trace (vm, node, b0, sizeof (*tr)); + vlib_add_trace(vm, node, b0, sizeof(*tr)); - tr->mdd = mddi0; + tr->mddt_payload_proto = mdd0->mdd_payload_proto; + tr->mddt_rpf_id = mdd0->mdd_rpf_id; + tr->mddt_mode = mdd0->mdd_mode; } if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED)) { mpls_label_disposition_trace_t *tr = - vlib_add_trace (vm, node, b1, sizeof (*tr)); - tr->mdd = mddi1; + vlib_add_trace(vm, node, b1, sizeof(*tr)); + tr->mddt_payload_proto = mdd1->mdd_payload_proto; + tr->mddt_rpf_id = mdd1->mdd_rpf_id; + tr->mddt_mode = mdd1->mdd_mode; } vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, @@ -254,7 +331,7 @@ mpls_label_disposition_inline (vlib_main_t * vm, n_left_from -= 1; n_left_to_next -= 1; - b0 = vlib_get_buffer (vm, bi0); + b0 = vlib_get_buffer(vm, bi0); /* dst lookup was done by ip4 lookup */ mddi0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; @@ -265,24 +342,48 @@ mpls_label_disposition_inline (vlib_main_t * vm, { ip4_header_t *ip0; - ip0 = vlib_buffer_get_current (b0); + ip0 = vlib_buffer_get_current(b0); /* * IPv4 input checks on the exposed IP header * including checksum */ - ip4_input_check_x1 (vm, error_node, b0, ip0, &next0, 1); + ip4_input_check_x1(vm, error_node, b0, ip0, &next0, 1); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP. recalc the chksum + */ + ip0->ttl = vnet_buffer(b0)->mpls.ttl; + ip0->tos = mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp); + ip0->checksum = ip4_header_checksum(ip0); + } } else if (payload_is_ip6) { ip6_header_t *ip0; - ip0 = vlib_buffer_get_current (b0); + ip0 = vlib_buffer_get_current(b0); /* * IPv6 input checks on the exposed IP header */ - ip6_input_check_x1 (vm, error_node, b0, ip0, &next0); + ip6_input_check_x1(vm, error_node, b0, ip0, &next0); + + if (FIB_MPLS_LSP_MODE_UNIFORM == mode) + { + /* + * Copy the TTL from the MPLS packet into the + * exposed IP + */ + ip0->hop_limit = vnet_buffer(b0)->mpls.ttl; + + ip6_set_traffic_class_network_order( + ip0, + mpls_exp_to_ip_dscp(vnet_buffer(b0)->mpls.exp)); + } } vnet_buffer(b0)->ip.adj_index[VLIB_TX] = mdd0->mdd_dpo.dpoi_index; @@ -291,14 +392,16 @@ mpls_label_disposition_inline (vlib_main_t * vm, if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { mpls_label_disposition_trace_t *tr = - vlib_add_trace (vm, node, b0, sizeof (*tr)); - tr->mdd = mddi0; + vlib_add_trace(vm, node, b0, sizeof(*tr)); + tr->mddt_payload_proto = mdd0->mdd_payload_proto; + tr->mddt_rpf_id = mdd0->mdd_rpf_id; + tr->mddt_mode = mdd0->mdd_mode; } vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0); } - vlib_put_next_frame (vm, node, next_index, n_left_to_next); + vlib_put_next_frame(vm, node, next_index, n_left_to_next); } return from_frame->n_vectors; } @@ -306,58 +409,93 @@ mpls_label_disposition_inline (vlib_main_t * vm, static u8 * format_mpls_label_disposition_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 *); - CLIB_UNUSED (mpls_label_disposition_trace_t * t); + CLIB_UNUSED(vlib_main_t * vm) = va_arg(*args, vlib_main_t *); + CLIB_UNUSED(vlib_node_t * node) = va_arg(*args, vlib_node_t *); + CLIB_UNUSED(mpls_label_disposition_trace_t * t); - t = va_arg (*args, mpls_label_disposition_trace_t *); + t = va_arg(*args, mpls_label_disposition_trace_t *); + + s = format(s, "rpf-id:%d %U, %U", + t->mddt_rpf_id, + format_dpo_proto, t->mddt_payload_proto, + format_fib_mpls_lsp_mode, t->mddt_mode); - s = format(s, "disp:%d", t->mdd); return (s); } -static uword -ip4_mpls_label_disposition (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VLIB_NODE_FN (ip4_mpls_label_disposition_pipe_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) +{ + return (mpls_label_disposition_inline(vm, node, frame, 1, 0, + FIB_MPLS_LSP_MODE_PIPE)); +} + +VLIB_REGISTER_NODE(ip4_mpls_label_disposition_pipe_node) = { + .name = "ip4-mpls-label-disposition-pipe", + .vector_size = sizeof(u32), + + .format_trace = format_mpls_label_disposition_trace, + .sibling_of = "ip4-input", + .n_errors = IP4_N_ERROR, + .error_strings = ip4_error_strings, +}; + +VLIB_NODE_FN (ip6_mpls_label_disposition_pipe_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) +{ + return (mpls_label_disposition_inline(vm, node, frame, 0, 1, + FIB_MPLS_LSP_MODE_PIPE)); +} + +VLIB_REGISTER_NODE(ip6_mpls_label_disposition_pipe_node) = { + .name = "ip6-mpls-label-disposition-pipe", + .vector_size = sizeof(u32), + + .format_trace = format_mpls_label_disposition_trace, + .sibling_of = "ip6-input", + .n_errors = IP6_N_ERROR, + .error_strings = ip6_error_strings, +}; + +VLIB_NODE_FN (ip4_mpls_label_disposition_uniform_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { - return (mpls_label_disposition_inline(vm, node, frame, 1, 0)); + return (mpls_label_disposition_inline(vm, node, frame, 1, 0, + FIB_MPLS_LSP_MODE_UNIFORM)); } -VLIB_REGISTER_NODE (ip4_mpls_label_disposition_node) = { - .function = ip4_mpls_label_disposition, - .name = "ip4-mpls-label-disposition", - .vector_size = sizeof (u32), +VLIB_REGISTER_NODE(ip4_mpls_label_disposition_uniform_node) = { + .name = "ip4-mpls-label-disposition-uniform", + .vector_size = sizeof(u32), .format_trace = format_mpls_label_disposition_trace, .sibling_of = "ip4-input", .n_errors = IP4_N_ERROR, .error_strings = ip4_error_strings, }; -VLIB_NODE_FUNCTION_MULTIARCH (ip4_mpls_label_disposition_node, - ip4_mpls_label_disposition) -static uword -ip6_mpls_label_disposition (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) +VLIB_NODE_FN (ip6_mpls_label_disposition_uniform_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * frame) { - return (mpls_label_disposition_inline(vm, node, frame, 0, 1)); + return (mpls_label_disposition_inline(vm, node, frame, 0, 1, + FIB_MPLS_LSP_MODE_UNIFORM)); } -VLIB_REGISTER_NODE (ip6_mpls_label_disposition_node) = { - .function = ip6_mpls_label_disposition, - .name = "ip6-mpls-label-disposition", - .vector_size = sizeof (u32), +VLIB_REGISTER_NODE(ip6_mpls_label_disposition_uniform_node) = { + .name = "ip6-mpls-label-disposition-uniform", + .vector_size = sizeof(u32), .format_trace = format_mpls_label_disposition_trace, .sibling_of = "ip6-input", .n_errors = IP6_N_ERROR, .error_strings = ip6_error_strings, }; -VLIB_NODE_FUNCTION_MULTIARCH (ip6_mpls_label_disposition_node, - ip6_mpls_label_disposition) +#ifndef CLIB_MARCH_VARIANT static void mpls_disp_dpo_mem_show (void) { @@ -374,25 +512,45 @@ const static dpo_vft_t mdd_vft = { .dv_mem_show = mpls_disp_dpo_mem_show, }; -const static char* const mpls_label_disp_ip4_nodes[] = +const static char* const mpls_label_disp_pipe_ip4_nodes[] = +{ + "ip4-mpls-label-disposition-pipe", + NULL, +}; +const static char* const mpls_label_disp_pipe_ip6_nodes[] = +{ + "ip6-mpls-label-disposition-pipe", + NULL, +}; +const static char* const * const mpls_label_disp_pipe_nodes[DPO_PROTO_NUM] = +{ + [DPO_PROTO_IP4] = mpls_label_disp_pipe_ip4_nodes, + [DPO_PROTO_IP6] = mpls_label_disp_pipe_ip6_nodes, +}; + +const static char* const mpls_label_disp_uniform_ip4_nodes[] = { - "ip4-mpls-label-disposition", + "ip4-mpls-label-disposition-uniform", NULL, }; -const static char* const mpls_label_disp_ip6_nodes[] = +const static char* const mpls_label_disp_uniform_ip6_nodes[] = { - "ip6-mpls-label-disposition", + "ip6-mpls-label-disposition-uniform", NULL, }; -const static char* const * const mpls_label_disp_nodes[DPO_PROTO_NUM] = +const static char* const * const mpls_label_disp_uniform_nodes[DPO_PROTO_NUM] = { - [DPO_PROTO_IP4] = mpls_label_disp_ip4_nodes, - [DPO_PROTO_IP6] = mpls_label_disp_ip6_nodes, + [DPO_PROTO_IP4] = mpls_label_disp_uniform_ip4_nodes, + [DPO_PROTO_IP6] = mpls_label_disp_uniform_ip6_nodes, }; void -mpls_disp_dpo_module_init (void) +mpls_disp_dpo_module_init(void) { - dpo_register(DPO_MPLS_DISPOSITION, &mdd_vft, mpls_label_disp_nodes); + dpo_register(DPO_MPLS_DISPOSITION_PIPE, &mdd_vft, + mpls_label_disp_pipe_nodes); + dpo_register(DPO_MPLS_DISPOSITION_UNIFORM, &mdd_vft, + mpls_label_disp_uniform_nodes); } +#endif /* CLIB_MARCH_VARIANT */