sr: SRv6 FlowLabel Added
Type: improvement
Signed-off-by: Jakub Horn <jhorn@cisco.com>
Change-Id: I06401a8645615d139893dca27d07bb3b3214bea7
diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c
index 3e8a4e4..c7ac44b 100644
--- a/src/vnet/srv6/sr_policy_rewrite.c
+++ b/src/vnet/srv6/sr_policy_rewrite.c
@@ -1238,14 +1238,21 @@
ip6_header_t * ip0, ip6_header_t * ip0_encap)
{
u32 new_l0;
+ u32 flow_label;
ip0_encap->hop_limit -= 1;
new_l0 =
ip0->payload_length + sizeof (ip6_header_t) +
clib_net_to_host_u16 (ip0_encap->payload_length);
ip0->payload_length = clib_host_to_net_u16 (new_l0);
- ip0->ip_version_traffic_class_and_flow_label =
- ip0_encap->ip_version_traffic_class_and_flow_label;
+
+ flow_label = ip6_compute_flow_hash (ip0_encap, IP_FLOW_HASH_DEFAULT);
+ ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 |
+ (clib_net_to_host_u32 (
+ ip0_encap->ip_version_traffic_class_and_flow_label) &
+ 0xfff00000) |
+ (flow_label & 0x0000ffff));
}
/**
@@ -1510,6 +1517,7 @@
ip6_sr_header_t *sr0;
u32 checksum0;
+ u32 flow_label;
/* Inner IPv4: Decrement TTL & update checksum */
ip0_encap->ttl -= 1;
@@ -1520,9 +1528,10 @@
/* Outer IPv6: Update length, FL, proto */
new_l0 = ip0->payload_length + clib_net_to_host_u16 (ip0_encap->length);
ip0->payload_length = clib_host_to_net_u16 (new_l0);
- ip0->ip_version_traffic_class_and_flow_label =
- clib_host_to_net_u32 (0 | ((6 & 0xF) << 28) |
- ((ip0_encap->tos & 0xFF) << 20));
+ flow_label = ip4_compute_flow_hash (ip0_encap, IP_FLOW_HASH_DEFAULT);
+ ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((ip0_encap->tos & 0xFF) << 20) |
+ (flow_label & 0x0000ffff));
if (ip0->protocol == IP_PROTOCOL_IPV6_ROUTE)
{
sr0 = (void *) (ip0 + 1);
@@ -1861,6 +1870,7 @@
ip6_sr_header_t *sr0, *sr1, *sr2, *sr3;
ip6_sr_policy_t *sp0, *sp1, *sp2, *sp3;
ip6_sr_sl_t *sl0, *sl1, *sl2, *sl3;
+ u32 flow_label0, flow_label1, flow_label2, flow_label3;
/* Prefetch next iteration. */
{
@@ -1916,12 +1926,16 @@
sm->sw_iface_sr_policies[vnet_buffer
(b3)->sw_if_index
[VLIB_RX]]);
+ flow_label0 = l2_flow_hash (b0);
+ flow_label1 = l2_flow_hash (b1);
+ flow_label2 = l2_flow_hash (b2);
+ flow_label3 = l2_flow_hash (b3);
if (vec_len (sp0->segments_lists) == 1)
vnet_buffer (b0)->ip.adj_index[VLIB_TX] = sp0->segments_lists[0];
else
{
- vnet_buffer (b0)->ip.flow_hash = l2_flow_hash (b0);
+ vnet_buffer (b0)->ip.flow_hash = flow_label0;
vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
sp0->segments_lists[(vnet_buffer (b0)->ip.flow_hash &
(vec_len (sp0->segments_lists) - 1))];
@@ -1931,7 +1945,7 @@
vnet_buffer (b1)->ip.adj_index[VLIB_TX] = sp1->segments_lists[1];
else
{
- vnet_buffer (b1)->ip.flow_hash = l2_flow_hash (b1);
+ vnet_buffer (b1)->ip.flow_hash = flow_label1;
vnet_buffer (b1)->ip.adj_index[VLIB_TX] =
sp1->segments_lists[(vnet_buffer (b1)->ip.flow_hash &
(vec_len (sp1->segments_lists) - 1))];
@@ -1941,7 +1955,7 @@
vnet_buffer (b2)->ip.adj_index[VLIB_TX] = sp2->segments_lists[2];
else
{
- vnet_buffer (b2)->ip.flow_hash = l2_flow_hash (b2);
+ vnet_buffer (b2)->ip.flow_hash = flow_label2;
vnet_buffer (b2)->ip.adj_index[VLIB_TX] =
sp2->segments_lists[(vnet_buffer (b2)->ip.flow_hash &
(vec_len (sp2->segments_lists) - 1))];
@@ -1951,7 +1965,7 @@
vnet_buffer (b3)->ip.adj_index[VLIB_TX] = sp3->segments_lists[3];
else
{
- vnet_buffer (b3)->ip.flow_hash = l2_flow_hash (b3);
+ vnet_buffer (b3)->ip.flow_hash = flow_label3;
vnet_buffer (b3)->ip.adj_index[VLIB_TX] =
sp3->segments_lists[(vnet_buffer (b3)->ip.flow_hash &
(vec_len (sp3->segments_lists) - 1))];
@@ -2044,8 +2058,16 @@
else
ip3->protocol = IP_PROTOCOL_IP6_ETHERNET;
- /* Which Traffic class and flow label do I set ? */
- //ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32(0|((6&0xF)<<28)|((ip0_encap->tos&0xFF)<<20));
+ /* TC is set to 0 for all ethernet frames, should be taken from COS
+ * od DSCP of encapsulated packet in the future */
+ ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((0x00) << 20) | (flow_label0 & 0xffff));
+ ip1->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((0x00) << 20) | (flow_label1 & 0xffff));
+ ip2->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((0x00) << 20) | (flow_label2 & 0xffff));
+ ip3->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((0x00) << 20) | (flow_label3 & 0xffff));
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
@@ -2107,6 +2129,7 @@
ip6_sr_policy_t *sp0;
ip6_sr_sl_t *sl0;
u32 next0 = SR_POLICY_REWRITE_NEXT_IP6_LOOKUP;
+ u32 flow_label0;
bi0 = from[0];
to_next[0] = bi0;
@@ -2121,13 +2144,14 @@
sm->sw_iface_sr_policies[vnet_buffer
(b0)->sw_if_index
[VLIB_RX]]);
+ flow_label0 = l2_flow_hash (b0);
/* In case there is more than one SL, LB among them */
if (vec_len (sp0->segments_lists) == 1)
vnet_buffer (b0)->ip.adj_index[VLIB_TX] = sp0->segments_lists[0];
else
{
- vnet_buffer (b0)->ip.flow_hash = l2_flow_hash (b0);
+ vnet_buffer (b0)->ip.flow_hash = flow_label0;
vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
sp0->segments_lists[(vnet_buffer (b0)->ip.flow_hash &
(vec_len (sp0->segments_lists) - 1))];
@@ -2158,6 +2182,9 @@
else
ip0->protocol = IP_PROTOCOL_IP6_ETHERNET;
+ ip0->ip_version_traffic_class_and_flow_label = clib_host_to_net_u32 (
+ 0 | ((6 & 0xF) << 28) | ((0x00) << 20) | (flow_label0 & 0xffff));
+
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
{