hsa: fix quic vcl test
[vpp.git] / src / vnet / srv6 / sr_policy_rewrite.c
index 3e8a4e4..98fae3b 100644 (file)
@@ -359,6 +359,9 @@ create_sl (ip6_sr_policy_t * sr_policy, ip6_address_t * sl, u32 weight,
 
   segment_list->segments = vec_dup (sl);
 
+  segment_list->egress_fib_table =
+    ip6_fib_index_from_table_id (sr_policy->fib_table);
+
   if (is_encap)
     {
       segment_list->rewrite = compute_rewrite_encaps (sl);
@@ -1238,14 +1241,21 @@ encaps_processing_v6 (vlib_node_runtime_t * node,
                      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));
 }
 
 /**
@@ -1368,6 +1378,11 @@ sr_policy_rewrite_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
          encaps_processing_v6 (node, b2, ip2, ip2_encap);
          encaps_processing_v6 (node, b3, ip3, ip3_encap);
 
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sl0->egress_fib_table;
+         vnet_buffer (b1)->sw_if_index[VLIB_TX] = sl1->egress_fib_table;
+         vnet_buffer (b2)->sw_if_index[VLIB_TX] = sl2->egress_fib_table;
+         vnet_buffer (b3)->sw_if_index[VLIB_TX] = sl3->egress_fib_table;
+
          if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
            {
              if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
@@ -1450,6 +1465,8 @@ sr_policy_rewrite_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
 
          encaps_processing_v6 (node, b0, ip0, ip0_encap);
 
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sl0->egress_fib_table;
+
          if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
              PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
            {
@@ -1510,6 +1527,7 @@ encaps_processing_v4 (vlib_node_runtime_t * node,
   ip6_sr_header_t *sr0;
 
   u32 checksum0;
+  u32 flow_label;
 
   /* Inner IPv4: Decrement TTL & update checksum */
   ip0_encap->ttl -= 1;
@@ -1520,9 +1538,10 @@ encaps_processing_v4 (vlib_node_runtime_t * node,
   /* 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);
@@ -1651,6 +1670,11 @@ sr_policy_rewrite_encaps_v4 (vlib_main_t * vm, vlib_node_runtime_t * node,
          encaps_processing_v4 (node, b2, ip2, ip2_encap);
          encaps_processing_v4 (node, b3, ip3, ip3_encap);
 
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sl0->egress_fib_table;
+         vnet_buffer (b1)->sw_if_index[VLIB_TX] = sl1->egress_fib_table;
+         vnet_buffer (b2)->sw_if_index[VLIB_TX] = sl2->egress_fib_table;
+         vnet_buffer (b3)->sw_if_index[VLIB_TX] = sl3->egress_fib_table;
+
          if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
            {
              if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
@@ -1734,6 +1758,8 @@ sr_policy_rewrite_encaps_v4 (vlib_main_t * vm, vlib_node_runtime_t * node,
 
          encaps_processing_v4 (node, b0, ip0, ip0_encap);
 
+         vnet_buffer (b0)->sw_if_index[VLIB_TX] = sl0->egress_fib_table;
+
          if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
              PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
            {
@@ -1861,6 +1887,7 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
          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 +1943,16 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
                                   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 +1962,7 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
            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 +1972,7 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
            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 +1982,7 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
            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 +2075,16 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
          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 +2146,7 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
          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 +2161,14 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
                                   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 +2199,9 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
          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))
            {