aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-07-16 14:00:16 +0000
committerBeno�t Ganne <bganne@cisco.com>2022-08-09 14:17:46 +0000
commitfd2417b2a42e34062e3d07875e5c4e11922513d5 (patch)
treeeec1ea914c259f685e2bca897e5853faec9339c1 /test
parent896b184b781a09ce5cefb94c471029c6a8d025aa (diff)
ip-neighbor: ARP and ND stats per-interface.
Type: feature stats of the like from: https://datatracker.ietf.org/doc/html/draft-ietf-rtgwg-arp-yang-model-03#section-4 Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: Icb1bf4f6f7e6ccc2f44b0008d4774b61cae96184
Diffstat (limited to 'test')
-rw-r--r--test/test_ip6.py54
-rw-r--r--test/test_neighbor.py34
2 files changed, 88 insertions, 0 deletions
diff --git a/test/test_ip6.py b/test/test_ip6.py
index ca153dba0e6..01a6d94288c 100644
--- a/test/test_ip6.py
+++ b/test/test_ip6.py
@@ -193,6 +193,22 @@ class TestIPv6ND(VppTestCase):
self.assertEqual(ip.src, sip)
self.assertEqual(ip.dst, dip)
+ def get_ip6_nd_rx_requests(self, itf):
+ """Get IP6 ND RX request stats for and interface"""
+ return self.statistics["/net/ip6-nd/rx/requests"][:, itf.sw_if_index].sum()
+
+ def get_ip6_nd_tx_requests(self, itf):
+ """Get IP6 ND TX request stats for and interface"""
+ return self.statistics["/net/ip6-nd/tx/requests"][:, itf.sw_if_index].sum()
+
+ def get_ip6_nd_rx_replies(self, itf):
+ """Get IP6 ND RX replies stats for and interface"""
+ return self.statistics["/net/ip6-nd/rx/replies"][:, itf.sw_if_index].sum()
+
+ def get_ip6_nd_tx_replies(self, itf):
+ """Get IP6 ND TX replies stats for and interface"""
+ return self.statistics["/net/ip6-nd/tx/replies"][:, itf.sw_if_index].sum()
+
@tag_run_solo
class TestIPv6(TestIPv6ND):
@@ -430,6 +446,9 @@ class TestIPv6(TestIPv6ND):
- Send NS for a target address the router does not onn.
"""
+ n_rx_req_pg0 = self.get_ip6_nd_rx_requests(self.pg0)
+ n_tx_rep_pg0 = self.get_ip6_nd_tx_replies(self.pg0)
+
#
# An NS from a non link source address
#
@@ -447,6 +466,7 @@ class TestIPv6(TestIPv6ND):
self.send_and_assert_no_replies(
self.pg0, pkts, "No response to NS source by address not on sub-net"
)
+ self.assert_equal(self.get_ip6_nd_rx_requests(self.pg0), n_rx_req_pg0 + 1)
#
# An NS for sent to a solicited mcast group the router is
@@ -485,6 +505,7 @@ class TestIPv6(TestIPv6ND):
self.send_and_assert_no_replies(
self.pg0, pkts, "No response to NS for unknown target"
)
+ self.assert_equal(self.get_ip6_nd_rx_requests(self.pg0), n_rx_req_pg0 + 2)
#
# A neighbor entry that has no associated FIB-entry
@@ -525,6 +546,8 @@ class TestIPv6(TestIPv6ND):
dst_ip=self.pg0._remote_hosts[2].ip6_ll,
tgt_ip=self.pg0.local_ip6,
)
+ self.assert_equal(self.get_ip6_nd_rx_requests(self.pg0), n_rx_req_pg0 + 3)
+ self.assert_equal(self.get_ip6_nd_tx_replies(self.pg0), n_tx_rep_pg0 + 1)
#
# we should have learned an ND entry for the peer's link-local
@@ -574,6 +597,37 @@ class TestIPv6(TestIPv6ND):
)
self.assertFalse(find_route(self, self.pg0._remote_hosts[3].ip6_ll, 128))
+ def test_nd_incomplete(self):
+ """IP6-ND Incomplete"""
+ self.pg1.generate_remote_hosts(3)
+
+ p0 = (
+ Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
+ / IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_hosts[1].ip6)
+ / UDP(sport=1234, dport=1234)
+ / Raw()
+ )
+
+ #
+ # a packet to an unresolved destination generates an ND request
+ #
+ n_tx_req_pg1 = self.get_ip6_nd_tx_requests(self.pg1)
+ self.send_and_expect_ns(self.pg0, self.pg1, p0, self.pg1.remote_hosts[1].ip6)
+ self.assert_equal(self.get_ip6_nd_tx_requests(self.pg1), n_tx_req_pg1 + 1)
+
+ #
+ # a reply to the request
+ #
+ self.assert_equal(self.get_ip6_nd_rx_replies(self.pg1), 0)
+ na = (
+ Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
+ / IPv6(dst=self.pg1.local_ip6, src=self.pg1.remote_hosts[1].ip6)
+ / ICMPv6ND_NA(tgt=self.pg1.remote_hosts[1].ip6)
+ / ICMPv6NDOptSrcLLAddr(lladdr=self.pg1.remote_hosts[1].mac)
+ )
+ self.send_and_assert_no_replies(self.pg1, [na])
+ self.assert_equal(self.get_ip6_nd_rx_replies(self.pg1), 1)
+
def test_ns_duplicates(self):
"""ND Duplicates"""
diff --git a/test/test_neighbor.py b/test/test_neighbor.py
index e1b37a0a124..64be36d739a 100644
--- a/test/test_neighbor.py
+++ b/test/test_neighbor.py
@@ -160,6 +160,30 @@ class ARPTestCase(VppTestCase):
self.assertEqual(ip.src, sip)
self.assertEqual(ip.dst, dip)
+ def get_arp_rx_requests(self, itf):
+ """Get ARP RX request stats for and interface"""
+ return self.statistics["/net/arp/rx/requests"][:, itf.sw_if_index].sum()
+
+ def get_arp_tx_requests(self, itf):
+ """Get ARP TX request stats for and interface"""
+ return self.statistics["/net/arp/tx/requests"][:, itf.sw_if_index].sum()
+
+ def get_arp_rx_replies(self, itf):
+ """Get ARP RX replies stats for and interface"""
+ return self.statistics["/net/arp/rx/replies"][:, itf.sw_if_index].sum()
+
+ def get_arp_tx_replies(self, itf):
+ """Get ARP TX replies stats for and interface"""
+ return self.statistics["/net/arp/tx/replies"][:, itf.sw_if_index].sum()
+
+ def get_arp_rx_garp(self, itf):
+ """Get ARP RX grat stats for and interface"""
+ return self.statistics["/net/arp/rx/gratuitous"][:, itf.sw_if_index].sum()
+
+ def get_arp_tx_garp(self, itf):
+ """Get ARP RX grat stats for and interface"""
+ return self.statistics["/net/arp/tx/gratuitous"][:, itf.sw_if_index].sum()
+
def test_arp(self):
"""ARP"""
@@ -208,6 +232,10 @@ class ARPTestCase(VppTestCase):
rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4
)
+ self.logger.info(self.vapi.cli("sh ip neighbor-stats"))
+ self.logger.info(self.vapi.cli("sh ip neighbor-stats pg1"))
+ self.assert_equal(self.get_arp_tx_requests(self.pg1), 1)
+
#
# And a dynamic ARP entry for host 1
#
@@ -328,6 +356,7 @@ class ARPTestCase(VppTestCase):
self.verify_arp_req(
rx[0], self.pg1.local_mac, self.pg1.local_ip4, self.pg1._remote_hosts[1].ip4
)
+ self.assert_equal(self.get_arp_tx_requests(self.pg1), 2)
self.assertFalse(dyn_arp.query_vpp_config())
self.assertTrue(static_arp.query_vpp_config())
@@ -353,6 +382,9 @@ class ARPTestCase(VppTestCase):
self.pg1.local_ip4,
self.pg1._remote_hosts[3].ip4,
)
+ self.logger.info(self.vapi.cli("sh ip neighbor-stats pg1"))
+ self.assert_equal(self.get_arp_rx_requests(self.pg1), 1)
+ self.assert_equal(self.get_arp_tx_replies(self.pg1), 1)
#
# VPP should have learned the mapping for the remote host
@@ -1662,6 +1694,7 @@ class ARPTestCase(VppTestCase):
mac=self.pg1.remote_hosts[2].mac,
)
)
+ self.assert_equal(self.get_arp_rx_garp(self.pg1), 1)
#
# Send a GARP (reply) to swap the host 1's address to that of host 3
@@ -1686,6 +1719,7 @@ class ARPTestCase(VppTestCase):
mac=self.pg1.remote_hosts[3].mac,
)
)
+ self.assert_equal(self.get_arp_rx_garp(self.pg1), 2)
#
# GARPs (request nor replies) for host we don't know yet