X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_bfd.py;h=635e7e12a760b6fd5f2b73ed1ce670ab0bdf24c3;hb=6c746172ef2a8ab7b6a267a889fedd1336f00371;hp=e8f8f33849f7c9d65165772e8b873083fc5dc0ea;hpb=88fc83eb716bf07f4634de6de5b569f795a56418;p=vpp.git diff --git a/test/test_bfd.py b/test/test_bfd.py index e8f8f33849f..635e7e12a76 100644 --- a/test/test_bfd.py +++ b/test/test_bfd.py @@ -2,24 +2,30 @@ """ BFD tests """ from __future__ import division -import unittest -import hashlib + import binascii +import hashlib import time -from struct import pack, unpack +import unittest from random import randint, shuffle, getrandbits from socket import AF_INET, AF_INET6, inet_ntop -from scapy.packet import Raw -from scapy.layers.l2 import Ether +from struct import pack, unpack + +from six import moves from scapy.layers.inet import UDP, IP from scapy.layers.inet6 import IPv6 +from scapy.layers.l2 import Ether +from scapy.packet import Raw + from bfd import VppBFDAuthKey, BFD, BFDAuthType, VppBFDUDPSession, \ BFDDiagCode, BFDState, BFD_vpp_echo from framework import VppTestCase, VppTestRunner, running_extended_tests -from vpp_pg_interface import CaptureTimeoutError, is_ipv6_misc from util import ppp -from vpp_papi_provider import UnexpectedApiReturnValueError +from vpp_ip import DpoProto from vpp_ip_route import VppIpRoute, VppRoutePath +from vpp_lo_interface import VppLoInterface +from vpp_papi_provider import UnexpectedApiReturnValueError +from vpp_pg_interface import CaptureTimeoutError, is_ipv6_misc USEC_IN_SEC = 1000000 @@ -51,7 +57,7 @@ class BFDAPITestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFDAPITestCase, cls).setUpClass() - + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces(range(2)) for i in cls.pg_interfaces: @@ -82,7 +88,7 @@ class BFDAPITestCase(VppTestCase): session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4) session.add_vpp_config() - with self.vapi.expect_negative_api_retval(): + with self.vapi.assert_negative_api_retval(): session.add_vpp_config() session.remove_vpp_config() @@ -250,7 +256,53 @@ class BFDAPITestCase(VppTestCase): session.add_vpp_config() session.activate_auth(key2) + def test_set_del_udp_echo_source(self): + """ set/del udp echo source """ + self.create_loopback_interfaces(1) + self.loopback0 = self.lo_interfaces[0] + self.loopback0.admin_up() + echo_source = self.vapi.bfd_udp_get_echo_source() + self.assertFalse(echo_source.is_set) + self.assertFalse(echo_source.have_usable_ip4) + self.assertFalse(echo_source.have_usable_ip6) + + self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) + echo_source = self.vapi.bfd_udp_get_echo_source() + self.assertTrue(echo_source.is_set) + self.assertEqual(echo_source.sw_if_index, self.loopback0.sw_if_index) + self.assertFalse(echo_source.have_usable_ip4) + self.assertFalse(echo_source.have_usable_ip6) + self.loopback0.config_ip4() + unpacked = unpack("!L", self.loopback0.local_ip4n) + echo_ip4 = pack("!L", unpacked[0] ^ 1) + echo_source = self.vapi.bfd_udp_get_echo_source() + self.assertTrue(echo_source.is_set) + self.assertEqual(echo_source.sw_if_index, self.loopback0.sw_if_index) + self.assertTrue(echo_source.have_usable_ip4) + self.assertEqual(echo_source.ip4_addr, echo_ip4) + self.assertFalse(echo_source.have_usable_ip6) + + self.loopback0.config_ip6() + unpacked = unpack("!LLLL", self.loopback0.local_ip6n) + echo_ip6 = pack("!LLLL", unpacked[0], unpacked[1], unpacked[2], + unpacked[3] ^ 1) + echo_source = self.vapi.bfd_udp_get_echo_source() + self.assertTrue(echo_source.is_set) + self.assertEqual(echo_source.sw_if_index, self.loopback0.sw_if_index) + self.assertTrue(echo_source.have_usable_ip4) + self.assertEqual(echo_source.ip4_addr, echo_ip4) + self.assertTrue(echo_source.have_usable_ip6) + self.assertEqual(echo_source.ip6_addr, echo_ip6) + + self.vapi.bfd_udp_del_echo_source() + echo_source = self.vapi.bfd_udp_get_echo_source() + self.assertFalse(echo_source.is_set) + self.assertFalse(echo_source.have_usable_ip4) + self.assertFalse(echo_source.have_usable_ip6) + + +@unittest.skipUnless(running_extended_tests(), "part of extended tests") class BFDTestSession(object): """ BFD session as seen from test framework side """ @@ -554,7 +606,7 @@ def verify_udp(test, packet): def verify_event(test, event, expected_state): """ Verify correctness of event values. """ e = event - test.logger.debug("BFD: Event: %s" % repr(e)) + test.logger.debug("BFD: Event: %s" % moves.reprlib.repr(e)) test.assert_equal(e.sw_if_index, test.vpp_session.interface.sw_if_index, "BFD interface index") @@ -612,6 +664,7 @@ def wait_for_bfd_packet(test, timeout=1, pcap_time_min=None): return p +@unittest.skipUnless(running_extended_tests(), "part of extended tests") class BFD4TestCase(VppTestCase): """Bidirectional Forwarding Detection (BFD)""" @@ -623,9 +676,10 @@ class BFD4TestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFD4TestCase, cls).setUpClass() + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces([0]) - cls.create_loopback_interfaces([0]) + cls.create_loopback_interfaces(1) cls.loopback0 = cls.lo_interfaces[0] cls.loopback0.config_ip4() cls.loopback0.admin_up() @@ -1066,13 +1120,13 @@ class BFD4TestCase(VppTestCase): def test_echo(self): """ echo function """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.test_session.send_packet() detection_time = self.test_session.detect_mult *\ self.vpp_session.required_min_rx / USEC_IN_SEC # echo shouldn't work without echo source set - for dummy in range(3): - sleep = 0.75 * detection_time + for dummy in range(10): + sleep = self.vpp_session.required_min_rx / USEC_IN_SEC self.sleep(sleep, "delay before sending bfd packet") self.test_session.send_packet() p = wait_for_bfd_packet( @@ -1080,7 +1134,9 @@ class BFD4TestCase(VppTestCase): self.assert_equal(p[BFD].required_min_rx_interval, self.vpp_session.required_min_rx, "BFD required min rx interval") + self.test_session.send_packet() self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) + echo_seen = False # should be turned on - loopback echo packets for dummy in range(3): loop_until = time.time() + 0.75 * detection_time @@ -1098,9 +1154,12 @@ class BFD4TestCase(VppTestCase): p[Ether].dst = self.pg0.local_mac self.pg0.add_stream(p) self.pg_start() + echo_seen = True elif p.haslayer(BFD): - self.assertGreaterEqual(p[BFD].required_min_rx_interval, - 1000000) + if echo_seen: + self.assertGreaterEqual( + p[BFD].required_min_rx_interval, + 1000000) if "P" in p.sprintf("%BFD.flags%"): final = self.test_session.create_packet() final[BFD].flags = "F" @@ -1111,12 +1170,13 @@ class BFD4TestCase(VppTestCase): self.assert_equal(len(self.vapi.collect_events()), 0, "number of bfd events") self.test_session.send_packet() + self.assertTrue(echo_seen, "No echo packets received") @unittest.skipUnless(running_extended_tests(), "part of extended tests") def test_echo_fail(self): """ session goes down if echo function fails """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.test_session.send_packet() detection_time = self.test_session.detect_mult *\ self.vpp_session.required_min_rx / USEC_IN_SEC @@ -1156,7 +1216,7 @@ class BFD4TestCase(VppTestCase): def test_echo_stop(self): """ echo function stops if peer sets required min echo rx zero """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.test_session.send_packet() self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) # wait for first echo packet @@ -1188,7 +1248,7 @@ class BFD4TestCase(VppTestCase): def test_echo_source_removed(self): """ echo function stops if echo source is removed """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.test_session.send_packet() self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) # wait for first echo packet @@ -1220,7 +1280,7 @@ class BFD4TestCase(VppTestCase): def test_stale_echo(self): """ stale echo packets don't keep a session up """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) self.test_session.send_packet() # should be turned on - loopback echo packets @@ -1273,7 +1333,7 @@ class BFD4TestCase(VppTestCase): def test_invalid_echo_checksum(self): """ echo packets with invalid checksum don't keep a session up """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) self.test_session.send_packet() # should be turned on - loopback echo packets @@ -1395,7 +1455,22 @@ class BFD4TestCase(VppTestCase): self.assert_equal(count, 0, "number of packets received") self.assert_equal(len(events), 0, "number of events received") + def test_intf_deleted(self): + """ interface with bfd session deleted """ + intf = VppLoInterface(self) + intf.config_ip4() + intf.admin_up() + sw_if_index = intf.sw_if_index + vpp_session = VppBFDUDPSession(self, intf, intf.remote_ip4) + vpp_session.add_vpp_config() + vpp_session.admin_up() + intf.remove_vpp_config() + e = self.vapi.wait_for_event(1, "bfd_udp_session_details") + self.assert_equal(e.sw_if_index, sw_if_index, "sw_if_index") + self.assertFalse(vpp_session.query_vpp_config()) + +@unittest.skipUnless(running_extended_tests(), "part of extended tests") class BFD6TestCase(VppTestCase): """Bidirectional Forwarding Detection (BFD) (IPv6) """ @@ -1407,13 +1482,14 @@ class BFD6TestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFD6TestCase, cls).setUpClass() + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces([0]) cls.pg0.config_ip6() cls.pg0.configure_ipv6_neighbors() cls.pg0.admin_up() cls.pg0.resolve_ndp() - cls.create_loopback_interfaces([0]) + cls.create_loopback_interfaces(1) cls.loopback0 = cls.lo_interfaces[0] cls.loopback0.config_ip6() cls.loopback0.admin_up() @@ -1534,15 +1610,15 @@ class BFD6TestCase(VppTestCase): "ECHO packet identifier for test purposes)") def test_echo(self): - """ echo function used """ + """ echo function """ bfd_session_up(self) - self.test_session.update(required_min_echo_rx=50000) + self.test_session.update(required_min_echo_rx=150000) self.test_session.send_packet() detection_time = self.test_session.detect_mult *\ self.vpp_session.required_min_rx / USEC_IN_SEC # echo shouldn't work without echo source set - for dummy in range(3): - sleep = 0.75 * detection_time + for dummy in range(10): + sleep = self.vpp_session.required_min_rx / USEC_IN_SEC self.sleep(sleep, "delay before sending bfd packet") self.test_session.send_packet() p = wait_for_bfd_packet( @@ -1550,7 +1626,9 @@ class BFD6TestCase(VppTestCase): self.assert_equal(p[BFD].required_min_rx_interval, self.vpp_session.required_min_rx, "BFD required min rx interval") + self.test_session.send_packet() self.vapi.bfd_udp_set_echo_source(self.loopback0.sw_if_index) + echo_seen = False # should be turned on - loopback echo packets for dummy in range(3): loop_until = time.time() + 0.75 * detection_time @@ -1568,9 +1646,12 @@ class BFD6TestCase(VppTestCase): p[Ether].dst = self.pg0.local_mac self.pg0.add_stream(p) self.pg_start() + echo_seen = True elif p.haslayer(BFD): - self.assertGreaterEqual(p[BFD].required_min_rx_interval, - 1000000) + if echo_seen: + self.assertGreaterEqual( + p[BFD].required_min_rx_interval, + 1000000) if "P" in p.sprintf("%BFD.flags%"): final = self.test_session.create_packet() final[BFD].flags = "F" @@ -1581,8 +1662,25 @@ class BFD6TestCase(VppTestCase): self.assert_equal(len(self.vapi.collect_events()), 0, "number of bfd events") self.test_session.send_packet() + self.assertTrue(echo_seen, "No echo packets received") + + def test_intf_deleted(self): + """ interface with bfd session deleted """ + intf = VppLoInterface(self) + intf.config_ip6() + intf.admin_up() + sw_if_index = intf.sw_if_index + vpp_session = VppBFDUDPSession( + self, intf, intf.remote_ip6, af=AF_INET6) + vpp_session.add_vpp_config() + vpp_session.admin_up() + intf.remove_vpp_config() + e = self.vapi.wait_for_event(1, "bfd_udp_session_details") + self.assert_equal(e.sw_if_index, sw_if_index, "sw_if_index") + self.assertFalse(vpp_session.query_vpp_config()) +@unittest.skipUnless(running_extended_tests(), "part of extended tests") class BFDFIBTestCase(VppTestCase): """ BFD-FIB interactions (IPv6) """ @@ -1619,8 +1717,8 @@ class BFDFIBTestCase(VppTestCase): # packets to match against both of the routes p = [(Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / - IPv6(src="3001::1", dst="2001::1") / - UDP(sport=1234, dport=1234) / + IPv6(src="3001::1", dst="2001::1") / + UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)), (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IPv6(src="3001::1", dst="2002::1") / @@ -1632,12 +1730,12 @@ class BFDFIBTestCase(VppTestCase): ip_2001_s_64 = VppIpRoute(self, "2001::", 64, [VppRoutePath(self.pg0.remote_ip6, self.pg0.sw_if_index, - is_ip6=1)], + proto=DpoProto.DPO_PROTO_IP6)], is_ip6=1) ip_2002_s_64 = VppIpRoute(self, "2002::", 64, [VppRoutePath(self.pg0.remote_ip6, 0xffffffff, - is_ip6=1)], + proto=DpoProto.DPO_PROTO_IP6)], is_ip6=1) ip_2001_s_64.add_vpp_config() ip_2002_s_64.add_vpp_config() @@ -1684,6 +1782,7 @@ class BFDFIBTestCase(VppTestCase): packet[IPv6].dst) +@unittest.skipUnless(running_extended_tests(), "part of extended tests") class BFDSHA1TestCase(VppTestCase): """Bidirectional Forwarding Detection (BFD) (SHA1 auth) """ @@ -1695,6 +1794,7 @@ class BFDSHA1TestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFDSHA1TestCase, cls).setUpClass() + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces([0]) cls.pg0.config_ip4() @@ -1927,6 +2027,7 @@ class BFDAuthOnOffTestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFDAuthOnOffTestCase, cls).setUpClass() + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces([0]) cls.pg0.config_ip4() @@ -2132,7 +2233,7 @@ class BFDCLITestCase(VppTestCase): @classmethod def setUpClass(cls): super(BFDCLITestCase, cls).setUpClass() - + cls.vapi.cli("set log class bfd level debug") try: cls.create_pg_interfaces((0,)) cls.pg0.config_ip4() @@ -2506,7 +2607,7 @@ class BFDCLITestCase(VppTestCase): def test_set_del_udp_echo_source(self): """ set/del udp echo source """ - self.create_loopback_interfaces([0]) + self.create_loopback_interfaces(1) self.loopback0 = self.lo_interfaces[0] self.loopback0.admin_up() self.cli_verify_response("show bfd echo-source",