docs: vnet comment nitfixes
[vpp.git] / src / vnet / srv6 / sr_policy_rewrite.c
index 3e8a4e4..500772e 100644 (file)
@@ -33,7 +33,7 @@
  * Traffic input usually is IPv6 packets. However it is possible to have
  * IPv4 packets or L2 frames. (that are encapsulated into IPv6 with SRH)
  *
- * This file provides the appropiates VPP graph nodes to do any of these
+ * This file provides the appropriate VPP graph nodes to do any of these
  * methods.
  *
  */
@@ -195,7 +195,7 @@ VLIB_CLI_COMMAND (set_sr_hop_limit_command, static) = {
  * @return precomputed rewrite string for encapsulation
  */
 static inline u8 *
-compute_rewrite_encaps (ip6_address_t * sl)
+compute_rewrite_encaps (ip6_address_t *sl, u8 type)
 {
   ip6_header_t *iph;
   ip6_sr_header_t *srh;
@@ -255,7 +255,7 @@ compute_rewrite_encaps (ip6_address_t * sl)
  * @return precomputed rewrite string for SRH insertion
  */
 static inline u8 *
-compute_rewrite_insert (ip6_address_t * sl)
+compute_rewrite_insert (ip6_address_t *sl, u8 type)
 {
   ip6_sr_header_t *srh;
   ip6_address_t *addrp, *this_address;
@@ -358,15 +358,19 @@ create_sl (ip6_sr_policy_t * sr_policy, ip6_address_t * sl, u32 weight,
     (weight != (u32) ~ 0 ? weight : SR_SEGMENT_LIST_WEIGHT_DEFAULT);
 
   segment_list->segments = vec_dup (sl);
+  segment_list->policy_type = sr_policy->type;
+
+  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);
+      segment_list->rewrite = compute_rewrite_encaps (sl, sr_policy->type);
       segment_list->rewrite_bsid = segment_list->rewrite;
     }
   else
     {
-      segment_list->rewrite = compute_rewrite_insert (sl);
+      segment_list->rewrite = compute_rewrite_insert (sl, sr_policy->type);
       segment_list->rewrite_bsid = compute_rewrite_bsid (sl);
     }
 
@@ -430,7 +434,7 @@ create_sl (ip6_sr_policy_t * sr_policy, ip6_address_t * sl, u32 weight,
 }
 
 /**
- * @brief Updates the Load Balancer after an SR Policy change
+ * @brief Updates the Load-Balancer after an SR Policy change
  *
  * @param sr_policy is the modified SR Policy
  */
@@ -629,9 +633,9 @@ update_replicate (ip6_sr_policy_t * sr_policy)
  * @return 0 if correct, else error
  */
 int
-sr_policy_add (ip6_address_t * bsid, ip6_address_t * segments,
-              u32 weight, u8 behavior, u32 fib_table, u8 is_encap,
-              u16 plugin, void *ls_plugin_mem)
+sr_policy_add (ip6_address_t *bsid, ip6_address_t *segments, u32 weight,
+              u8 type, u32 fib_table, u8 is_encap, u16 plugin,
+              void *ls_plugin_mem)
 {
   ip6_sr_main_t *sm = &sr_main;
   ip6_sr_policy_t *sr_policy = 0;
@@ -672,7 +676,7 @@ sr_policy_add (ip6_address_t * bsid, ip6_address_t * segments,
   pool_get (sm->sr_policies, sr_policy);
   clib_memset (sr_policy, 0, sizeof (*sr_policy));
   clib_memcpy_fast (&sr_policy->bsid, bsid, sizeof (ip6_address_t));
-  sr_policy->type = behavior;
+  sr_policy->type = type;
   sr_policy->fib_table = (fib_table != (u32) ~ 0 ? fib_table : 0);     //Is default FIB 0 ?
   sr_policy->is_encap = is_encap;
 
@@ -933,7 +937,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
   ip6_address_t *segments = 0, *this_seg;
   u8 operation = 0;
   char is_encap = 1;
-  char is_spray = 0;
+  u8 type = SR_POLICY_TYPE_DEFAULT;
   u16 behavior = 0;
   void *ls_plugin_mem = 0;
 
@@ -972,7 +976,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
       else if (unformat (input, "insert"))
        is_encap = 0;
       else if (unformat (input, "spray"))
-       is_spray = 1;
+       type = SR_POLICY_TYPE_SPRAY;
       else if (!behavior && unformat (input, "behavior"))
        {
          sr_policy_fn_registration_t *plugin = 0, **vec_plugins = 0;
@@ -1021,9 +1025,7 @@ sr_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
       if (vec_len (segments) == 0)
        return clib_error_return (0, "No Segment List specified");
 
-      rv = sr_policy_add (&bsid, segments, weight,
-                         (is_spray ? SR_POLICY_TYPE_SPRAY :
-                          SR_POLICY_TYPE_DEFAULT), fib_table, is_encap,
+      rv = sr_policy_add (&bsid, segments, weight, type, fib_table, is_encap,
                          behavior, ls_plugin_mem);
 
       vec_free (segments);
@@ -1134,9 +1136,15 @@ show_sr_policies_command_fn (vlib_main_t * vm, unformat_input_t * input,
     vlib_cli_output (vm, "\tBehavior: %s",
                     (sr_policy->is_encap ? "Encapsulation" :
                      "SRH insertion"));
-    vlib_cli_output (vm, "\tType: %s",
-                    (sr_policy->type ==
-                     SR_POLICY_TYPE_DEFAULT ? "Default" : "Spray"));
+    switch (sr_policy->type)
+      {
+      case SR_POLICY_TYPE_SPRAY:
+       vlib_cli_output (vm, "\tType: %s", "Spray");
+       break;
+      default:
+       vlib_cli_output (vm, "\tType: %s", "Default");
+       break;
+      }
     vlib_cli_output (vm, "\tFIB table: %u",
                     (sr_policy->fib_table !=
                      (u32) ~ 0 ? sr_policy->fib_table : 0));
@@ -1233,19 +1241,26 @@ format_sr_policy_rewrite_trace (u8 * s, va_list * args)
  * @brief IPv6 encapsulation processing as per RFC2473
  */
 static_always_inline void
-encaps_processing_v6 (vlib_node_runtime_t * node,
-                     vlib_buffer_t * b0,
-                     ip6_header_t * ip0, ip6_header_t * ip0_encap)
+encaps_processing_v6 (vlib_node_runtime_t *node, vlib_buffer_t *b0,
+                     ip6_header_t *ip0, ip6_header_t *ip0_encap,
+                     u8 policy_type)
 {
   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));
 }
 
 /**
@@ -1297,10 +1312,10 @@ sr_policy_rewrite_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -1363,10 +1378,15 @@ sr_policy_rewrite_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
          ip2 = vlib_buffer_get_current (b2);
          ip3 = vlib_buffer_get_current (b3);
 
-         encaps_processing_v6 (node, b0, ip0, ip0_encap);
-         encaps_processing_v6 (node, b1, ip1, ip1_encap);
-         encaps_processing_v6 (node, b2, ip2, ip2_encap);
-         encaps_processing_v6 (node, b3, ip3, ip3_encap);
+         encaps_processing_v6 (node, b0, ip0, ip0_encap, sl0->policy_type);
+         encaps_processing_v6 (node, b1, ip1, ip1_encap, sl1->policy_type);
+         encaps_processing_v6 (node, b2, ip2, ip2_encap, sl2->policy_type);
+         encaps_processing_v6 (node, b3, ip3, ip3_encap, sl3->policy_type);
+
+         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)))
            {
@@ -1448,7 +1468,9 @@ sr_policy_rewrite_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
 
          ip0 = vlib_buffer_get_current (b0);
 
-         encaps_processing_v6 (node, b0, ip0, ip0_encap);
+         encaps_processing_v6 (node, b0, ip0, ip0_encap, sl0->policy_type);
+
+         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 +1532,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 +1543,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);
@@ -1581,10 +1605,10 @@ sr_policy_rewrite_encaps_v4 (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -1651,6 +1675,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 +1763,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 +1892,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. */
          {
@@ -1877,10 +1909,10 @@ sr_policy_rewrite_encaps_l2 (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -1916,12 +1948,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 +1967,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 +1977,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 +1987,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 +2080,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 +2151,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 +2166,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 +2204,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))
            {
@@ -2256,10 +2305,10 @@ sr_policy_rewrite_insert (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -2678,10 +2727,10 @@ sr_policy_rewrite_b_insert (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -3043,10 +3092,9 @@ VLIB_REGISTER_NODE (sr_policy_rewrite_b_insert_node) = {
  * @brief Function BSID encapsulation
  */
 static_always_inline void
-end_bsid_encaps_srh_processing (vlib_node_runtime_t * node,
-                               vlib_buffer_t * b0,
-                               ip6_header_t * ip0,
-                               ip6_sr_header_t * sr0, u32 * next0)
+end_bsid_encaps_srh_processing (vlib_node_runtime_t *node, vlib_buffer_t *b0,
+                               ip6_header_t *ip0, ip6_sr_header_t *sr0,
+                               u32 *next0, u8 policy_type)
 {
   ip6_address_t *new_dst0;
 
@@ -3121,10 +3169,10 @@ sr_policy_rewrite_b_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
            vlib_prefetch_buffer_header (p6, LOAD);
            vlib_prefetch_buffer_header (p7, LOAD);
 
-           CLIB_PREFETCH (p4->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p5->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p6->data, CLIB_CACHE_LINE_BYTES, STORE);
-           CLIB_PREFETCH (p7->data, CLIB_CACHE_LINE_BYTES, STORE);
+           clib_prefetch_store (p4->data);
+           clib_prefetch_store (p5->data);
+           clib_prefetch_store (p6->data);
+           clib_prefetch_store (p7->data);
          }
 
          to_next[0] = bi0 = from[0];
@@ -3180,10 +3228,14 @@ sr_policy_rewrite_b_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
            ip6_ext_header_find (vm, b3, ip3_encap, IP_PROTOCOL_IPV6_ROUTE,
                                 NULL);
 
-         end_bsid_encaps_srh_processing (node, b0, ip0_encap, sr0, &next0);
-         end_bsid_encaps_srh_processing (node, b1, ip1_encap, sr1, &next1);
-         end_bsid_encaps_srh_processing (node, b2, ip2_encap, sr2, &next2);
-         end_bsid_encaps_srh_processing (node, b3, ip3_encap, sr3, &next3);
+         end_bsid_encaps_srh_processing (node, b0, ip0_encap, sr0, &next0,
+                                         sl0->policy_type);
+         end_bsid_encaps_srh_processing (node, b1, ip1_encap, sr1, &next1,
+                                         sl1->policy_type);
+         end_bsid_encaps_srh_processing (node, b2, ip2_encap, sr2, &next2,
+                                         sl2->policy_type);
+         end_bsid_encaps_srh_processing (node, b3, ip3_encap, sr3, &next3,
+                                         sl3->policy_type);
 
          clib_memcpy_fast (((u8 *) ip0_encap) - vec_len (sl0->rewrite),
                            sl0->rewrite, vec_len (sl0->rewrite));
@@ -3204,10 +3256,10 @@ sr_policy_rewrite_b_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
          ip2 = vlib_buffer_get_current (b2);
          ip3 = vlib_buffer_get_current (b3);
 
-         encaps_processing_v6 (node, b0, ip0, ip0_encap);
-         encaps_processing_v6 (node, b1, ip1, ip1_encap);
-         encaps_processing_v6 (node, b2, ip2, ip2_encap);
-         encaps_processing_v6 (node, b3, ip3, ip3_encap);
+         encaps_processing_v6 (node, b0, ip0, ip0_encap, sl0->policy_type);
+         encaps_processing_v6 (node, b1, ip1, ip1_encap, sl1->policy_type);
+         encaps_processing_v6 (node, b2, ip2, ip2_encap, sl2->policy_type);
+         encaps_processing_v6 (node, b3, ip3, ip3_encap, sl3->policy_type);
 
          if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
            {
@@ -3286,7 +3338,8 @@ sr_policy_rewrite_b_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
          sr0 =
            ip6_ext_header_find (vm, b0, ip0_encap, IP_PROTOCOL_IPV6_ROUTE,
                                 NULL);
-         end_bsid_encaps_srh_processing (node, b0, ip0_encap, sr0, &next0);
+         end_bsid_encaps_srh_processing (node, b0, ip0_encap, sr0, &next0,
+                                         sl0->policy_type);
 
          clib_memcpy_fast (((u8 *) ip0_encap) - vec_len (sl0->rewrite),
                            sl0->rewrite, vec_len (sl0->rewrite));
@@ -3294,7 +3347,7 @@ sr_policy_rewrite_b_encaps (vlib_main_t * vm, vlib_node_runtime_t * node,
 
          ip0 = vlib_buffer_get_current (b0);
 
-         encaps_processing_v6 (node, b0, ip0, ip0_encap);
+         encaps_processing_v6 (node, b0, ip0, ip0_encap, sl0->policy_type);
 
          if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
              PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))