a->neighbor_probe_adj_index = ~0;
- if (pfx.fp_len < 32)
+ if (pfx.fp_len <= 30)
{
+ /* a /30 or shorter - add a glean for the network address */
fib_node_index_t fei;
fei = fib_table_entry_update_one_path (fib_index, &pfx,
NULL,
FIB_ROUTE_PATH_FLAG_NONE);
a->neighbor_probe_adj_index = fib_entry_get_adj (fei);
- }
+ /* Add the two broadcast addresses as drop */
+ fib_prefix_t net_pfx = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[pfx.fp_len],
+ };
+ if (net_pfx.fp_addr.ip4.as_u32 != pfx.fp_addr.ip4.as_u32)
+ fib_table_entry_special_add(fib_index,
+ &net_pfx,
+ FIB_SOURCE_INTERFACE,
+ (FIB_ENTRY_FLAG_DROP |
+ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ ADJ_INDEX_INVALID);
+ net_pfx.fp_addr.ip4.as_u32 |= ~im->fib_masks[pfx.fp_len];
+ if (net_pfx.fp_addr.ip4.as_u32 != pfx.fp_addr.ip4.as_u32)
+ fib_table_entry_special_add(fib_index,
+ &net_pfx,
+ FIB_SOURCE_INTERFACE,
+ (FIB_ENTRY_FLAG_DROP |
+ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ ADJ_INDEX_INVALID);
+ }
+ else if (pfx.fp_len == 31)
+ {
+ u32 mask = clib_host_to_net_u32(1);
+ fib_prefix_t net_pfx = pfx;
+
+ net_pfx.fp_len = 32;
+ net_pfx.fp_addr.ip4.as_u32 ^= mask;
+
+ /* a /31 - add the other end as an attached host */
+ fib_table_entry_update_one_path (fib_index, &net_pfx,
+ FIB_SOURCE_INTERFACE,
+ (FIB_ENTRY_FLAG_ATTACHED),
+ FIB_PROTOCOL_IP4,
+ &net_pfx.fp_addr,
+ sw_if_index,
+ // invalid FIB index
+ ~0,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ }
pfx.fp_len = 32;
if (sw_if_index < vec_len (lm->classify_table_index_by_sw_if_index))
.fp_addr.ip4 = *address,
};
- if (pfx.fp_len < 32)
+ if (pfx.fp_len <= 30)
{
+ fib_prefix_t net_pfx = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[pfx.fp_len],
+ };
+ if (net_pfx.fp_addr.ip4.as_u32 != pfx.fp_addr.ip4.as_u32)
+ fib_table_entry_special_remove(fib_index,
+ &net_pfx,
+ FIB_SOURCE_INTERFACE);
+ net_pfx.fp_addr.ip4.as_u32 |= ~im->fib_masks[pfx.fp_len];
+ if (net_pfx.fp_addr.ip4.as_u32 != pfx.fp_addr.ip4.as_u32)
+ fib_table_entry_special_remove(fib_index,
+ &net_pfx,
+ FIB_SOURCE_INTERFACE);
fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE);
}
+ else if (pfx.fp_len == 31)
+ {
+ u32 mask = clib_host_to_net_u32(1);
+ fib_prefix_t net_pfx = pfx;
+
+ net_pfx.fp_len = 32;
+ net_pfx.fp_addr.ip4.as_u32 ^= mask;
+
+ fib_table_entry_delete (fib_index, &net_pfx, FIB_SOURCE_INTERFACE);
+ }
pfx.fp_len = 32;
fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE);
!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 *
{
.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,
};
.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,
};
.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 */
};
{
.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,
};
adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
adj_index1 = vnet_buffer (p1)->ip.adj_index[VLIB_TX];
+ /*
+ * pre-fetch the per-adjacency counters
+ */
+ if (do_counters)
+ {
+ vlib_prefetch_combined_counter (&adjacency_counters,
+ cpu_index, adj_index0);
+ vlib_prefetch_combined_counter (&adjacency_counters,
+ cpu_index, adj_index1);
+ }
+
/* We should never rewrite a pkt using the MISS adjacency */
ASSERT (adj_index0 && adj_index1);
rewrite_header.max_l3_packet_bytes ? IP4_ERROR_MTU_EXCEEDED :
error1);
- /*
- * pre-fetch the per-adjacency counters
- */
- 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 */
if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
/*
* copy bytes from the IP address into the MAC rewrite
*/
- vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0, 1);
- vnet_fixup_one_header (adj1[0], &ip1->dst_address, ip1, 1);
+ 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,
p0->flags &= ~VNET_BUFFER_LOCALLY_ORIGINATED;
}
- vlib_prefetch_combined_counter (&adjacency_counters,
- cpu_index, adj_index0);
+ if (do_counters)
+ vlib_prefetch_combined_counter (&adjacency_counters,
+ cpu_index, adj_index0);
/* Guess we are only writing on simple Ethernet header. */
vnet_rewrite_one_header (adj0[0], ip0, sizeof (ethernet_header_t));
/*
* copy bytes from the IP address into the MAC rewrite
*/
- vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0, 1);
+ vnet_fixup_one_header (adj0[0], &ip0->dst_address, ip0);
}
/* Update packet buffer attributes/set output interface. */
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,
+ cpu_index, adj_index0, 1,
+ vlib_buffer_length_in_chain (vm, p0) + rw_len0);
/* Check MTU of outgoing interface. */
error0 = (vlib_buffer_length_in_chain (vm, p0)