summaryrefslogtreecommitdiffstats
path: root/src/examples/srv6-sample-localsid/node.c
diff options
context:
space:
mode:
authorPablo Camarillo <pcamaril@cisco.com>2017-06-06 15:18:12 +0200
committerDamjan Marion <dmarion.lists@gmail.com>2017-06-07 13:01:33 +0000
commit7a4e0925f58f04cd31e4c37def959600d888940c (patch)
tree26054b7d555b9b65f5686ad2623f599a0817d116 /src/examples/srv6-sample-localsid/node.c
parent0018a3e54efcf6dfbc08ae307b366ee6c4fb3257 (diff)
VPP-872 and End.T function for SRv6
Fixes VPP-872 and adds support for End.T Change-Id: I3c32cb6e412f37babe1abd293c0b6b49367fc2a9 Signed-off-by: Pablo Camarillo <pcamaril@cisco.com>
Diffstat (limited to 'src/examples/srv6-sample-localsid/node.c')
-rw-r--r--src/examples/srv6-sample-localsid/node.c103
1 files changed, 82 insertions, 21 deletions
diff --git a/src/examples/srv6-sample-localsid/node.c b/src/examples/srv6-sample-localsid/node.c
index e83e23525f0..3ac7108bb08 100644
--- a/src/examples/srv6-sample-localsid/node.c
+++ b/src/examples/srv6-sample-localsid/node.c
@@ -59,43 +59,102 @@ typedef enum {
} srv6_localsid_sample_next_t;
/**
- * @brief Function doing End processing.
+ * @brief Function doing End processing.
*/
-//Fixme: support OAM (hop-by-hop header) here!
static_always_inline void
end_srh_processing (vlib_node_runtime_t * node,
- vlib_buffer_t * b0,
- ip6_header_t * ip0,
- ip6_sr_header_t * sr0,
- u32 * next0)
+ vlib_buffer_t * b0,
+ ip6_header_t * ip0,
+ ip6_sr_header_t * sr0,
+ ip6_sr_localsid_t * ls0,
+ u32 * next0,
+ u8 psp,
+ ip6_ext_header_t * prev0)
{
ip6_address_t *new_dst0;
- if(PREDICT_TRUE(ip0->protocol == IP_PROTOCOL_IPV6_ROUTE))
+ if (PREDICT_TRUE (sr0->type == ROUTING_HEADER_TYPE_SR))
{
- if(PREDICT_TRUE(sr0->type == ROUTING_HEADER_TYPE_SR))
+ if (sr0->segments_left == 1 && psp)
{
- if(PREDICT_TRUE(sr0->segments_left != 0))
+ u32 new_l0, sr_len;
+ u64 *copy_dst0, *copy_src0;
+ u32 copy_len_u64s0 = 0;
+
+ ip0->dst_address.as_u64[0] = sr0->segments->as_u64[0];
+ ip0->dst_address.as_u64[1] = sr0->segments->as_u64[1];
+
+ /* Remove the SRH taking care of the rest of IPv6 ext header */
+ if (prev0)
+ prev0->next_hdr = sr0->protocol;
+ else
+ ip0->protocol = sr0->protocol;
+
+ sr_len = ip6_ext_header_len (sr0);
+ vlib_buffer_advance (b0, sr_len);
+ new_l0 = clib_net_to_host_u16 (ip0->payload_length) - sr_len;
+ ip0->payload_length = clib_host_to_net_u16 (new_l0);
+ copy_src0 = (u64 *) ip0;
+ copy_dst0 = copy_src0 + (sr0->length + 1);
+ /* number of 8 octet units to copy
+ * By default in absence of extension headers it is equal to length of ip6 header
+ * With extension headers it number of 8 octet units of ext headers preceding
+ * SR header
+ */
+ copy_len_u64s0 =
+ (((u8 *) sr0 - (u8 *) ip0) - sizeof (ip6_header_t)) >> 3;
+ copy_dst0[4 + copy_len_u64s0] = copy_src0[4 + copy_len_u64s0];
+ copy_dst0[3 + copy_len_u64s0] = copy_src0[3 + copy_len_u64s0];
+ copy_dst0[2 + copy_len_u64s0] = copy_src0[2 + copy_len_u64s0];
+ copy_dst0[1 + copy_len_u64s0] = copy_src0[1 + copy_len_u64s0];
+ copy_dst0[0 + copy_len_u64s0] = copy_src0[0 + copy_len_u64s0];
+
+ int i;
+ for (i = copy_len_u64s0 - 1; i >= 0; i--)
{
- sr0->segments_left -= 1;
- new_dst0 = (ip6_address_t *)(sr0->segments);
- new_dst0 += sr0->segments_left;
- ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
- ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];
+ copy_dst0[i] = copy_src0[i];
}
- else
+
+ if (ls0->behavior == SR_BEHAVIOR_X)
+ {
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj;
+ *next0 = SR_LOCALSID_NEXT_IP6_REWRITE;
+ }
+ else if(ls0->behavior == SR_BEHAVIOR_T)
{
- *next0 = SRV6_SAMPLE_LOCALSID_NEXT_ERROR;
- b0->error = node->errors[SRV6_LOCALSID_COUNTER_NO_SRH];
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
+ }
+ }
+ else if (PREDICT_TRUE(sr0->segments_left > 0))
+ {
+ sr0->segments_left -= 1;
+ new_dst0 = (ip6_address_t *) (sr0->segments);
+ new_dst0 += sr0->segments_left;
+ ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
+ ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];
+
+ if (ls0->behavior == SR_BEHAVIOR_X)
+ {
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0->nh_adj;
+ *next0 = SR_LOCALSID_NEXT_IP6_REWRITE;
+ }
+ else if(ls0->behavior == SR_BEHAVIOR_T)
+ {
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ls0->vrf_index;
}
}
else
{
- /* Error. Routing header of type != SR */
- *next0 = SRV6_SAMPLE_LOCALSID_NEXT_ERROR;
- b0->error = node->errors[SRV6_LOCALSID_COUNTER_NO_SRH];
+ *next0 = SR_LOCALSID_NEXT_ERROR;
+ b0->error = node->errors[SR_LOCALSID_ERROR_NO_MORE_SEGMENTS];
}
}
+ else
+ {
+ /* Error. Routing header of type != SR */
+ *next0 = SR_LOCALSID_NEXT_ERROR;
+ b0->error = node->errors[SR_LOCALSID_ERROR_NO_SRH];
+ }
}
/*
@@ -129,6 +188,7 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram
vlib_buffer_t * b0;
ip6_header_t * ip0 = 0;
ip6_sr_header_t * sr0;
+ ip6_ext_header_t *prev0
u32 next0 = SRV6_SAMPLE_LOCALSID_NEXT_IP6LOOKUP;
ip6_sr_localsid_t *ls0;
srv6_localsid_sample_per_sid_memory_t *ls0_mem;
@@ -149,7 +209,8 @@ srv6_localsid_sample_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_fram
ls0_mem = ls0->plugin_mem;
/* SRH processing */
- end_srh_processing (node, b0, ip0, sr0, &next0);
+ ip6_ext_header_find_t (ip0, prev0, sr0, IP_PROTOCOL_IPV6_ROUTE);
+ end_decaps_srh_processing (node, b0, ip0, sr0, ls0, &next0);
/* ==================================================================== */
/* INSERT CODE HERE */