feature: all input nodes must have same nexts
[vpp.git] / vnet / vnet / ip / ip4_input.c
index 5b2b42d..268f7af 100644 (file)
@@ -108,7 +108,7 @@ ip4_input_inline (vlib_main_t * vm,
        {
          vlib_buffer_t * p0, * p1;
          ip4_header_t * ip0, * ip1;
-         ip_config_main_t * cm0, * cm1;
+         vnet_feature_config_main_t * cm0, * cm1;
          u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
          u32 sw_if_index1, pi1, ip_len1, cur_len1, next1;
          i32 len_diff0, len_diff1;
@@ -144,11 +144,11 @@ ip4_input_inline (vlib_main_t * vm,
          sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
          sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];
 
-         cast0 = ip4_address_is_multicast (&ip0->dst_address) ? VNET_MULTICAST : VNET_UNICAST;
-         cast1 = ip4_address_is_multicast (&ip1->dst_address) ? VNET_MULTICAST : VNET_UNICAST;
+         cast0 = ip4_address_is_multicast (&ip0->dst_address) ? VNET_IP_RX_MULTICAST_FEAT : VNET_IP_RX_UNICAST_FEAT;
+         cast1 = ip4_address_is_multicast (&ip1->dst_address) ? VNET_IP_RX_MULTICAST_FEAT : VNET_IP_RX_UNICAST_FEAT;
 
-         cm0 = lm->rx_config_mains + cast0;
-         cm1 = lm->rx_config_mains + cast1;
+         cm0 = lm->feature_config_mains + cast0;
+         cm1 = lm->feature_config_mains + cast1;
 
          p0->current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
          p1->current_config_index = vec_elt (cm1->config_index_by_sw_if_index, sw_if_index1);
@@ -194,9 +194,9 @@ ip4_input_inline (vlib_main_t * vm,
          error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
          error1 = ip4_get_fragment_offset (ip1) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error1;
 
-         /* TTL <= 1? Drop it. */
-         error0 = (ip0->ttl <= 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
-         error1 = (ip1->ttl <= 1 && cast1 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error1;
+         /* TTL < 1? Drop it. */
+         error0 = (ip0->ttl < 1 && cast0 == VNET_IP_RX_UNICAST_FEAT) ? IP4_ERROR_TIME_EXPIRED : error0;
+         error1 = (ip1->ttl < 1 && cast1 == VNET_IP_RX_UNICAST_FEAT) ? IP4_ERROR_TIME_EXPIRED : error1;
 
          /* Verify lengths. */
          ip_len0 = clib_net_to_host_u16 (ip0->length);
@@ -245,7 +245,7 @@ ip4_input_inline (vlib_main_t * vm,
        {
          vlib_buffer_t * p0;
          ip4_header_t * ip0;
-         ip_config_main_t * cm0;
+         vnet_feature_config_main_t * cm0;
          u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
          i32 len_diff0;
          u8 error0, cast0;
@@ -262,8 +262,8 @@ ip4_input_inline (vlib_main_t * vm,
 
          sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
 
-         cast0 = ip4_address_is_multicast (&ip0->dst_address) ? VNET_MULTICAST : VNET_UNICAST;
-         cm0 = lm->rx_config_mains + cast0;
+         cast0 = ip4_address_is_multicast (&ip0->dst_address) ? VNET_IP_RX_MULTICAST_FEAT : VNET_IP_RX_UNICAST_FEAT;
+         cm0 = lm->feature_config_mains + cast0;
          p0->current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
          vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
          vnet_get_config_data (&cm0->config_main,
@@ -293,8 +293,8 @@ ip4_input_inline (vlib_main_t * vm,
          /* Drop fragmentation offset 1 packets. */
          error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
 
-         /* TTL <= 1? Drop it. */
-          error0 = (ip0->ttl <= 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
+         /* TTL < 1? Drop it. */
+          error0 = (ip0->ttl < 1 && cast0 == VNET_IP_RX_UNICAST_FEAT) ? IP4_ERROR_TIME_EXPIRED : error0;
 
          /* Verify lengths. */
          ip_len0 = clib_net_to_host_u16 (ip0->length);
@@ -328,6 +328,41 @@ ip4_input_inline (vlib_main_t * vm,
   return frame->n_vectors;
 }
 
+/** \brief IPv4 input node.
+    @node ip4-input
+
+    This is the IPv4 input node: validates ip4 header checksums,
+    verifies ip header lengths, discards pkts with expired TTLs,
+    and sends pkts to the set of ip feature nodes configured on
+    the rx interface.
+
+    @param vm vlib_main_t corresponding to the current thread
+    @param node vlib_node_runtime_t
+    @param frame vlib_frame_t whose contents should be dispatched
+
+    @par Graph mechanics: buffer metadata, next index usage
+
+    @em Uses:
+    - vnet_feature_config_main_t cm corresponding to each pkt's dst address unicast / 
+      multicast status.
+    - <code>b->current_config_index</code> corresponding to each pkt's
+      rx sw_if_index. 
+         - This sets the per-packet graph trajectory, ensuring that
+           each packet visits the per-interface features in order.
+
+    - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
+        - Indicates the @c sw_if_index value of the interface that the
+         packet was received on.
+
+    @em Sets:
+    - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
+        - The lookup result adjacency index.
+
+    <em>Next Indices:</em>
+    - Dispatches pkts to the (first) feature node:
+      <code> vnet_get_config_data (... &next0 ...); </code>
+      or @c error-drop 
+*/
 static uword
 ip4_input (vlib_main_t * vm,
           vlib_node_runtime_t * node,
@@ -418,6 +453,10 @@ static clib_error_t * ip4_init (vlib_main_t * vm)
   if ((error = vlib_call_init_function (vm, ip4_source_check_init)))
     return error;
 
+  if ((error = vlib_call_init_function 
+       (vm, ip4_source_and_port_range_check_init)))
+    return error;
+
   /* Set flow hash to something non-zero. */
   ip4_main.flow_hash_seed = 0xdeadbeef;