IP-MAC,ND:wildcard events,fix sending multiple events
wildcard ND events publisher was sending the last event mutiple times Change-Id: I6c30f2de03fa825e79df9005a3cfaaf68ff7ea2f Signed-off-by: Eyal Bari <ebari@cisco.com>
This commit is contained in:
@@ -216,6 +216,7 @@ _(to_netconf_client) \
|
||||
_(from_netconf_client) \
|
||||
_(oam_events) \
|
||||
_(bfd_events) \
|
||||
_(wc_ip6_nd_events) \
|
||||
_(wc_ip4_arp_events)
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -94,6 +94,7 @@ typedef struct
|
||||
ethernet_proxy_arp_t *proxy_arps;
|
||||
|
||||
uword wc_ip4_arp_publisher_node;
|
||||
uword wc_ip4_arp_publisher_et;
|
||||
} ethernet_arp_main_t;
|
||||
|
||||
static ethernet_arp_main_t ethernet_arp_main;
|
||||
@@ -1536,21 +1537,24 @@ vnet_arp_wc_publish_internal (vnet_main_t * vnm,
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
ethernet_arp_main_t *am = ðernet_arp_main;
|
||||
if (am->wc_ip4_arp_publisher_node == (uword) ~ 0)
|
||||
uword ni = am->wc_ip4_arp_publisher_node;
|
||||
uword et = am->wc_ip4_arp_publisher_et;
|
||||
|
||||
if (ni == (uword) ~ 0)
|
||||
return;
|
||||
wc_arp_report_t *r =
|
||||
vlib_process_signal_event_data (vm, am->wc_ip4_arp_publisher_node, 1, 1,
|
||||
sizeof *r);
|
||||
vlib_process_signal_event_data (vm, ni, et, 1, sizeof *r);
|
||||
r->ip4 = args->a.ip4.as_u32;
|
||||
r->sw_if_index = args->sw_if_index;
|
||||
memcpy (r->mac, args->a.ethernet, sizeof r->mac);
|
||||
}
|
||||
|
||||
void
|
||||
wc_arp_set_publisher_node (uword node_index)
|
||||
wc_arp_set_publisher_node (uword node_index, uword event_type)
|
||||
{
|
||||
ethernet_arp_main_t *am = ðernet_arp_main;
|
||||
am->wc_ip4_arp_publisher_node = node_index;
|
||||
am->wc_ip4_arp_publisher_et = event_type;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -543,7 +543,7 @@ int vnet_add_del_ip4_arp_change_event (vnet_main_t * vnm,
|
||||
uword type_opaque,
|
||||
uword data, int is_add);
|
||||
|
||||
void wc_arp_set_publisher_node (uword inode_index);
|
||||
void wc_arp_set_publisher_node (uword inode_index, uword event_type);
|
||||
|
||||
void ethernet_arp_change_mac (u32 sw_if_index);
|
||||
void ethernet_ndp_change_mac (u32 sw_if_index);
|
||||
|
||||
+53
-20
@@ -195,6 +195,9 @@ typedef struct
|
||||
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 */
|
||||
@@ -216,6 +219,50 @@ typedef union
|
||||
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)
|
||||
{
|
||||
@@ -3931,6 +3978,8 @@ ip6_neighbor_init (vlib_main_t * vm)
|
||||
/* 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
|
||||
@@ -4047,7 +4096,6 @@ vnet_ip6_nd_term (vlib_main_t * vm,
|
||||
{
|
||||
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 &&
|
||||
@@ -4063,26 +4111,11 @@ vnet_ip6_nd_term (vlib_main_t * vm,
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
@@ -89,6 +89,14 @@ extern int ip6_neighbor_proxy_add_del (u32 sw_if_index,
|
||||
|
||||
u32 ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index,
|
||||
u32 is_add);
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
ip6_address_t ip6;
|
||||
u8 mac[6];
|
||||
} wc_nd_report_t;
|
||||
|
||||
void wc_nd_set_publisher_node (uword node_index, uword event_type);
|
||||
|
||||
#endif /* included_ip6_neighbor_h */
|
||||
|
||||
|
||||
+145
-76
File diff suppressed because it is too large
Load Diff
@@ -168,6 +168,13 @@ class TestL2bdArpTerm(VppTestCase):
|
||||
def arp_event_hosts(self, evs):
|
||||
return {self.arp_event_host(e) for e in evs}
|
||||
|
||||
def nd_event_host(self, e):
|
||||
return Host(mac=':'.join(['%02x' % ord(char) for char in e.new_mac]),
|
||||
ip6=inet_ntop(AF_INET6, e.address))
|
||||
|
||||
def nd_event_hosts(self, evs):
|
||||
return {self.nd_event_host(e) for e in evs}
|
||||
|
||||
@classmethod
|
||||
def ns_req(cls, src_host, host):
|
||||
nsma = in6_getnsma(inet_pton(AF_INET6, "fd10::ffff"))
|
||||
@@ -178,7 +185,11 @@ class TestL2bdArpTerm(VppTestCase):
|
||||
ICMPv6NDOptSrcLLAddr(lladdr=src_host.mac))
|
||||
|
||||
@classmethod
|
||||
def ns_reqs(cls, src_host, entries):
|
||||
def ns_reqs_dst(cls, entries, dst_host):
|
||||
return [cls.ns_req(e, dst_host) for e in entries]
|
||||
|
||||
@classmethod
|
||||
def ns_reqs_src(cls, src_host, entries):
|
||||
return [cls.ns_req(src_host, e) for e in entries]
|
||||
|
||||
def na_resp_host(self, src_host, rx):
|
||||
@@ -237,7 +248,7 @@ class TestL2bdArpTerm(VppTestCase):
|
||||
self.assertEqual(len(resps ^ resp_hosts), 0)
|
||||
|
||||
def verify_nd(self, src_host, req_hosts, resp_hosts, bd_id=1):
|
||||
reqs = self.ns_reqs(src_host, req_hosts)
|
||||
reqs = self.ns_reqs_src(src_host, req_hosts)
|
||||
|
||||
for swif in self.bd_swifs(bd_id):
|
||||
swif.add_stream(reqs)
|
||||
@@ -423,6 +434,59 @@ class TestL2bdArpTerm(VppTestCase):
|
||||
self.assertEqual(len(self.vapi.collect_events()), 0)
|
||||
self.bd_add_del(1, is_add=0)
|
||||
|
||||
def test_l2bd_arp_term_12(self):
|
||||
""" L2BD ND term - send NS packets verify reports
|
||||
"""
|
||||
self.vapi.want_ip6_nd_events(address=inet_pton(AF_INET6, "::0"))
|
||||
dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
|
||||
self.bd_add_del(1, is_add=1)
|
||||
self.set_bd_flags(1, arp_term=True, flood=False,
|
||||
uu_flood=False, learn=False)
|
||||
macs = self.mac_list(range(10, 15))
|
||||
hosts = self.ip6_hosts(5, 1, macs)
|
||||
reqs = self.ns_reqs_dst(hosts, dst_host)
|
||||
self.bd_swifs(1)[0].add_stream(reqs)
|
||||
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
evs = [self.vapi.wait_for_event(2, "ip6_nd_event")
|
||||
for i in range(len(hosts))]
|
||||
ev_hosts = self.nd_event_hosts(evs)
|
||||
self.assertEqual(len(ev_hosts ^ hosts), 0)
|
||||
|
||||
def test_l2bd_arp_term_13(self):
|
||||
""" L2BD ND term - send duplicate ns, verify suppression
|
||||
"""
|
||||
dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
|
||||
macs = self.mac_list(range(10, 11))
|
||||
hosts = self.ip6_hosts(5, 1, macs)
|
||||
reqs = self.ns_reqs_dst(hosts, dst_host) * 5
|
||||
self.bd_swifs(1)[0].add_stream(reqs)
|
||||
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
evs = [self.vapi.wait_for_event(2, "ip6_nd_event")
|
||||
for i in range(len(hosts))]
|
||||
ev_hosts = self.nd_event_hosts(evs)
|
||||
self.assertEqual(len(ev_hosts ^ hosts), 0)
|
||||
|
||||
def test_l2bd_arp_term_14(self):
|
||||
""" L2BD ND term - disable ip4 arp events,send ns, verify no events
|
||||
"""
|
||||
self.vapi.want_ip6_nd_events(enable_disable=0,
|
||||
address=inet_pton(AF_INET6, "::0"))
|
||||
dst_host = self.ip6_host(50, 50, "00:00:11:22:33:44")
|
||||
macs = self.mac_list(range(10, 15))
|
||||
hosts = self.ip6_hosts(5, 1, macs)
|
||||
reqs = self.ns_reqs_dst(hosts, dst_host)
|
||||
self.bd_swifs(1)[0].add_stream(reqs)
|
||||
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
self.sleep(1)
|
||||
self.assertEqual(len(self.vapi.collect_events()), 0)
|
||||
self.bd_add_del(1, is_add=0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=VppTestRunner)
|
||||
|
||||
@@ -425,6 +425,12 @@ class VppPapiProvider(object):
|
||||
'address': address,
|
||||
'pid': os.getpid(), })
|
||||
|
||||
def want_ip6_nd_events(self, enable_disable=1, address=0):
|
||||
return self.api(self.papi.want_ip6_nd_events,
|
||||
{'enable_disable': enable_disable,
|
||||
'address': address,
|
||||
'pid': os.getpid(), })
|
||||
|
||||
def l2fib_add_del(self, mac, bd_id, sw_if_index, is_add=1, static_mac=0,
|
||||
filter_mac=0, bvi_mac=0):
|
||||
"""Create/delete L2 FIB entry.
|
||||
|
||||
Reference in New Issue
Block a user