Fix IP feature ordering.
[vpp.git] / src / vnet / ip / ip4_forward.c
index fe4d676..0dad61d 100644 (file)
@@ -586,8 +586,7 @@ ip4_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))
            {
@@ -599,7 +598,7 @@ ip4_load_balance (vlib_main_t * vm,
              else
                {
                  hc0 = vnet_buffer (p0)->ip.flow_hash =
-                   ip4_compute_flow_hash (ip0, hc0);
+                   ip4_compute_flow_hash (ip0, lb0->lb_hash_config);
                }
            }
          if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
@@ -612,7 +611,7 @@ ip4_load_balance (vlib_main_t * vm,
              else
                {
                  hc1 = vnet_buffer (p1)->ip.flow_hash =
-                   ip4_compute_flow_hash (ip1, hc1);
+                   ip4_compute_flow_hash (ip1, lb1->lb_hash_config);
                }
            }
 
@@ -662,7 +661,7 @@ ip4_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))
@@ -673,7 +672,7 @@ ip4_load_balance (vlib_main_t * vm,
              else
                {
                  hc0 = vnet_buffer (p0)->ip.flow_hash =
-                   ip4_compute_flow_hash (ip0, hc0);
+                   ip4_compute_flow_hash (ip0, lb0->lb_hash_config);
                }
            }
 
@@ -848,9 +847,8 @@ ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
                               !is_enable, 0, 0);
 
 
-  vnet_feature_enable_disable ("ip4-multicast",
-                              "ip4-mfib-forward-lookup",
-                              sw_if_index, is_enable, 0, 0);
+  vnet_feature_enable_disable ("ip4-multicast", "ip4-drop",
+                              sw_if_index, !is_enable, 0, 0);
 }
 
 static clib_error_t *
@@ -955,7 +953,6 @@ VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
 {
   .arc_name = "ip4-unicast",
   .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
-  .end_node = "ip4-lookup",
   .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
 };
 
@@ -1022,27 +1019,25 @@ VNET_FEATURE_INIT (ip4_vxlan_bypass, static) =
   .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_lookup, static) =
+VNET_FEATURE_INIT (ip4_drop, static) =
 {
   .arc_name = "ip4-unicast",
-  .node_name = "ip4-lookup",
-  .runs_before = VNET_FEATURES ("ip4-drop"),
+  .node_name = "ip4-drop",
+  .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_drop, static) =
+VNET_FEATURE_INIT (ip4_lookup, static) =
 {
   .arc_name = "ip4-unicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-lookup",
   .runs_before = 0,    /* not before any other features */
 };
 
-
 /* Built-in ip4 multicast rx feature path definition */
 VNET_FEATURE_ARC_INIT (ip4_multicast, static) =
 {
   .arc_name = "ip4-multicast",
   .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
-  .end_node = "ip4-lookup-multicast",
   .arc_index_ptr = &ip4_main.lookup_main.mcast_feature_arc_index,
 };
 
@@ -1053,17 +1048,17 @@ VNET_FEATURE_INIT (ip4_vpath_mc, static) =
   .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_lookup_mc, static) =
+VNET_FEATURE_INIT (ip4_mc_drop, static) =
 {
   .arc_name = "ip4-multicast",
-  .node_name = "ip4-mfib-forward-lookup",
-  .runs_before = VNET_FEATURES ("ip4-drop"),
+  .node_name = "ip4-drop",
+  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_mc_drop, static) =
+VNET_FEATURE_INIT (ip4_lookup_mc, static) =
 {
   .arc_name = "ip4-multicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-mfib-forward-lookup",
   .runs_before = 0,    /* last feature */
 };
 
@@ -1072,7 +1067,6 @@ VNET_FEATURE_ARC_INIT (ip4_output, static) =
 {
   .arc_name = "ip4-output",
   .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain"),
-  .end_node = "interface-output",
   .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index,
 };
 
@@ -1233,7 +1227,6 @@ format_ip4_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 *);
   ip4_forward_next_trace_t *t = va_arg (*args, ip4_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 dpo-idx %d : %U flow hash: 0x%08x",
@@ -1242,7 +1235,7 @@ format_ip4_rewrite_trace (u8 * s, va_list * args)
   s = format (s, "\n%U%U",
              format_white_space, indent,
              format_ip_adjacency_packet_data,
-             vnm, t->dpo_index, t->packet_data, sizeof (t->packet_data));
+             t->dpo_index, t->packet_data, sizeof (t->packet_data));
   return s;
 }
 
@@ -1707,10 +1700,11 @@ ip4_local_inline (vlib_main_t * vm,
                     ip1->dst_address.as_u32 != 0xFFFFFFFF)
                    ? IP4_ERROR_SRC_LOOKUP_MISS : error1);
 
+       skip_checks:
+
          next0 = lm->local_next_by_ip_protocol[proto0];
          next1 = lm->local_next_by_ip_protocol[proto1];
 
-       skip_checks:
          next0 =
            error0 != IP4_ERROR_UNKNOWN_PROTOCOL ? IP_LOCAL_NEXT_DROP : next0;
          next1 =
@@ -2327,7 +2321,8 @@ typedef enum
 always_inline uword
 ip4_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 = &ip4_main.lookup_main;
   u32 *from = vlib_frame_vector_args (frame);
@@ -2488,10 +2483,13 @@ ip4_rewrite_inline (vlib_main_t * vm,
          /*
           * pre-fetch the per-adjacency counters
           */
-         vlib_prefetch_combined_counter (&adjacency_counters,
-                                         cpu_index, adj_index0);
-         vlib_prefetch_combined_counter (&adjacency_counters,
-                                         cpu_index, adj_index1);
+         if (do_counters)
+           {
+             vlib_prefetch_combined_counter (&adjacency_counters,
+                                             cpu_index, adj_index0);
+             vlib_prefetch_combined_counter (&adjacency_counters,
+                                             cpu_index, adj_index1);
+           }
 
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
           * to see the IP headerr */
@@ -2503,8 +2501,10 @@ ip4_rewrite_inline (vlib_main_t * vm,
              tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
              vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
 
-             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 == IP4_ERROR_NONE))
            {
@@ -2515,8 +2515,10 @@ ip4_rewrite_inline (vlib_main_t * vm,
              tx_sw_if_index1 = adj1[0].rewrite_header.sw_if_index;
              vnet_buffer (p1)->sw_if_index[VLIB_TX] = tx_sw_if_index1;
 
-             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. */
@@ -2526,15 +2528,20 @@ ip4_rewrite_inline (vlib_main_t * vm,
          /*
           * Bump the per-adjacency counters
           */
-         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,
+                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 (is_midchain)
            {
@@ -2662,8 +2669,10 @@ ip4_rewrite_inline (vlib_main_t * vm,
                  adj0->sub_type.midchain.fixup_func (vm, adj0, p0);
                }
 
-             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);
 
            }
 
@@ -2723,21 +2732,30 @@ static uword
 ip4_rewrite (vlib_main_t * vm,
             vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 0, 0);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
 }
 
 static uword
 ip4_midchain (vlib_main_t * vm,
              vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 1, 0);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 1, 0);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 1, 0);
 }
 
 static uword
 ip4_rewrite_mcast (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * frame)
 {
-  return ip4_rewrite_inline (vm, node, frame, 0, 1);
+  if (adj_are_counters_enabled ())
+    return ip4_rewrite_inline (vm, node, frame, 1, 0, 1);
+  else
+    return ip4_rewrite_inline (vm, node, frame, 0, 0, 1);
 }
 
 /* *INDENT-OFF* */