Use thread local storage for thread index
[vpp.git] / src / vnet / ip / ip6_forward.c
index 2388a30..c2fc4f8 100644 (file)
@@ -74,7 +74,7 @@ ip6_lookup_inline (vlib_main_t * vm,
   vlib_combined_counter_main_t *cm = &load_balance_main.lbm_to_counters;
   u32 n_left_from, n_left_to_next, *from, *to_next;
   ip_lookup_next_t next;
-  u32 cpu_index = os_get_cpu_number ();
+  u32 thread_index = vlib_get_thread_index ();
 
   from = vlib_frame_vector_args (frame);
   n_left_from = frame->n_vectors;
@@ -185,9 +185,9 @@ ip6_lookup_inline (vlib_main_t * vm,
          vnet_buffer (p1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
 
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
+           (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1));
+           (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1));
 
          from += 2;
          to_next += 2;
@@ -291,7 +291,7 @@ ip6_lookup_inline (vlib_main_t * vm,
          vnet_buffer (p0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
 
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
+           (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
 
          from += 1;
          to_next += 1;
@@ -703,7 +703,7 @@ ip6_load_balance (vlib_main_t * vm,
   vlib_combined_counter_main_t *cm = &load_balance_main.lbm_via_counters;
   u32 n_left_from, n_left_to_next, *from, *to_next;
   ip_lookup_next_t next;
-  u32 cpu_index = os_get_cpu_number ();
+  u32 thread_index = vlib_get_thread_index ();
   ip6_main_t *im = &ip6_main;
 
   from = vlib_frame_vector_args (frame);
@@ -766,8 +766,7 @@ ip6_load_balance (vlib_main_t * vm,
           * We don't want to use the same hash value at each level in the recursion
           * graph as that would lead to polarisation
           */
-         hc0 = vnet_buffer (p0)->ip.flow_hash = 0;
-         hc1 = vnet_buffer (p1)->ip.flow_hash = 0;
+         hc0 = hc1 = 0;
 
          if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
            {
@@ -779,7 +778,7 @@ ip6_load_balance (vlib_main_t * vm,
              else
                {
                  hc0 = vnet_buffer (p0)->ip.flow_hash =
-                   ip6_compute_flow_hash (ip0, hc0);
+                   ip6_compute_flow_hash (ip0, lb0->lb_hash_config);
                }
            }
          if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
@@ -792,7 +791,7 @@ ip6_load_balance (vlib_main_t * vm,
              else
                {
                  hc1 = vnet_buffer (p1)->ip.flow_hash =
-                   ip6_compute_flow_hash (ip1, hc1);
+                   ip6_compute_flow_hash (ip1, lb1->lb_hash_config);
                }
            }
 
@@ -825,9 +824,9 @@ ip6_load_balance (vlib_main_t * vm,
          vnet_buffer (p1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
 
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
+           (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1));
+           (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1));
 
          vlib_validate_buffer_enqueue_x2 (vm, node, next,
                                           to_next, n_left_to_next,
@@ -857,7 +856,7 @@ ip6_load_balance (vlib_main_t * vm,
 
          lb0 = load_balance_get (lbi0);
 
-         hc0 = vnet_buffer (p0)->ip.flow_hash = 0;
+         hc0 = 0;
          if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
            {
              if (PREDICT_TRUE (vnet_buffer (p0)->ip.flow_hash))
@@ -868,7 +867,7 @@ ip6_load_balance (vlib_main_t * vm,
              else
                {
                  hc0 = vnet_buffer (p0)->ip.flow_hash =
-                   ip6_compute_flow_hash (ip0, hc0);
+                   ip6_compute_flow_hash (ip0, lb0->lb_hash_config);
                }
            }
          dpo0 =
@@ -887,7 +886,7 @@ ip6_load_balance (vlib_main_t * vm,
            }
 
          vlib_increment_combined_counter
-           (cm, cpu_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
+           (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0));
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next,
                                           to_next, n_left_to_next,
@@ -962,7 +961,6 @@ format_ip6_rewrite_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   ip6_forward_next_trace_t *t = va_arg (*args, ip6_forward_next_trace_t *);
-  vnet_main_t *vnm = vnet_get_main ();
   uword indent = format_get_indent (s);
 
   s = format (s, "tx_sw_if_index %d adj-idx %d : %U flow hash: 0x%08x",
@@ -971,7 +969,7 @@ format_ip6_rewrite_trace (u8 * s, va_list * args)
   s = format (s, "\n%U%U",
              format_white_space, indent,
              format_ip_adjacency_packet_data,
-             vnm, t->adj_index, t->packet_data, sizeof (t->packet_data));
+             t->adj_index, t->packet_data, sizeof (t->packet_data));
   return s;
 }
 
@@ -1162,7 +1160,8 @@ ip6_tcp_udp_icmp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
                                                uword));
     }
 
-  /* some icmp packets may come with a "router alert" hop-by-hop extension header (e.g., mldv2 packets) */
+  /* some icmp packets may come with a "router alert" hop-by-hop extension header (e.g., mldv2 packets)
+   * or UDP-Ping packets */
   if (PREDICT_FALSE (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
     {
       u32 skip_bytes;
@@ -1170,7 +1169,8 @@ ip6_tcp_udp_icmp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
        (ip6_hop_by_hop_ext_t *) data_this_buffer;
 
       /* validate really icmp6 next */
-      ASSERT (ext_hdr->next_hdr == IP_PROTOCOL_ICMP6);
+      ASSERT ((ext_hdr->next_hdr == IP_PROTOCOL_ICMP6)
+             || (ext_hdr->next_hdr == IP_PROTOCOL_UDP));
 
       skip_bytes = 8 * (1 + ext_hdr->n_data_u64s);
       data_this_buffer = (void *) ((u8 *) data_this_buffer + skip_bytes);
@@ -1318,23 +1318,6 @@ ip6_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
          len_diff0 = 0;
          len_diff1 = 0;
 
-         /* Skip HBH local processing */
-         if (PREDICT_FALSE
-             (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
-           {
-             ip6_hop_by_hop_ext_t *ext_hdr =
-               (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
-             next0 = lm->local_next_by_ip_protocol[ext_hdr->next_hdr];
-             type0 = lm->builtin_protocol_by_ip_protocol[ext_hdr->next_hdr];
-           }
-         if (PREDICT_FALSE
-             (ip1->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
-           {
-             ip6_hop_by_hop_ext_t *ext_hdr =
-               (ip6_hop_by_hop_ext_t *) ip6_next_header (ip1);
-             next1 = lm->local_next_by_ip_protocol[ext_hdr->next_hdr];
-             type1 = lm->builtin_protocol_by_ip_protocol[ext_hdr->next_hdr];
-           }
          if (PREDICT_TRUE (IP_PROTOCOL_UDP == ip6_locate_header (p0, ip0,
                                                                  IP_PROTOCOL_UDP,
                                                                  &udp_offset0)))
@@ -1459,15 +1442,6 @@ ip6_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
          good_l4_checksum0 = (flags0 & IP_BUFFER_L4_CHECKSUM_CORRECT) != 0;
          len_diff0 = 0;
 
-         /* Skip HBH local processing */
-         if (PREDICT_FALSE
-             (ip0->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS))
-           {
-             ip6_hop_by_hop_ext_t *ext_hdr =
-               (ip6_hop_by_hop_ext_t *) ip6_next_header (ip0);
-             next0 = lm->local_next_by_ip_protocol[ext_hdr->next_hdr];
-             type0 = lm->builtin_protocol_by_ip_protocol[ext_hdr->next_hdr];
-           }
          if (PREDICT_TRUE (IP_PROTOCOL_UDP == ip6_locate_header (p0, ip0,
                                                                  IP_PROTOCOL_UDP,
                                                                  &udp_offset0)))
@@ -1912,7 +1886,8 @@ typedef enum
 always_inline uword
 ip6_rewrite_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
-                   vlib_frame_t * frame, int is_midchain, int is_mcast)
+                   vlib_frame_t * frame,
+                   int do_counters, int is_midchain, int is_mcast)
 {
   ip_lookup_main_t *lm = &ip6_main.lookup_main;
   u32 *from = vlib_frame_vector_args (frame);
@@ -1922,7 +1897,7 @@ ip6_rewrite_inline (vlib_main_t * vm,
 
   n_left_from = frame->n_vectors;
   next_index = node->cached_next_index;
-  u32 cpu_index = os_get_cpu_number ();
+  u32 thread_index = vlib_get_thread_index ();
 
   while (n_left_from > 0)
     {
@@ -1968,9 +1943,6 @@ ip6_rewrite_inline (vlib_main_t * vm,
          adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
          adj_index1 = vnet_buffer (p1)->ip.adj_index[VLIB_TX];
 
-         /* We should never rewrite a pkt using the MISS adjacency */
-         ASSERT (adj_index0 && adj_index1);
-
          ip0 = vlib_buffer_get_current (p0);
          ip1 = vlib_buffer_get_current (p1);
 
@@ -2043,14 +2015,17 @@ ip6_rewrite_inline (vlib_main_t * vm,
          vnet_buffer (p0)->ip.save_rewrite_length = rw_len0;
          vnet_buffer (p1)->ip.save_rewrite_length = rw_len1;
 
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0);
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index, adj_index1,
-            1, vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+         if (do_counters)
+           {
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                thread_index, adj_index0, 1,
+                vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                thread_index, adj_index1, 1,
+                vlib_buffer_length_in_chain (vm, p1) + rw_len1);
+           }
 
          /* Check MTU of outgoing interface. */
          error0 =
@@ -2075,8 +2050,10 @@ ip6_rewrite_inline (vlib_main_t * vm,
              vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
              next0 = adj0[0].rewrite_header.next_index;
 
-             vnet_feature_arc_start (lm->output_feature_arc_index,
-                                     tx_sw_if_index0, &next0, p0);
+             if (PREDICT_FALSE
+                 (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
+               vnet_feature_arc_start (lm->output_feature_arc_index,
+                                       tx_sw_if_index0, &next0, p0);
            }
          if (PREDICT_TRUE (error1 == IP6_ERROR_NONE))
            {
@@ -2087,8 +2064,10 @@ ip6_rewrite_inline (vlib_main_t * vm,
              vnet_buffer (p1)->sw_if_index[VLIB_TX] = tx_sw_if_index1;
              next1 = adj1[0].rewrite_header.next_index;
 
-             vnet_feature_arc_start (lm->output_feature_arc_index,
-                                     tx_sw_if_index1, &next1, p1);
+             if (PREDICT_FALSE
+                 (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
+               vnet_feature_arc_start (lm->output_feature_arc_index,
+                                       tx_sw_if_index1, &next1, p1);
            }
 
          /* Guess we are only writing on simple Ethernet header. */
@@ -2105,8 +2084,8 @@ ip6_rewrite_inline (vlib_main_t * vm,
              /*
               * copy bytes from the IP address into the MAC rewrite
               */
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0, 0);
-             vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1, 0);
+             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
+             vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1);
            }
 
          vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
@@ -2129,9 +2108,6 @@ ip6_rewrite_inline (vlib_main_t * vm,
 
          adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
 
-         /* We should never rewrite a pkt using the MISS adjacency */
-         ASSERT (adj_index0);
-
          adj0 = ip_get_adjacency (lm, adj_index0);
 
          ip0 = vlib_buffer_get_current (p0);
@@ -2176,10 +2152,13 @@ ip6_rewrite_inline (vlib_main_t * vm,
          rw_len0 = adj0[0].rewrite_header.data_bytes;
          vnet_buffer (p0)->ip.save_rewrite_length = rw_len0;
 
-         vlib_increment_combined_counter
-           (&adjacency_counters,
-            cpu_index,
-            adj_index0, 1, vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+         if (do_counters)
+           {
+             vlib_increment_combined_counter
+               (&adjacency_counters,
+                thread_index, adj_index0, 1,
+                vlib_buffer_length_in_chain (vm, p0) + rw_len0);
+           }
 
          /* Check MTU of outgoing interface. */
          error0 =
@@ -2200,8 +2179,10 @@ ip6_rewrite_inline (vlib_main_t * vm,
              vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
              next0 = adj0[0].rewrite_header.next_index;
 
-             vnet_feature_arc_start (lm->output_feature_arc_index,
-                                     tx_sw_if_index0, &next0, p0);
+             if (PREDICT_FALSE
+                 (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
+               vnet_feature_arc_start (lm->output_feature_arc_index,
+                                       tx_sw_if_index0, &next0, p0);
            }
 
          if (is_midchain)
@@ -2210,7 +2191,7 @@ ip6_rewrite_inline (vlib_main_t * vm,
            }
          if (is_mcast)
            {
-             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0, 0);
+             vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
            }
 
          p0->error = error_node->errors[error0];
@@ -2239,21 +2220,30 @@ static uword
 ip6_rewrite (vlib_main_t * vm,
             vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 0, 0);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 0, 0);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 0, 0);
 }
 
 static uword
 ip6_rewrite_mcast (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 0, 1);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 0, 1);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 0, 1);
 }
 
 static uword
 ip6_midchain (vlib_main_t * vm,
              vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip6_rewrite_inline (vm, node, frame, 1, 0);
+  if (adj_are_counters_enabled ())
+    return ip6_rewrite_inline (vm, node, frame, 1, 1, 0);
+  else
+    return ip6_rewrite_inline (vm, node, frame, 0, 1, 0);
 }
 
 /* *INDENT-OFF* */