{
/* Next hop is not known, so create indirect adj */
ip_adjacency_t add_adj;
+ memset (&add_adj, 0, sizeof(add_adj));
+ add_adj.n_adj = 1;
add_adj.lookup_next_index = IP_LOOKUP_NEXT_INDIRECT;
add_adj.indirect.next_hop.ip4.as_u32 = next_hop->as_u32;
add_adj.explicit_fib_index = explicit_fib_index;
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (ip4_sw_interface_admin_up_down);
+/* Built-in ip4 unicast rx feature path definition */
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_inacl, static) = {
+ .node_name = "ip4-inacl",
+ .runs_before = {"ip4-source-check-via-rx", 0},
+ .feature_index = &ip4_main.ip4_unicast_rx_feature_check_access,
+};
+
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_source_check_1, static) = {
+ .node_name = "ip4-source-check-via-rx",
+ .runs_before = {"ip4-source-check-via-any", 0},
+ .feature_index =
+ &ip4_main.ip4_unicast_rx_feature_source_reachable_via_rx,
+};
+
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_source_check_2, static) = {
+ .node_name = "ip4-source-check-via-any",
+ .runs_before = {"ipsec-input-ip4", 0},
+ .feature_index =
+ &ip4_main.ip4_unicast_rx_feature_source_reachable_via_any,
+};
+
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_ipsec, static) = {
+ .node_name = "ipsec-input-ip4",
+ .runs_before = {"vpath-input-ip4", 0},
+ .feature_index = &ip4_main.ip4_unicast_rx_feature_ipsec,
+};
+
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_vpath, static) = {
+ .node_name = "vpath-input-ip4",
+ .runs_before = {"ip4-lookup", 0},
+ .feature_index = &ip4_main.ip4_unicast_rx_feature_vpath,
+};
+
+VNET_IP4_UNICAST_FEATURE_INIT (ip4_lookup, static) = {
+ .node_name = "ip4-lookup",
+ .runs_before = {0}, /* not before any other features */
+ .feature_index = &ip4_main.ip4_unicast_rx_feature_lookup,
+};
+
+/* Built-in ip4 multicast rx feature path definition */
+VNET_IP4_MULTICAST_FEATURE_INIT (ip4_vpath_mc, static) = {
+ .node_name = "vpath-input-ip4",
+ .runs_before = {"ip4-lookup-multicast", 0},
+ .feature_index = &ip4_main.ip4_multicast_rx_feature_vpath,
+};
+
+VNET_IP4_MULTICAST_FEATURE_INIT (ip4_lookup_mc, static) = {
+ .node_name = "ip4-lookup-multicast",
+ .runs_before = {0}, /* not before any other features */
+ .feature_index = &ip4_main.ip4_multicast_rx_feature_lookup,
+};
+
+static char * feature_start_nodes[] =
+ { "ip4-input", "ip4-input-no-checksum"};
+
+static clib_error_t *
+ip4_feature_init (vlib_main_t * vm, ip4_main_t * im)
+{
+ ip_lookup_main_t * lm = &im->lookup_main;
+ clib_error_t * error;
+ vnet_cast_t cast;
+
+ for (cast = 0; cast < VNET_N_CAST; cast++)
+ {
+ ip_config_main_t * cm = &lm->rx_config_mains[cast];
+ vnet_config_main_t * vcm = &cm->config_main;
+
+ if ((error = ip_feature_init_cast (vm, cm, vcm,
+ feature_start_nodes,
+ ARRAY_LEN(feature_start_nodes),
+ cast,
+ 1 /* is_ip4 */)))
+ return error;
+ }
+ return 0;
+}
+
static clib_error_t *
ip4_sw_interface_add_del (vnet_main_t * vnm,
u32 sw_if_index,
ip4_main_t * im = &ip4_main;
ip_lookup_main_t * lm = &im->lookup_main;
u32 ci, cast;
+ u32 feature_index;
for (cast = 0; cast < VNET_N_CAST; cast++)
{
ip_config_main_t * cm = &lm->rx_config_mains[cast];
vnet_config_main_t * vcm = &cm->config_main;
- if (! vcm->node_index_by_feature_index)
- {
- if (cast == VNET_UNICAST)
- {
- static char * start_nodes[] = { "ip4-input", "ip4-input-no-checksum", };
- static char * feature_nodes[] = {
- [IP4_RX_FEATURE_CHECK_ACCESS] = "ip4-inacl",
- [IP4_RX_FEATURE_SOURCE_CHECK_REACHABLE_VIA_RX] = "ip4-source-check-via-rx",
- [IP4_RX_FEATURE_SOURCE_CHECK_REACHABLE_VIA_ANY] = "ip4-source-check-via-any",
- [IP4_RX_FEATURE_IPSEC] = "ipsec-input-ip4",
- [IP4_RX_FEATURE_VPATH] = "vpath-input-ip4",
- [IP4_RX_FEATURE_LOOKUP] = "ip4-lookup",
- };
-
- vnet_config_init (vm, vcm,
- start_nodes, ARRAY_LEN (start_nodes),
- feature_nodes, ARRAY_LEN (feature_nodes));
- }
- else
- {
- static char * start_nodes[] = { "ip4-input", "ip4-input-no-checksum", };
- static char * feature_nodes[] = {
- [IP4_RX_FEATURE_VPATH] = "vpath-input-ip4",
- [IP4_RX_FEATURE_LOOKUP] = "ip4-lookup-multicast",
- };
-
- vnet_config_init (vm, vcm,
- start_nodes, ARRAY_LEN (start_nodes),
- feature_nodes, ARRAY_LEN (feature_nodes));
- }
- }
-
vec_validate_init_empty (cm->config_index_by_sw_if_index, sw_if_index, ~0);
ci = cm->config_index_by_sw_if_index[sw_if_index];
+ if (cast == VNET_UNICAST)
+ feature_index = im->ip4_unicast_rx_feature_lookup;
+ else
+ feature_index = im->ip4_multicast_rx_feature_lookup;
+
if (is_add)
ci = vnet_config_add_feature (vm, vcm,
ci,
- IP4_RX_FEATURE_LOOKUP,
+ feature_index,
/* config data */ 0,
/* # bytes of config data */ 0);
else
ci = vnet_config_del_feature (vm, vcm,
ci,
- IP4_RX_FEATURE_LOOKUP,
+ feature_index,
/* config data */ 0,
/* # bytes of config data */ 0);
.format_trace = format_ip4_lookup_trace,
- .n_next_nodes = IP_LOOKUP_N_NEXT,
+ .n_next_nodes = IP4_LOOKUP_N_NEXT,
.next_nodes = IP4_LOOKUP_NEXT_NODES,
};
.function = ip4_indirect,
.name = "ip4-indirect",
.vector_size = sizeof (u32),
-
+ .sibling_of = "ip4-lookup",
.format_trace = format_ip4_lookup_trace,
- .n_next_nodes = IP_LOOKUP_N_NEXT,
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
+ .n_next_nodes = 0,
};
VLIB_NODE_FUNCTION_MULTIARCH (ip4_indirect_node, ip4_indirect)
"ip4 arp");
}
+ ip4_feature_init (vm, im);
+
return 0;
}
clib_memcpy (h0->ip4_over_ethernet[0].ethernet, hw_if0->hw_address,
sizeof (h0->ip4_over_ethernet[0].ethernet));
- ip4_src_address_for_packet (im, p0, &h0->ip4_over_ethernet[0].ip4, sw_if_index0);
+ if (ip4_src_address_for_packet (im, p0, &h0->ip4_over_ethernet[0].ip4, sw_if_index0)) {
+ //No source address available
+ p0->error = node->errors[IP4_ARP_ERROR_NO_SOURCE_ADDRESS];
+ vlib_buffer_free(vm, &bi0, 1);
+ continue;
+ }
/* Copy in destination address we are requesting. */
h0->ip4_over_ethernet[1].ip4.data_u32 = ip0->dst_address.data_u32;
[IP4_ARP_ERROR_NON_ARP_ADJ] = "ARPs to non-ARP adjacencies",
[IP4_ARP_ERROR_REPLICATE_DROP] = "ARP replication completed",
[IP4_ARP_ERROR_REPLICATE_FAIL] = "ARP replication failed",
+ [IP4_ARP_ERROR_NO_SOURCE_ADDRESS] = "no source address for ARP request",
};
VLIB_REGISTER_NODE (ip4_arp_node) = {
/* Worth pipelining. No guarantee that adj0,1 are hot... */
rw_len0 = adj0[0].rewrite_header.data_bytes;
rw_len1 = adj1[0].rewrite_header.data_bytes;
+
+ /* Check MTU of outgoing interface. */
+ error0 = (vlib_buffer_length_in_chain (vm, p0) > adj0[0].rewrite_header.max_l3_packet_bytes
+ ? IP4_ERROR_MTU_EXCEEDED
+ : error0);
+ error1 = (vlib_buffer_length_in_chain (vm, p1) > adj1[0].rewrite_header.max_l3_packet_bytes
+ ? IP4_ERROR_MTU_EXCEEDED
+ : error1);
+
next0 = (error0 == IP4_ERROR_NONE)
? adj0[0].rewrite_header.next_index : 0;
/* packet increment */ 0,
/* byte increment */ rw_len1-sizeof(ethernet_header_t));
- /* Check MTU of outgoing interface. */
- error0 = (vlib_buffer_length_in_chain (vm, p0) > adj0[0].rewrite_header.max_l3_packet_bytes
- ? IP4_ERROR_MTU_EXCEEDED
- : error0);
- error1 = (vlib_buffer_length_in_chain (vm, p1) > adj1[0].rewrite_header.max_l3_packet_bytes
- ? IP4_ERROR_MTU_EXCEEDED
- : error1);
-
p0->current_data -= rw_len0;
p1->current_data -= rw_len1;
.format_trace = format_ip4_rewrite_trace,
- .n_next_nodes = 2,
- .next_nodes = {
- [IP4_REWRITE_NEXT_DROP] = "error-drop",
- [IP4_REWRITE_NEXT_ARP] = "ip4-arp",
- },
+ .n_next_nodes = 0,
};
VLIB_NODE_FUNCTION_MULTIARCH (ip4_rewrite_local_node, ip4_rewrite_local)
.function = ip4_lookup_multicast,
.name = "ip4-lookup-multicast",
.vector_size = sizeof (u32),
-
+ .sibling_of = "ip4-lookup",
.format_trace = format_ip4_lookup_trace,
- .n_next_nodes = IP_LOOKUP_N_NEXT,
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
+ .n_next_nodes = 0,
};
VLIB_NODE_FUNCTION_MULTIARCH (ip4_lookup_multicast_node, ip4_lookup_multicast)