summaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
authorVengada Govindan <venggovi@cisco.com>2016-10-12 05:54:09 -0700
committerVengada Govindan <venggovi@cisco.com>2016-12-09 06:15:02 +0000
commit6d403a013276f095e542c9b6281db96354fa6f07 (patch)
tree3954b21a8fe2bb789d42f6f6234344d39c4e1e4d /vnet
parentc9b20bc7a5399fd1e7bf2d33e7c4f1f08ef1c1e4 (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.h7
-rw-r--r--vnet/vnet/vxlan-gpe/decap.c66
-rw-r--r--vnet/vnet/vxlan-gpe/encap.c46
-rw-r--r--vnet/vnet/vxlan-gpe/vxlan_gpe.c47
-rw-r--r--vnet/vnet/vxlan-gpe/vxlan_gpe.h27
-rw-r--r--vnet/vnet/vxlan-gpe/vxlan_gpe_packet.h5
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;
/**