aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_vrrp.py
diff options
context:
space:
mode:
authorEmanuele Di Pascale <lele84@gmail.com>2022-03-29 12:29:23 +0200
committerEmanuele Di Pascale <lele84@gmail.com>2022-04-01 18:10:35 +0200
commit7539e4b5522b015a715ba49eed4477b8cece1b86 (patch)
tree9f181557091c4125d1561f606fa40f4d0f5d2ef5 /test/test_vrrp.py
parent2518dca440f1ef41500d73067fe44318b782b98d (diff)
vrrp: add stats support and update API
Add simple counter statistics to VRRP, based on a subset of those defined in RFC8347. Add an update API that allows in-place modification of an existing instance. The method returns a vrrp_index which can be used both for retrieving statistics and to modify non-key parameters. Also add a delete method which will take that vrrp_index as parameter. Type: improvement Signed-off-by: Emanuele Di Pascale <lele84@gmail.com> Change-Id: I2cd11467b4dbd9dfdb5aa748783144b4883dba57
Diffstat (limited to 'test/test_vrrp.py')
-rw-r--r--test/test_vrrp.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/test/test_vrrp.py b/test/test_vrrp.py
index 1f28cf3d18d..f7a0662bf01 100644
--- a/test/test_vrrp.py
+++ b/test/test_vrrp.py
@@ -37,6 +37,8 @@ VRRP_VR_STATE_BACKUP = 1
VRRP_VR_STATE_MASTER = 2
VRRP_VR_STATE_INTF_DOWN = 3
+VRRP_INDEX_INVALID = 0xffffffff
+
def is_non_arp(p):
""" Want to filter out advertisements, igmp, etc"""
@@ -95,6 +97,7 @@ class VppVRRPVirtualRouter(VppObject):
self._adv_dest_ip = "224.0.0.18"
self._vips = ([intf.local_ip4] if vips is None else vips)
self._tracked_ifs = []
+ self._vrrp_index = VRRP_INDEX_INVALID
def add_vpp_config(self):
self._test.vapi.vrrp_vr_add_del(is_add=1,
@@ -106,6 +109,20 @@ class VppVRRPVirtualRouter(VppObject):
n_addrs=len(self._vips),
addrs=self._vips)
+ def update_vpp_config(self):
+ r = self._test.vapi.vrrp_vr_update(vrrp_index=self._vrrp_index,
+ sw_if_index=self._intf.sw_if_index,
+ vr_id=self._vr_id,
+ priority=self._prio,
+ interval=self._intvl,
+ flags=self._flags,
+ n_addrs=len(self._vips),
+ addrs=self._vips)
+ self._vrrp_index = r.vrrp_index
+
+ def delete_vpp_config(self):
+ self._test.vapi.vrrp_vr_del(vrrp_index=self._vrrp_index)
+
def query_vpp_config(self):
vrs = self._test.vapi.vrrp_vr_dump(sw_if_index=self._intf.sw_if_index)
for vr in vrs:
@@ -341,6 +358,56 @@ class TestVRRP4(VppTestCase):
vr.remove_vpp_config()
self._vrs = []
+ # Same as above but with the update API, and add a change
+ # of parameters to test that too
+ def test_vrrp4_master_adv_update(self):
+ """ IPv4 Master VR adv + Update to Backup """
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ prio = 255
+ intvl = self._default_adv
+ vr = VppVRRPVirtualRouter(self, self.pg0, 100,
+ prio=prio, intvl=intvl,
+ flags=self._default_flags)
+
+ vr.update_vpp_config()
+ vr.start_stop(is_start=1)
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+ # Update VR with lower prio and larger interval
+ # we need to keep old VR for the adv checks
+ upd_vr = VppVRRPVirtualRouter(self, self.pg0, 100,
+ prio=100, intvl=2*intvl,
+ flags=self._default_flags,
+ vips=[self.pg0.remote_ip4])
+ upd_vr._vrrp_index = vr._vrrp_index
+ upd_vr.update_vpp_config()
+ start_time = time.time()
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+ upd_vr.assert_state_equals(VRRP_VR_STATE_BACKUP)
+ self._vrs = [upd_vr]
+
+ pkts = self.pg0.get_capture(5)
+ # Init -> Master: IGMP Join, VRRP adv, gratuitous ARP are sent
+ self.verify_vrrp4_igmp(pkts[0])
+ self.verify_vrrp4_adv(pkts[1], vr, prio=prio)
+ self.verify_vrrp4_garp(pkts[2], vr.virtual_ips()[0], vr.virtual_mac())
+ # Master -> Init: Adv with priority 0 sent to force an election
+ self.verify_vrrp4_adv(pkts[3], vr, prio=0)
+ # Init -> Backup: An IGMP join should be sent
+ self.verify_vrrp4_igmp(pkts[4])
+
+ # send higher prio advertisements, should not receive any
+ end_time = start_time + 2 * upd_vr.master_down_seconds()
+ src_ip = self.pg0.remote_ip4
+ pkts = [upd_vr.vrrp_adv_packet(prio=110, src_ip=src_ip)]
+ while time.time() < end_time:
+ self.send_and_assert_no_replies(self.pg0, pkts, timeout=intvl*0.01)
+ self.logger.info(self.vapi.cli("show trace"))
+
+ upd_vr.start_stop(is_start=0)
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+
# VR with priority < 255 enters backup state and does not advertise as
# long as it receives higher priority advertisements
def test_vrrp4_backup_noadv(self):
@@ -875,6 +942,59 @@ class TestVRRP6(VppTestCase):
vr.remove_vpp_config()
self._vrs = []
+ # Same as above but with the update API, and add a change
+ # of parameters to test that too
+ def test_vrrp6_master_adv_update(self):
+ """ IPv6 Master VR adv + Update to Backup """
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ prio = 255
+ intvl = self._default_adv
+ vr = VppVRRPVirtualRouter(self, self.pg0, 100,
+ prio=prio, intvl=intvl,
+ flags=self._default_flags)
+
+ vr.update_vpp_config()
+ vr.start_stop(is_start=1)
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+ # Update VR with lower prio and larger interval
+ # we need to keep old VR for the adv checks
+ upd_vr = VppVRRPVirtualRouter(self, self.pg0, 100,
+ prio=100, intvl=2*intvl,
+ flags=self._default_flags,
+ vips=[self.pg0.remote_ip6])
+ upd_vr._vrrp_index = vr._vrrp_index
+ upd_vr.update_vpp_config()
+ start_time = time.time()
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+ upd_vr.assert_state_equals(VRRP_VR_STATE_BACKUP)
+ self._vrs = [upd_vr]
+
+ pkts = self.pg0.get_capture(5, filter_out_fn=None)
+
+ # Init -> Master: Multicast group Join, VRRP adv, gratuitous NAs sent
+ self.verify_vrrp6_mlr(pkts[0], vr)
+ self.verify_vrrp6_adv(pkts[1], vr, prio=prio)
+ self.verify_vrrp6_gna(pkts[2], vr)
+ # Master -> Init: Adv with priority 0 sent to force an election
+ self.verify_vrrp6_adv(pkts[3], vr, prio=0)
+ # Init -> Backup: A multicast listener report should be sent
+ # not actually verified in the test below, where I took this from
+
+ # send higher prio advertisements, should not see VPP send any
+ src_ip = self.pg0.remote_ip6_ll
+ pkts = [upd_vr.vrrp_adv_packet(prio=110, src_ip=src_ip)]
+ self.logger.info(self.vapi.cli("show vlib graph"))
+ end_time = start_time + 2 * upd_vr.master_down_seconds()
+ while time.time() < end_time:
+ self.send_and_assert_no_replies(
+ self.pg0, pkts, timeout=0.01*upd_vr._intvl)
+ self.logger.info(self.vapi.cli("show trace"))
+
+ vr.start_stop(is_start=0)
+ self.logger.info(self.vapi.cli("show vrrp vr"))
+
# VR with priority < 255 enters backup state and does not advertise as
# long as it receives higher priority advertisements
def test_vrrp6_backup_noadv(self):