u32 limit_neighbor_cache_size;
u32 neighbor_delete_rotor;
+ /* Wildcard nd report publisher */
+ uword wc_ip6_nd_publisher_node;
+ uword wc_ip6_nd_publisher_et;
} ip6_neighbor_main_t;
/* ipv6 neighbor discovery - timer/event types */
static ip6_neighbor_main_t ip6_neighbor_main;
static ip6_address_t ip6a_zero; /* ip6 address 0 */
+static void wc_nd_signal_report (wc_nd_report_t * r);
+
+/**
+ * @brief publish wildcard arp event
+ * @param sw_if_index The interface on which the ARP entires are acted
+ */
+static int
+vnet_nd_wc_publish (u32 sw_if_index, u8 * mac, ip6_address_t * ip6)
+{
+ wc_nd_report_t r = {
+ .sw_if_index = sw_if_index,
+ .ip6 = *ip6,
+ };
+ memcpy (r.mac, mac, sizeof r.mac);
+
+ void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
+ vl_api_rpc_call_main_thread (wc_nd_signal_report, (u8 *) & r, sizeof r);
+ return 0;
+}
+
+static void
+wc_nd_signal_report (wc_nd_report_t * r)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ ip6_neighbor_main_t *nm = &ip6_neighbor_main;
+ uword ni = nm->wc_ip6_nd_publisher_node;
+ uword et = nm->wc_ip6_nd_publisher_et;
+
+ if (ni == (uword) ~ 0)
+ return;
+ wc_nd_report_t *q =
+ vlib_process_signal_event_data (vm, ni, et, 1, sizeof *q);
+
+ *q = *r;
+}
+
+void
+wc_nd_set_publisher_node (uword node_index, uword event_type)
+{
+ ip6_neighbor_main_t *nm = &ip6_neighbor_main;
+ nm->wc_ip6_nd_publisher_node = node_index;
+ nm->wc_ip6_nd_publisher_et = event_type;
+}
+
static u8 *
format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
{
}
static void
-ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, uint32_t fib_index)
+ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, u32 fib_index)
{
if (FIB_NODE_INDEX_INVALID != n->fib_entry_index)
{
switch (adj->lookup_next_index)
{
- case IP_LOOKUP_NEXT_ARP:
case IP_LOOKUP_NEXT_GLEAN:
+ adj_glean_update_rewrite (ai);
+ break;
+ case IP_LOOKUP_NEXT_ARP:
if (NULL != nbr)
{
adj_nbr_walk_nh6 (sw_if_index, &nbr->key.ip6_address,
static void
-ip6_neighbor_adj_fib_add (ip6_neighbor_t * n, uint32_t fib_index)
+ip6_neighbor_adj_fib_add (ip6_neighbor_t * n, u32 fib_index)
{
fib_prefix_t pfx = {
.fp_len = 128,
*/
if (0 == memcmp (n->link_layer_address,
link_layer_address, n_bytes_link_layer_address))
- return -1;
+ goto check_customers;
clib_memcpy (n->link_layer_address,
link_layer_address, n_bytes_link_layer_address);
adj_nbr_walk_nh6 (sw_if_index,
&n->key.ip6_address, ip6_nd_mk_complete_walk, n);
+check_customers:
/* Customer(s) waiting for this address to be resolved? */
p = mhash_get (&nm->pending_resolutions_by_address, a);
if (p)
.n_next_nodes = ICMP6_ROUTER_SOLICITATION_N_NEXT,
.next_nodes = {
- [ICMP6_ROUTER_SOLICITATION_NEXT_DROP] = "error-drop",
+ [ICMP6_ROUTER_SOLICITATION_NEXT_DROP] = "ip6-drop",
[ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW] = "ip6-rewrite-mcast",
[ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_TX] = "interface-output",
},
.n_next_nodes = 1,
.next_nodes = {
- [0] = "error-drop",
+ [0] = "ip6-drop",
},
};
/* *INDENT-ON* */
.n_next_nodes = ICMP6_NEIGHBOR_SOLICITATION_N_NEXT,
.next_nodes = {
- [ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP] = "error-drop",
+ [ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP] = "ip6-drop",
[ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY] = "interface-output",
},
};
.n_next_nodes = 1,
.next_nodes = {
- [0] = "error-drop",
+ [0] = "ip6-drop",
},
};
/* *INDENT-ON* */
/* default, configurable */
nm->limit_neighbor_cache_size = 50000;
+ nm->wc_ip6_nd_publisher_node = (uword) ~ 0;
+
#if 0
/* $$$$ Hack fix for today */
vec_validate_init_empty
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
- pending_resolution_t *mc;
ndh = ip6_next_header (ip);
if (ndh->icmp.type != ICMP6_neighbor_solicitation &&
}
/* Check if anyone want ND events for L2 BDs */
- uword *p = mhash_get (&nm->mac_changes_by_address, &ip6a_zero);
- if (p && !ip6_address_is_link_local_unicast (&ip->src_address))
+ if (PREDICT_FALSE
+ (nm->wc_ip6_nd_publisher_node != (uword) ~ 0
+ && !ip6_address_is_link_local_unicast (&ip->src_address)))
{
- u32 next_index = p[0];
- while (next_index != (u32) ~ 0)
- {
- int (*fp) (u32, u8 *, u32, ip6_address_t *);
- int rv = 1;
- mc = pool_elt_at_index (nm->mac_changes, next_index);
- fp = mc->data_callback;
- /* Call the callback, return 1 to suppress dup events */
- if (fp)
- rv = (*fp) (mc->data,
- eth->src_address, sw_if_index, &ip->src_address);
- /* Signal the resolver process */
- if (rv == 0)
- vlib_process_signal_event (vm, mc->node_index,
- mc->type_opaque, mc->data);
- next_index = mc->next_index;
- }
+ vnet_nd_wc_publish (sw_if_index, eth->src_address, &ip->src_address);
}
/* Check if MAC entry exsist for solicited target IP */
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
ip6_neighbor_t *n;
+ adj_index_t ai;
/* *INDENT-OFF* */
pool_foreach (n, nm->neighbor_pool,
}
}));
/* *INDENT-ON* */
+
+ ai = adj_glean_get (FIB_PROTOCOL_IP6, sw_if_index);
+
+ if (ADJ_INDEX_INVALID != ai)
+ adj_glean_update_rewrite (ai);
}
void