diff options
author | Vengada Govindan <venggovi@cisco.com> | 2016-10-12 05:54:09 -0700 |
---|---|---|
committer | Vengada Govindan <venggovi@cisco.com> | 2016-12-09 06:15:02 +0000 |
commit | 6d403a013276f095e542c9b6281db96354fa6f07 (patch) | |
tree | 3954b21a8fe2bb789d42f6f6234344d39c4e1e4d /vnet | |
parent | c9b20bc7a5399fd1e7bf2d33e7c4f1f08ef1c1e4 (diff) |
VPP-470: Introduce VxLAN-GPE as transport for iOAM.
See Jira ticket for more details
- New plugins created to (a) Add VxLAN-GPE as transport (b) Provide export infra for
VxLAN-GPE.
Change-Id: Ife50c7434f53d17a4783062310f73d063d53494c
Signed-off-by: Vengada Govindan <venggovi@cisco.com>
Diffstat (limited to 'vnet')
-rw-r--r-- | vnet/vnet/ip/ip6_hop_by_hop.h | 7 | ||||
-rw-r--r-- | vnet/vnet/vxlan-gpe/decap.c | 66 | ||||
-rw-r--r-- | vnet/vnet/vxlan-gpe/encap.c | 46 | ||||
-rw-r--r-- | vnet/vnet/vxlan-gpe/vxlan_gpe.c | 47 | ||||
-rw-r--r-- | vnet/vnet/vxlan-gpe/vxlan_gpe.h | 27 | ||||
-rw-r--r-- | vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h | 5 |
6 files changed, 137 insertions, 61 deletions
diff --git a/vnet/vnet/ip/ip6_hop_by_hop.h b/vnet/vnet/ip/ip6_hop_by_hop.h index 7d157cf55e7..e86a6d05f82 100644 --- a/vnet/vnet/ip/ip6_hop_by_hop.h +++ b/vnet/vnet/ip/ip6_hop_by_hop.h @@ -69,11 +69,6 @@ typedef struct { /* Enabling analyis of iOAM data on decap node */ u8 has_analyse_option; -#define TSP_SECONDS 0 -#define TSP_MILLISECONDS 1 -#define TSP_MICROSECONDS 2 -#define TSP_NANOSECONDS 3 - /* Array of function pointers to ADD and POP HBH option handling routines */ u8 options_size[MAX_IP6_HBH_OPTION]; int (*add_options[MAX_IP6_HBH_OPTION])(u8 *rewrite_string, u8 *rewrite_size); @@ -189,4 +184,6 @@ static inline u8 is_seqno_enabled (void) return (ip6_hop_by_hop_ioam_main.has_seqno_option); } +int +ip6_trace_profile_setup (); #endif /* __included_ip6_hop_by_hop_ioam_h__ */ diff --git a/vnet/vnet/vxlan-gpe/decap.c b/vnet/vnet/vxlan-gpe/decap.c index f6d1402d3f0..22ab4b62f66 100644 --- a/vnet/vnet/vxlan-gpe/decap.c +++ b/vnet/vnet/vxlan-gpe/decap.c @@ -211,10 +211,14 @@ vxlan_gpe_input (vlib_main_t * vm, if (is_ip4) { - next0 = (iuvn4_0->vxlan.protocol < node->n_next_nodes) ? - iuvn4_0->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP; - next1 = (iuvn4_1->vxlan.protocol < node->n_next_nodes) ? - iuvn4_1->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP; + next0 = + (iuvn4_0->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn4_0->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; + next1 = + (iuvn4_1->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn4_1->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; key4_0.local = iuvn4_0->ip4.dst_address.as_u32; key4_1.local = iuvn4_1->ip4.dst_address.as_u32; @@ -273,6 +277,28 @@ vxlan_gpe_input (vlib_main_t * vm, } else /* is_ip6 */ { + next0 = + (iuvn6_0->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn6_0->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; + next1 = + (iuvn6_1->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn6_1->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; + + key6_0.local.as_u64[0] = iuvn6_0->ip6.dst_address.as_u64[0]; + key6_0.local.as_u64[1] = iuvn6_0->ip6.dst_address.as_u64[1]; + key6_1.local.as_u64[0] = iuvn6_1->ip6.dst_address.as_u64[0]; + key6_1.local.as_u64[1] = iuvn6_1->ip6.dst_address.as_u64[1]; + + key6_0.remote.as_u64[0] = iuvn6_0->ip6.src_address.as_u64[0]; + key6_0.remote.as_u64[1] = iuvn6_0->ip6.src_address.as_u64[1]; + key6_1.remote.as_u64[0] = iuvn6_1->ip6.src_address.as_u64[0]; + key6_1.remote.as_u64[1] = iuvn6_1->ip6.src_address.as_u64[1]; + + key6_0.vni = iuvn6_0->vxlan.vni_res; + key6_1.vni = iuvn6_1->vxlan.vni_res; + /* Processing for key6_0 */ if (PREDICT_FALSE(memcmp (&key6_0, &last_key6, sizeof(last_key6)) != 0)) { @@ -293,7 +319,6 @@ vxlan_gpe_input (vlib_main_t * vm, t0 = pool_elt_at_index(ngm->tunnels, tunnel_index0); - next0 = t0->protocol; sw_if_index0 = t0->sw_if_index; len0 = vlib_buffer_length_in_chain (vm, b0); @@ -378,7 +403,6 @@ vxlan_gpe_input (vlib_main_t * vm, t1 = pool_elt_at_index(ngm->tunnels, tunnel_index1); - next1 = t1->protocol; sw_if_index1 = t1->sw_if_index; len1 = vlib_buffer_length_in_chain (vm, b1); @@ -477,8 +501,9 @@ vxlan_gpe_input (vlib_main_t * vm, if (is_ip4) { next0 = - (iuvn4_0->vxlan.protocol < node->n_next_nodes) ? - iuvn4_0->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP; + (iuvn4_0->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn4_0->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; key4_0.local = iuvn4_0->ip4.dst_address.as_u32; key4_0.remote = iuvn4_0->ip4.src_address.as_u32; @@ -507,8 +532,10 @@ vxlan_gpe_input (vlib_main_t * vm, } else /* is_ip6 */ { - next0 = (iuvn6_0->vxlan.protocol < node->n_next_nodes) ? - iuvn6_0->vxlan.protocol : VXLAN_GPE_INPUT_NEXT_DROP; + next0 = + (iuvn6_0->vxlan.protocol < VXLAN_GPE_PROTOCOL_MAX)? + ngm->decap_next_node_list[iuvn6_0->vxlan.protocol]: \ + VXLAN_GPE_INPUT_NEXT_DROP; key6_0.local.as_u64[0] = iuvn6_0->ip6.dst_address.as_u64[0]; key6_0.local.as_u64[1] = iuvn6_0->ip6.dst_address.as_u64[1]; @@ -536,7 +563,6 @@ vxlan_gpe_input (vlib_main_t * vm, t0 = pool_elt_at_index(ngm->tunnels, tunnel_index0); - next0 = t0->protocol; sw_if_index0 = t0->sw_if_index; len0 = vlib_buffer_length_in_chain (vm, b0); @@ -614,6 +640,24 @@ vxlan4_gpe_input (vlib_main_t * vm, vlib_node_runtime_t * node, return vxlan_gpe_input (vm, node, from_frame, /* is_ip4 */1); } + +void +vxlan_gpe_register_decap_protocol (u8 protocol_id, uword next_node_index) +{ + vxlan_gpe_main_t *hm = &vxlan_gpe_main; + hm->decap_next_node_list[protocol_id] = next_node_index; + return; +} + +void +vxlan_gpe_unregister_decap_protocol (u8 protocol_id, uword next_node_index) +{ + vxlan_gpe_main_t *hm = &vxlan_gpe_main; + hm->decap_next_node_list[protocol_id] = VXLAN_GPE_INPUT_NEXT_DROP; + return; +} + + /** * @brief Graph processing dispatch function for IPv6 VXLAN GPE * diff --git a/vnet/vnet/vxlan-gpe/encap.c b/vnet/vnet/vxlan-gpe/encap.c index 9cd2c722aa1..3a486e5606e 100644 --- a/vnet/vnet/vxlan-gpe/encap.c +++ b/vnet/vnet/vxlan-gpe/encap.c @@ -48,16 +48,6 @@ typedef enum { } vxlan_gpe_encap_error_t; /** - * @brief Struct for defining VXLAN GPE next nodes - */ -typedef enum { - VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP, - VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP, - VXLAN_GPE_ENCAP_NEXT_DROP, - VXLAN_GPE_ENCAP_N_NEXT -} vxlan_gpe_encap_next_t; - -/** * @brief Struct for tracing VXLAN GPE encapsulated packets */ typedef struct { @@ -96,22 +86,14 @@ u8 * format_vxlan_gpe_encap_trace (u8 * s, va_list * args) */ always_inline void vxlan_gpe_encap_one_inline (vxlan_gpe_main_t * ngm, vlib_buffer_t * b0, - vxlan_gpe_tunnel_t * t0, u32 * next0, u8 is_v4) + vxlan_gpe_tunnel_t * t0, u32 * next0, + u8 is_v4) { ASSERT(sizeof(ip4_vxlan_gpe_header_t) == 36); ASSERT(sizeof(ip6_vxlan_gpe_header_t) == 56); - if (is_v4) - { - ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, 36, 1); - next0[0] = VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP; - - } - else - { - ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, 56, 0); - next0[0] = VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP; - } + ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, t0->rewrite_size, is_v4); + next0[0] = t0->encap_next_node; } /** @@ -128,25 +110,17 @@ vxlan_gpe_encap_one_inline (vxlan_gpe_main_t * ngm, vlib_buffer_t * b0, * */ always_inline void -vxlan_gpe_encap_two_inline (vxlan_gpe_main_t * ngm, vlib_buffer_t * b0, vlib_buffer_t * b1, - vxlan_gpe_tunnel_t * t0, vxlan_gpe_tunnel_t * t1, u32 * next0, +vxlan_gpe_encap_two_inline (vxlan_gpe_main_t * ngm, vlib_buffer_t * b0, + vlib_buffer_t * b1, vxlan_gpe_tunnel_t * t0, + vxlan_gpe_tunnel_t * t1, u32 * next0, u32 * next1, u8 is_v4) { ASSERT(sizeof(ip4_vxlan_gpe_header_t) == 36); ASSERT(sizeof(ip6_vxlan_gpe_header_t) == 56); - if (is_v4) - { - ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, 36, 1); - ip_udp_encap_one (ngm->vlib_main, b1, t1->rewrite, 36, 1); - next0[0] = next1[0] = VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP; - } - else - { - ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, 56, 0); - ip_udp_encap_one (ngm->vlib_main, b1, t1->rewrite, 56, 0); - next0[0] = next1[0] = VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP; - } + ip_udp_encap_one (ngm->vlib_main, b0, t0->rewrite, t0->rewrite_size, is_v4); + ip_udp_encap_one (ngm->vlib_main, b1, t1->rewrite, t1->rewrite_size, is_v4); + next0[0] = next1[0] = t0->encap_next_node; } /** diff --git a/vnet/vnet/vxlan-gpe/vxlan_gpe.c b/vnet/vnet/vxlan-gpe/vxlan_gpe.c index 979864e9092..b97510c4ee3 100644 --- a/vnet/vnet/vxlan-gpe/vxlan_gpe.c +++ b/vnet/vnet/vxlan-gpe/vxlan_gpe.c @@ -121,6 +121,7 @@ VNET_DEVICE_CLASS (vxlan_gpe_device_class,static) = { .admin_up_down_function = vxlan_gpe_interface_admin_up_down, }; + /** * @brief Formatting function for tracing VXLAN GPE with length * @@ -172,15 +173,17 @@ _(decap_fib_index) * @return rc * */ -static int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t) +int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size, + u8 protocol_override, uword encap_next_node) { u8 *rw = 0; ip4_header_t * ip0; ip4_vxlan_gpe_header_t * h0; int len; - len = sizeof (*h0); + len = sizeof (*h0) + extension_size; + vec_free(t->rewrite); vec_validate_aligned (rw, len-1, CLIB_CACHE_LINE_BYTES); h0 = (ip4_vxlan_gpe_header_t *) rw; @@ -203,10 +206,19 @@ static int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t) /* VXLAN header. Are we having fun yet? */ h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P; h0->vxlan.ver_res = VXLAN_GPE_VERSION; - h0->vxlan.protocol = t->protocol; + if (protocol_override) + { + h0->vxlan.protocol = protocol_override; + } + else + { + h0->vxlan.protocol = t->protocol; + } + t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) + extension_size; h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8); t->rewrite = rw; + t->encap_next_node = encap_next_node; return (0); } @@ -218,15 +230,17 @@ static int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t) * @return rc * */ -static int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t) +int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size, + u8 protocol_override, uword encap_next_node) { u8 *rw = 0; ip6_header_t * ip0; ip6_vxlan_gpe_header_t * h0; int len; - len = sizeof (*h0); + len = sizeof (*h0) + extension_size; + vec_free(t->rewrite); vec_validate_aligned (rw, len-1, CLIB_CACHE_LINE_BYTES); h0 = (ip6_vxlan_gpe_header_t *) rw; @@ -249,10 +263,19 @@ static int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t) /* VXLAN header. Are we having fun yet? */ h0->vxlan.flags = VXLAN_GPE_FLAGS_I | VXLAN_GPE_FLAGS_P; h0->vxlan.ver_res = VXLAN_GPE_VERSION; - h0->vxlan.protocol = t->protocol; + if (protocol_override) + { + h0->vxlan.protocol = t->protocol; + } + else + { + h0->vxlan.protocol = protocol_override; + } + t->rewrite_size = sizeof(ip4_vxlan_gpe_header_t) + extension_size; h0->vxlan.vni_res = clib_host_to_net_u32 (t->vni<<8); t->rewrite = rw; + t->encap_next_node = encap_next_node; return (0); } @@ -319,9 +342,9 @@ int vnet_vxlan_gpe_add_del_tunnel if (!a->is_ip6) t->flags |= VXLAN_GPE_TUNNEL_IS_IPV4; if (!a->is_ip6) { - rv = vxlan4_gpe_rewrite (t); + rv = vxlan4_gpe_rewrite (t, 0, 0, VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP); } else { - rv = vxlan6_gpe_rewrite (t); + rv = vxlan6_gpe_rewrite (t, 0, 0, VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP); } if (rv) @@ -621,6 +644,14 @@ clib_error_t *vxlan_gpe_init (vlib_main_t *vm) vxlan4_gpe_input_node.index, 1 /* is_ip4 */); udp_register_dst_port (vm, UDP_DST_PORT_vxlan6_gpe, vxlan6_gpe_input_node.index, 0 /* is_ip4 */); + + /* Register the list of standard decap protocols supported */ + vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP4, + VXLAN_GPE_INPUT_NEXT_IP4_INPUT); + vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_IP6, + VXLAN_GPE_INPUT_NEXT_IP6_INPUT); + vxlan_gpe_register_decap_protocol (VXLAN_GPE_PROTOCOL_ETHERNET, + VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT); return 0; } diff --git a/vnet/vnet/vxlan-gpe/vxlan_gpe.h b/vnet/vnet/vxlan-gpe/vxlan_gpe.h index e33725f3ef3..1b4bc44e7bb 100644 --- a/vnet/vnet/vxlan-gpe/vxlan_gpe.h +++ b/vnet/vnet/vxlan-gpe/vxlan_gpe.h @@ -114,6 +114,12 @@ typedef struct { /** flags */ u32 flags; + + /** rewrite size for dynamic plugins like iOAM */ + u8 rewrite_size; + + /** Next node after VxLAN-GPE encap */ + uword encap_next_node; } vxlan_gpe_tunnel_t; /** Flags for vxlan_gpe_tunnel_t */ @@ -162,6 +168,9 @@ typedef struct { vlib_main_t * vlib_main; /** State convenience vnet_main_t */ vnet_main_t * vnet_main; + + /** List of next nodes for the decap indexed on protocol */ + uword decap_next_node_list[VXLAN_GPE_PROTOCOL_MAX]; } vxlan_gpe_main_t; vxlan_gpe_main_t vxlan_gpe_main; @@ -188,7 +197,25 @@ int vnet_vxlan_gpe_add_del_tunnel (vnet_vxlan_gpe_add_del_tunnel_args_t *a, u32 * sw_if_indexp); +int vxlan4_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size, + u8 protocol_override, uword encap_next_node); +int vxlan6_gpe_rewrite (vxlan_gpe_tunnel_t * t, u32 extension_size, + u8 protocol_override, uword encap_next_node); + +/** + * @brief Struct for defining VXLAN GPE next nodes + */ +typedef enum { + VXLAN_GPE_ENCAP_NEXT_IP4_LOOKUP, + VXLAN_GPE_ENCAP_NEXT_IP6_LOOKUP, + VXLAN_GPE_ENCAP_NEXT_DROP, + VXLAN_GPE_ENCAP_N_NEXT +} vxlan_gpe_encap_next_t; + + +void vxlan_gpe_unregister_decap_protocol (u8 protocol_id, uword next_node_index); +void vxlan_gpe_register_decap_protocol (u8 protocol_id, uword next_node_index); #endif /* included_vnet_vxlan_gpe_h */ diff --git a/vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h b/vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h index e5501b95e3f..ec3c2e586e1 100644 --- a/vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h +++ b/vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h @@ -68,7 +68,8 @@ _ (0x01, IP4) \ _ (0x02, IP6) \ _ (0x03, ETHERNET) \ -_ (0x04, NSH) +_ (0x04, NSH) \ +_ (0x05, IOAM) /** @@ -77,11 +78,13 @@ _ (0x04, NSH) * 2 - IP6 * 3 - ETHERNET * 4 - NSH + * 5 - IOAM */ typedef enum { #define _(n,f) VXLAN_GPE_PROTOCOL_##f = n, foreach_vxlan_gpe_protocol #undef _ + VXLAN_GPE_PROTOCOL_MAX, } vxlan_gpe_protocol_t; /** |