From beb4bf7df82658e556a20891cfa04ce375ddb435 Mon Sep 17 00:00:00 2001 From: Hongjun Ni Date: Fri, 25 Nov 2016 00:03:46 +0800 Subject: Augment Vxlan to support NSH-Proxy PatchSet 9: add range check for decap_next_index PatchSet 6: delete runtime range check Change-Id: I415e156d05d09d2ff34f6578924f0b243058f464 Signed-off-by: Hongjun Ni --- vnet/vnet/vxlan-gpe/encap.c | 2 +- vnet/vnet/vxlan/decap.c | 6 +-- vnet/vnet/vxlan/vxlan.c | 85 ++++++++++++++++++++++++++++++++++++++++--- vnet/vnet/vxlan/vxlan.h | 2 + vpp-api-test/vat/api_format.c | 2 +- vpp/vpp-api/api.c | 3 +- 6 files changed, 87 insertions(+), 13 deletions(-) diff --git a/vnet/vnet/vxlan-gpe/encap.c b/vnet/vnet/vxlan-gpe/encap.c index 3f6f43c564c..9cd2c722aa1 100644 --- a/vnet/vnet/vxlan-gpe/encap.c +++ b/vnet/vnet/vxlan-gpe/encap.c @@ -407,7 +407,7 @@ VLIB_REGISTER_NODE (vxlan_gpe_encap_node) = { .next_nodes = { [VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP] = "ip4-lookup", - [VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP] = "ip6-lookup", + [VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP] = "ip6-lookup", [VXLAN_GPE_ENCAP_NEXT_DROP] = "error-drop", }, }; diff --git a/vnet/vnet/vxlan/decap.c b/vnet/vnet/vxlan/decap.c index 05565504669..22f2f85b2bc 100644 --- a/vnet/vnet/vxlan/decap.c +++ b/vnet/vnet/vxlan/decap.c @@ -217,7 +217,7 @@ vxlan_input (vlib_main_t * vm, } t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0); - + next0 = t0->decap_next_index; sw_if_index0 = t0->sw_if_index; len0 = vlib_buffer_length_in_chain (vm, b0); @@ -312,7 +312,7 @@ vxlan_input (vlib_main_t * vm, } t1 = pool_elt_at_index (vxm->tunnels, tunnel_index1); - + next1 = t1->decap_next_index; sw_if_index1 = t1->sw_if_index; len1 = vlib_buffer_length_in_chain (vm, b1); @@ -464,7 +464,7 @@ vxlan_input (vlib_main_t * vm, } t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0); - + next0 = t0->decap_next_index; sw_if_index0 = t0->sw_if_index; len0 = vlib_buffer_length_in_chain (vm, b0); diff --git a/vnet/vnet/vxlan/vxlan.c b/vnet/vnet/vxlan/vxlan.c index bda0bbc968a..a2b89208116 100644 --- a/vnet/vnet/vxlan/vxlan.c +++ b/vnet/vnet/vxlan/vxlan.c @@ -17,6 +17,7 @@ #include #include #include +#include /** * @file @@ -37,6 +38,22 @@ vxlan_main_t vxlan_main; +static u8 * format_decap_next (u8 * s, va_list * args) +{ + u32 next_index = va_arg (*args, u32); + + switch (next_index) + { + case VXLAN_INPUT_NEXT_DROP: + return format (s, "drop"); + case VXLAN_INPUT_NEXT_L2_INPUT: + return format (s, "l2"); + default: + return format (s, "next-index %d", next_index); + } + return s; +} + u8 * format_vxlan_tunnel (u8 * s, va_list * args) { vxlan_tunnel_t * t = va_arg (*args, vxlan_tunnel_t *); @@ -44,11 +61,12 @@ u8 * format_vxlan_tunnel (u8 * s, va_list * args) s = format (s, "[%d] src %U dst %U vni %d encap_fib_index %d sw_if_index %d " - "fib_entry_index %d\n", + "fib_entry_index %d", t - ngm->tunnels, format_ip46_address, &t->src, IP46_TYPE_ANY, format_ip46_address, &t->dst, IP46_TYPE_ANY, t->vni, t->encap_fib_index, t->sw_if_index, t->fib_entry_index); + s = format (s, " decap_next %U\n", format_decap_next, t->decap_next_index); return s; } @@ -176,6 +194,7 @@ const static fib_node_vft_t vxlan_vft = { _(vni) \ _(mcast_sw_if_index) \ _(encap_fib_index) \ +_(decap_next_index) \ _(src) \ _(dst) @@ -245,6 +264,27 @@ static int vxlan6_rewrite (vxlan_tunnel_t * t) return (0); } +static int vxlan_check_decap_next(vxlan_main_t * vxm, u32 is_ip6, u32 decap_next_index) +{ + vlib_main_t * vm = vxm->vlib_main; + vlib_node_runtime_t *r; + + if(!is_ip6) + { + r = vlib_node_get_runtime (vm, vxlan4_input_node.index); + if(decap_next_index >= r->n_next_nodes) + return 1; + } + else + { + r = vlib_node_get_runtime (vm, vxlan6_input_node.index); + if(decap_next_index >= r->n_next_nodes) + return 1; + } + + return 0; +} + int vnet_vxlan_add_del_tunnel (vnet_vxlan_add_del_tunnel_args_t *a, u32 * sw_if_indexp) { @@ -283,6 +323,12 @@ int vnet_vxlan_add_del_tunnel if (p) return VNET_API_ERROR_TUNNEL_EXIST; + /*if not set explicitly, default to l2 */ + if(a->decap_next_index == ~0) + a->decap_next_index = VXLAN_INPUT_NEXT_L2_INPUT; + if (vxlan_check_decap_next(vxm, is_ip6, a->decap_next_index)) + return VNET_API_ERROR_INVALID_DECAP_NEXT; + pool_get_aligned (vxm->tunnels, t, CLIB_CACHE_LINE_BYTES); memset (t, 0, sizeof (*t)); @@ -496,13 +542,37 @@ static u32 fib6_index_from_fib_id (u32 fib_id) return p[0]; } +static uword get_decap_next_for_node(u32 node_index, u32 ipv4_set) +{ + vxlan_main_t * vxm = &vxlan_main; + vlib_main_t * vm = vxm->vlib_main; + uword next_index = ~0; + + if (ipv4_set) + { + next_index = vlib_node_add_next (vm, vxlan4_input_node.index, node_index); + } + else + { + next_index = vlib_node_add_next (vm, vxlan6_input_node.index, node_index); + } + + return next_index; +} + static uword unformat_decap_next (unformat_input_t * input, va_list * args) { u32 * result = va_arg (*args, u32 *); + u32 ipv4_set = va_arg (*args, int); + vxlan_main_t * vxm = &vxlan_main; + vlib_main_t * vm = vxm->vlib_main; + u32 node_index; u32 tmp; - + if (unformat (input, "l2")) *result = VXLAN_INPUT_NEXT_L2_INPUT; + else if (unformat (input, "node %U", unformat_vlib_node, vm, &node_index)) + *result = get_decap_next_for_node(node_index, ipv4_set); else if (unformat (input, "%d", &tmp)) *result = tmp; else @@ -525,7 +595,7 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, u8 ipv6_set = 0; u32 encap_fib_index = 0; u32 mcast_sw_if_index = ~0; - u32 decap_next_index = ~0; + u32 decap_next_index = VXLAN_INPUT_NEXT_L2_INPUT; u32 vni = 0; u32 tmp; int rv; @@ -595,7 +665,7 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, return clib_error_return (0, "nonexistent encap-vrf-id %d", tmp); } else if (unformat (line_input, "decap-next %U", unformat_decap_next, - &decap_next_index)) + &decap_next_index, ipv4_set)) ; else if (unformat (line_input, "vni %d", &vni)) { @@ -627,6 +697,9 @@ vxlan_add_del_tunnel_command_fn (vlib_main_t * vm, if (ip46_address_cmp(&src, &dst) == 0) return clib_error_return (0, "src and dst addresses are identical"); + if (decap_next_index == ~0) + return clib_error_return (0, "next node not found"); + if (vni == 0) return clib_error_return (0, "vni not specified"); @@ -689,7 +762,7 @@ VLIB_CLI_COMMAND (create_vxlan_tunnel_command, static) = { .short_help = "create vxlan tunnel src " " {dst |group } vni " - " [encap-vrf-id ]", + " [encap-vrf-id ] [decap-next [l2|node ]] [del]", .function = vxlan_add_del_tunnel_command_fn, }; /* *INDENT-ON* */ @@ -719,7 +792,7 @@ show_vxlan_tunnel_command_fn (vlib_main_t * vm, * @cliexpar * Example of how to display the VXLAN Tunnel entries: * @cliexstart{show vxlan tunnel} - * [0] src 10.0.3.1 dst 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 + * [0] src 10.0.3.1 dst 10.0.3.3 vni 13 encap_fib_index 0 sw_if_index 5 decap_next l2 * @cliexend ?*/ /* *INDENT-OFF* */ diff --git a/vnet/vnet/vxlan/vxlan.h b/vnet/vnet/vxlan/vxlan.h index 3041df27dcc..fe31ce160b8 100644 --- a/vnet/vnet/vxlan/vxlan.h +++ b/vnet/vnet/vxlan/vxlan.h @@ -86,6 +86,8 @@ typedef struct { ip46_address_t dst; u32 mcast_sw_if_index; + /* decap next index */ + u32 decap_next_index; /* The FIB index for src/dst addresses */ u32 encap_fib_index; diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index 9d80c42aba2..2925c9bf26e 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -16808,7 +16808,7 @@ _(sw_if_l2tpv3_tunnel_dump, "") \ _(vxlan_add_del_tunnel, \ "src { dst | group \n" \ "{ | mcast_sw_if_index } }\n" \ - "vni [encap-vrf-id ] [decap-next l2|ip4|ip6] [del]") \ + "vni [encap-vrf-id ] [decap-next ] [del]") \ _(vxlan_tunnel_dump, "[ | sw_if_index ]") \ _(gre_add_del_tunnel, \ "src dst [outer-fib-id ] [teb] [del]\n") \ diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index a011c650b8e..c110769b620 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -4545,8 +4545,7 @@ static void send_vxlan_tunnel_details } rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index); rmp->vni = htonl (t->vni); - /* decap_next_index is deprecated, hard code to l2-input */ - rmp->decap_next_index = htonl (VXLAN_INPUT_NEXT_L2_INPUT); + rmp->decap_next_index = htonl (t->decap_next_index); rmp->sw_if_index = htonl (t->sw_if_index); rmp->is_ipv6 = is_ipv6; rmp->context = context; -- cgit 1.2.3-korg