aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorDave Wallace <dwallacelf@gmail.com>2021-05-12 21:43:59 -0400
committerDamjan Marion <dmarion@me.com>2021-05-13 09:33:06 +0000
commiteddd8e3588561039985b27edf059db6033bfdfab (patch)
tree44896887d6070853ea77a18cae218f5d4ef4d93a /src/vnet
parentfd77f8c00c8e9d528d91a9cefae1878e383582ed (diff)
tests: move test source to vpp/test
- Generate copyright year and version instead of using hard-coded data Type: refactor Signed-off-by: Dave Wallace <dwallacelf@gmail.com> Change-Id: I6058f5025323b3aa483f5df4a2c4371e27b5914e
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/bfd/test/bfd.py423
-rw-r--r--src/vnet/bfd/test/test_bfd.py2763
-rw-r--r--src/vnet/bier/test/test_bier.py862
-rw-r--r--src/vnet/bier/test/vpp_bier.py293
-rw-r--r--src/vnet/bonding/test/test_bond.py321
-rw-r--r--src/vnet/bonding/test/vpp_bond_interface.py52
-rw-r--r--src/vnet/classify/test/test_classifier.py569
-rw-r--r--src/vnet/classify/test/test_classifier_ip6.py490
-rw-r--r--src/vnet/crypto/test/test_crypto.py28
-rw-r--r--src/vnet/fib/test/test_dvr.py410
-rw-r--r--src/vnet/fib/test/test_fib.py48
-rw-r--r--src/vnet/gre/test/test_gre.py1296
-rw-r--r--src/vnet/gso/test/test_gro.py142
-rw-r--r--src/vnet/gso/test/test_gso.py722
-rw-r--r--src/vnet/policer/test/test_policer.py117
-rw-r--r--src/vnet/policer/test/test_policer_input.py146
-rw-r--r--src/vnet/vxlan/test/test_vxlan.py421
-rw-r--r--src/vnet/vxlan/test/test_vxlan6.py316
-rw-r--r--src/vnet/vxlan/test/test_vxlan_gbp.py293
-rw-r--r--src/vnet/vxlan/test/test_vxlan_gpe.py265
-rw-r--r--src/vnet/vxlan/test/vpp_vxlan_gbp_tunnel.py75
-rw-r--r--src/vnet/vxlan/test/vpp_vxlan_tunnel.py87
22 files changed, 0 insertions, 10139 deletions
diff --git a/src/vnet/bfd/test/bfd.py b/src/vnet/bfd/test/bfd.py
deleted file mode 100644
index 9d44425ec9f..00000000000
--- a/src/vnet/bfd/test/bfd.py
+++ /dev/null
@@ -1,423 +0,0 @@
-""" BFD protocol implementation """
-
-from random import randint
-from socket import AF_INET, AF_INET6, inet_pton
-from scapy.all import bind_layers
-from scapy.layers.inet import UDP
-from scapy.packet import Packet
-from scapy.fields import BitField, BitEnumField, XByteField, FlagsField,\
- ConditionalField, StrField
-from vpp_object import VppObject
-from util import NumericConstant
-from vpp_papi import VppEnum
-
-
-class BFDDiagCode(NumericConstant):
- """ BFD Diagnostic Code """
- no_diagnostic = 0
- control_detection_time_expired = 1
- echo_function_failed = 2
- neighbor_signaled_session_down = 3
- forwarding_plane_reset = 4
- path_down = 5
- concatenated_path_down = 6
- administratively_down = 7
- reverse_concatenated_path_down = 8
-
- desc_dict = {
- no_diagnostic: "No diagnostic",
- control_detection_time_expired: "Control Detection Time Expired",
- echo_function_failed: "Echo Function Failed",
- neighbor_signaled_session_down: "Neighbor Signaled Session Down",
- forwarding_plane_reset: "Forwarding Plane Reset",
- path_down: "Path Down",
- concatenated_path_down: "Concatenated Path Down",
- administratively_down: "Administratively Down",
- reverse_concatenated_path_down: "Reverse Concatenated Path Down",
- }
-
-
-class BFDState(NumericConstant):
- """ BFD State """
- admin_down = 0
- down = 1
- init = 2
- up = 3
-
- desc_dict = {
- admin_down: "AdminDown",
- down: "Down",
- init: "Init",
- up: "Up",
- }
-
-
-class BFDAuthType(NumericConstant):
- """ BFD Authentication Type """
- no_auth = 0
- simple_pwd = 1
- keyed_md5 = 2
- meticulous_keyed_md5 = 3
- keyed_sha1 = 4
- meticulous_keyed_sha1 = 5
-
- desc_dict = {
- no_auth: "No authentication",
- simple_pwd: "Simple Password",
- keyed_md5: "Keyed MD5",
- meticulous_keyed_md5: "Meticulous Keyed MD5",
- keyed_sha1: "Keyed SHA1",
- meticulous_keyed_sha1: "Meticulous Keyed SHA1",
- }
-
-
-def bfd_is_auth_used(pkt):
- """ is packet authenticated? """
- return "A" in pkt.sprintf("%BFD.flags%")
-
-
-def bfd_is_simple_pwd_used(pkt):
- """ is simple password authentication used? """
- return bfd_is_auth_used(pkt) and pkt.auth_type == BFDAuthType.simple_pwd
-
-
-def bfd_is_sha1_used(pkt):
- """ is sha1 authentication used? """
- return bfd_is_auth_used(pkt) and pkt.auth_type in \
- (BFDAuthType.keyed_sha1, BFDAuthType.meticulous_keyed_sha1)
-
-
-def bfd_is_md5_used(pkt):
- """ is md5 authentication used? """
- return bfd_is_auth_used(pkt) and pkt.auth_type in \
- (BFDAuthType.keyed_md5, BFDAuthType.meticulous_keyed_md5)
-
-
-def bfd_is_md5_or_sha1_used(pkt):
- """ is md5 or sha1 used? """
- return bfd_is_md5_used(pkt) or bfd_is_sha1_used(pkt)
-
-
-class BFD(Packet):
- """ BFD protocol layer for scapy """
-
- udp_dport = 3784 #: BFD destination port per RFC 5881
- udp_dport_echo = 3785 # : BFD destination port for ECHO per RFC 5881
- udp_sport_min = 49152 #: BFD source port min value per RFC 5881
- udp_sport_max = 65535 #: BFD source port max value per RFC 5881
- bfd_pkt_len = 24 # : length of BFD pkt without authentication section
- sha1_auth_len = 28 # : length of authentication section if SHA1 used
-
- name = "BFD"
-
- fields_desc = [
- BitField("version", 1, 3),
- BitEnumField("diag", 0, 5, BFDDiagCode.desc_dict),
- BitEnumField("state", 0, 2, BFDState.desc_dict),
- FlagsField("flags", 0, 6, ['M', 'D', 'A', 'C', 'F', 'P']),
- XByteField("detect_mult", 0),
- BitField("length", bfd_pkt_len, 8),
- BitField("my_discriminator", 0, 32),
- BitField("your_discriminator", 0, 32),
- BitField("desired_min_tx_interval", 0, 32),
- BitField("required_min_rx_interval", 0, 32),
- BitField("required_min_echo_rx_interval", 0, 32),
- ConditionalField(
- BitEnumField("auth_type", 0, 8, BFDAuthType.desc_dict),
- bfd_is_auth_used),
- ConditionalField(BitField("auth_len", 0, 8), bfd_is_auth_used),
- ConditionalField(BitField("auth_key_id", 0, 8), bfd_is_auth_used),
- ConditionalField(BitField("auth_reserved", 0, 8),
- bfd_is_md5_or_sha1_used),
- ConditionalField(
- BitField("auth_seq_num", 0, 32), bfd_is_md5_or_sha1_used),
- ConditionalField(StrField("auth_key_hash", "0" * 16), bfd_is_md5_used),
- ConditionalField(
- StrField("auth_key_hash", "0" * 20), bfd_is_sha1_used),
- ]
-
- def mysummary(self):
- return self.sprintf("BFD(my_disc=%BFD.my_discriminator%,"
- "your_disc=%BFD.your_discriminator%)")
-
-
-# glue the BFD packet class to scapy parser
-bind_layers(UDP, BFD, dport=BFD.udp_dport)
-
-
-class BFD_vpp_echo(Packet):
- """ BFD echo packet as used by VPP (non-rfc, as rfc doesn't define one) """
-
- udp_dport = 3785 #: BFD echo destination port per RFC 5881
- name = "BFD_VPP_ECHO"
-
- fields_desc = [
- BitField("discriminator", 0, 32),
- BitField("expire_time_clocks", 0, 64),
- BitField("checksum", 0, 64)
- ]
-
- def mysummary(self):
- return self.sprintf(
- "BFD_VPP_ECHO(disc=%BFD_VPP_ECHO.discriminator%,"
- "expire_time_clocks=%BFD_VPP_ECHO.expire_time_clocks%)")
-
-
-# glue the BFD echo packet class to scapy parser
-bind_layers(UDP, BFD_vpp_echo, dport=BFD_vpp_echo.udp_dport)
-
-
-class VppBFDAuthKey(VppObject):
- """ Represents BFD authentication key in VPP """
-
- def __init__(self, test, conf_key_id, auth_type, key):
- self._test = test
- self._key = key
- self._auth_type = auth_type
- test.assertIn(auth_type, BFDAuthType.desc_dict)
- self._conf_key_id = conf_key_id
-
- @property
- def test(self):
- """ Test which created this key """
- return self._test
-
- @property
- def auth_type(self):
- """ Authentication type for this key """
- return self._auth_type
-
- @property
- def key(self):
- """ key data """
- return self._key
-
- @key.setter
- def key(self, value):
- self._key = value
-
- @property
- def conf_key_id(self):
- """ configuration key ID """
- return self._conf_key_id
-
- def add_vpp_config(self):
- self.test.vapi.bfd_auth_set_key(
- conf_key_id=self._conf_key_id, auth_type=self._auth_type,
- key=self._key, key_len=len(self._key))
- self._test.registry.register(self, self.test.logger)
-
- def get_bfd_auth_keys_dump_entry(self):
- """ get the entry in the auth keys dump corresponding to this key """
- result = self.test.vapi.bfd_auth_keys_dump()
- for k in result:
- if k.conf_key_id == self._conf_key_id:
- return k
- return None
-
- def query_vpp_config(self):
- return self.get_bfd_auth_keys_dump_entry() is not None
-
- def remove_vpp_config(self):
- self.test.vapi.bfd_auth_del_key(conf_key_id=self._conf_key_id)
-
- def object_id(self):
- return "bfd-auth-key-%s" % self._conf_key_id
-
-
-class VppBFDUDPSession(VppObject):
- """ Represents BFD UDP session in VPP """
-
- def __init__(self, test, interface, peer_addr, local_addr=None, af=AF_INET,
- desired_min_tx=300000, required_min_rx=300000, detect_mult=3,
- sha1_key=None, bfd_key_id=None, is_tunnel=False):
- self._test = test
- self._interface = interface
- self._af = af
- if local_addr:
- self._local_addr = local_addr
- else:
- self._local_addr = None
- self._peer_addr = peer_addr
- self._desired_min_tx = desired_min_tx
- self._required_min_rx = required_min_rx
- self._detect_mult = detect_mult
- self._sha1_key = sha1_key
- if bfd_key_id is not None:
- self._bfd_key_id = bfd_key_id
- else:
- self._bfd_key_id = randint(0, 255)
- self._is_tunnel = is_tunnel
-
- @property
- def test(self):
- """ Test which created this session """
- return self._test
-
- @property
- def interface(self):
- """ Interface on which this session lives """
- return self._interface
-
- @property
- def af(self):
- """ Address family - AF_INET or AF_INET6 """
- return self._af
-
- @property
- def local_addr(self):
- """ BFD session local address (VPP address) """
- if self._local_addr is None:
- if self.af == AF_INET:
- return self._interface.local_ip4
- elif self.af == AF_INET6:
- return self._interface.local_ip6
- else:
- raise Exception("Unexpected af '%s'" % self.af)
- return self._local_addr
-
- @property
- def peer_addr(self):
- """ BFD session peer address """
- return self._peer_addr
-
- def get_bfd_udp_session_dump_entry(self):
- """ get the namedtuple entry from bfd udp session dump """
- result = self.test.vapi.bfd_udp_session_dump()
- for s in result:
- self.test.logger.debug("session entry: %s" % str(s))
- if s.sw_if_index == self.interface.sw_if_index:
- if self.af == AF_INET \
- and self.interface.local_ip4 == str(s.local_addr) \
- and self.interface.remote_ip4 == str(s.peer_addr):
- return s
- if self.af == AF_INET6 \
- and self.interface.local_ip6 == str(s.local_addr) \
- and self.interface.remote_ip6 == str(s.peer_addr):
- return s
- return None
-
- @property
- def state(self):
- """ BFD session state """
- session = self.get_bfd_udp_session_dump_entry()
- if session is None:
- raise Exception("Could not find BFD session in VPP response")
- return session.state
-
- @property
- def desired_min_tx(self):
- """ desired minimum tx interval """
- return self._desired_min_tx
-
- @property
- def required_min_rx(self):
- """ required minimum rx interval """
- return self._required_min_rx
-
- @property
- def detect_mult(self):
- """ detect multiplier """
- return self._detect_mult
-
- @property
- def sha1_key(self):
- """ sha1 key """
- return self._sha1_key
-
- @property
- def bfd_key_id(self):
- """ bfd key id in use """
- return self._bfd_key_id
-
- @property
- def is_tunnel(self):
- return self._is_tunnel
-
- def activate_auth(self, key, bfd_key_id=None, delayed=False):
- """ activate authentication for this session """
- self._bfd_key_id = bfd_key_id if bfd_key_id else randint(0, 255)
- self._sha1_key = key
- conf_key_id = self._sha1_key.conf_key_id
- is_delayed = 1 if delayed else 0
- self.test.vapi.bfd_udp_auth_activate(
- sw_if_index=self._interface.sw_if_index,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr,
- bfd_key_id=self._bfd_key_id,
- conf_key_id=conf_key_id,
- is_delayed=is_delayed)
-
- def deactivate_auth(self, delayed=False):
- """ deactivate authentication """
- self._bfd_key_id = None
- self._sha1_key = None
- is_delayed = 1 if delayed else 0
- self.test.vapi.bfd_udp_auth_deactivate(
- sw_if_index=self._interface.sw_if_index,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr,
- is_delayed=is_delayed)
-
- def modify_parameters(self,
- detect_mult=None,
- desired_min_tx=None,
- required_min_rx=None):
- """ modify session parameters """
- if detect_mult:
- self._detect_mult = detect_mult
- if desired_min_tx:
- self._desired_min_tx = desired_min_tx
- if required_min_rx:
- self._required_min_rx = required_min_rx
- self.test.vapi.bfd_udp_mod(sw_if_index=self._interface.sw_if_index,
- desired_min_tx=self.desired_min_tx,
- required_min_rx=self.required_min_rx,
- detect_mult=self.detect_mult,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr)
-
- def add_vpp_config(self):
- bfd_key_id = self._bfd_key_id if self._sha1_key else None
- conf_key_id = self._sha1_key.conf_key_id if self._sha1_key else None
- is_authenticated = True if self._sha1_key else False
- self.test.vapi.bfd_udp_add(sw_if_index=self._interface.sw_if_index,
- desired_min_tx=self.desired_min_tx,
- required_min_rx=self.required_min_rx,
- detect_mult=self.detect_mult,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr,
- bfd_key_id=bfd_key_id,
- conf_key_id=conf_key_id,
- is_authenticated=is_authenticated)
- self._test.registry.register(self, self.test.logger)
-
- def query_vpp_config(self):
- session = self.get_bfd_udp_session_dump_entry()
- return session is not None
-
- def remove_vpp_config(self):
- self.test.vapi.bfd_udp_del(self._interface.sw_if_index,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr)
-
- def object_id(self):
- return "bfd-udp-%s-%s-%s-%s" % (self._interface.sw_if_index,
- self.local_addr,
- self.peer_addr,
- self.af)
-
- def admin_up(self):
- """ set bfd session admin-up """
- self.test.vapi.bfd_udp_session_set_flags(
- flags=VppEnum.vl_api_if_status_flags_t.IF_STATUS_API_FLAG_ADMIN_UP,
- sw_if_index=self._interface.sw_if_index,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr)
-
- def admin_down(self):
- """ set bfd session admin-down """
- self.test.vapi.bfd_udp_session_set_flags(
- flags=0, sw_if_index=self._interface.sw_if_index,
- local_addr=self.local_addr,
- peer_addr=self.peer_addr)
diff --git a/src/vnet/bfd/test/test_bfd.py b/src/vnet/bfd/test/test_bfd.py
deleted file mode 100644
index 01b468c8e27..00000000000
--- a/src/vnet/bfd/test/test_bfd.py
+++ /dev/null
@@ -1,2763 +0,0 @@
-#!/usr/bin/env python3
-""" BFD tests """
-
-from __future__ import division
-
-import binascii
-import hashlib
-import ipaddress
-import reprlib
-import time
-import unittest
-from random import randint, shuffle, getrandbits
-from socket import AF_INET, AF_INET6, inet_ntop
-from struct import pack, unpack
-
-import scapy.compat
-from scapy.layers.inet import UDP, IP
-from scapy.layers.inet6 import IPv6
-from scapy.layers.l2 import Ether, GRE
-from scapy.packet import Raw
-
-from bfd import VppBFDAuthKey, BFD, BFDAuthType, VppBFDUDPSession, \
- BFDDiagCode, BFDState, BFD_vpp_echo
-from framework import tag_fixme_vpp_workers
-from framework import VppTestCase, VppTestRunner, running_extended_tests
-from framework import tag_run_solo
-from util import ppp
-from vpp_ip import DpoProto
-from vpp_ip_route import VppIpRoute, VppRoutePath
-from vpp_lo_interface import VppLoInterface
-from vpp_papi_provider import UnexpectedApiReturnValueError, \
- CliFailedCommandError
-from vpp_pg_interface import CaptureTimeoutError, is_ipv6_misc
-from vpp_gre_interface import VppGreInterface
-from vpp_papi import VppEnum
-
-USEC_IN_SEC = 1000000
-
-
-class AuthKeyFactory(object):
- """Factory class for creating auth keys with unique conf key ID"""
-
- def __init__(self):
- self._conf_key_ids = {}
-
- def create_random_key(self, test, auth_type=BFDAuthType.keyed_sha1):
- """ create a random key with unique conf key id """
- conf_key_id = randint(0, 0xFFFFFFFF)
- while conf_key_id in self._conf_key_ids:
- conf_key_id = randint(0, 0xFFFFFFFF)
- self._conf_key_ids[conf_key_id] = 1
- key = scapy.compat.raw(
- bytearray([randint(0, 255) for _ in range(randint(1, 20))]))
- return VppBFDAuthKey(test=test, auth_type=auth_type,
- conf_key_id=conf_key_id, key=key)
-
-
-class BFDAPITestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD) - API"""
-
- pg0 = None
- pg1 = None
-
- @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:
- i.config_ip4()
- i.config_ip6()
- i.resolve_arp()
-
- except Exception:
- super(BFDAPITestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFDAPITestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDAPITestCase, self).setUp()
- self.factory = AuthKeyFactory()
-
- def test_add_bfd(self):
- """ create a BFD session """
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
-
- def test_double_add(self):
- """ create the same BFD session twice (negative case) """
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- session.add_vpp_config()
-
- with self.vapi.assert_negative_api_retval():
- session.add_vpp_config()
-
- session.remove_vpp_config()
-
- def test_add_bfd6(self):
- """ create IPv6 BFD session """
- session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip6, af=AF_INET6)
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
-
- def test_mod_bfd(self):
- """ modify BFD session parameters """
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- desired_min_tx=50000,
- required_min_rx=10000,
- detect_mult=1)
- session.add_vpp_config()
- s = session.get_bfd_udp_session_dump_entry()
- self.assert_equal(session.desired_min_tx,
- s.desired_min_tx,
- "desired min transmit interval")
- self.assert_equal(session.required_min_rx,
- s.required_min_rx,
- "required min receive interval")
- self.assert_equal(session.detect_mult, s.detect_mult, "detect mult")
- session.modify_parameters(desired_min_tx=session.desired_min_tx * 2,
- required_min_rx=session.required_min_rx * 2,
- detect_mult=session.detect_mult * 2)
- s = session.get_bfd_udp_session_dump_entry()
- self.assert_equal(session.desired_min_tx,
- s.desired_min_tx,
- "desired min transmit interval")
- self.assert_equal(session.required_min_rx,
- s.required_min_rx,
- "required min receive interval")
- self.assert_equal(session.detect_mult, s.detect_mult, "detect mult")
-
- def test_add_sha1_keys(self):
- """ add SHA1 keys """
- key_count = 10
- keys = [self.factory.create_random_key(
- self) for i in range(0, key_count)]
- for key in keys:
- self.assertFalse(key.query_vpp_config())
- for key in keys:
- key.add_vpp_config()
- for key in keys:
- self.assertTrue(key.query_vpp_config())
- # remove randomly
- indexes = list(range(key_count))
- shuffle(indexes)
- removed = []
- for i in indexes:
- key = keys[i]
- key.remove_vpp_config()
- removed.append(i)
- for j in range(key_count):
- key = keys[j]
- if j in removed:
- self.assertFalse(key.query_vpp_config())
- else:
- self.assertTrue(key.query_vpp_config())
- # should be removed now
- for key in keys:
- self.assertFalse(key.query_vpp_config())
- # add back and remove again
- for key in keys:
- key.add_vpp_config()
- for key in keys:
- self.assertTrue(key.query_vpp_config())
- for key in keys:
- key.remove_vpp_config()
- for key in keys:
- self.assertFalse(key.query_vpp_config())
-
- def test_add_bfd_sha1(self):
- """ create a BFD session (SHA1) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key)
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
- session.add_vpp_config()
- self.logger.debug("Session state is %s", session.state)
- session.remove_vpp_config()
-
- def test_double_add_sha1(self):
- """ create the same BFD session twice (negative case) (SHA1) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key)
- session.add_vpp_config()
- with self.assertRaises(Exception):
- session.add_vpp_config()
-
- def test_add_auth_nonexistent_key(self):
- """ create BFD session using non-existent SHA1 (negative case) """
- session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4,
- sha1_key=self.factory.create_random_key(self))
- with self.assertRaises(Exception):
- session.add_vpp_config()
-
- def test_shared_sha1_key(self):
- """ share single SHA1 key between multiple BFD sessions """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- sessions = [
- VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key),
- VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip6,
- sha1_key=key, af=AF_INET6),
- VppBFDUDPSession(self, self.pg1, self.pg1.remote_ip4,
- sha1_key=key),
- VppBFDUDPSession(self, self.pg1, self.pg1.remote_ip6,
- sha1_key=key, af=AF_INET6)]
- for s in sessions:
- s.add_vpp_config()
- removed = 0
- for s in sessions:
- e = key.get_bfd_auth_keys_dump_entry()
- self.assert_equal(e.use_count, len(sessions) - removed,
- "Use count for shared key")
- s.remove_vpp_config()
- removed += 1
- e = key.get_bfd_auth_keys_dump_entry()
- self.assert_equal(e.use_count, len(sessions) - removed,
- "Use count for shared key")
-
- def test_activate_auth(self):
- """ activate SHA1 authentication """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- session.add_vpp_config()
- session.activate_auth(key)
-
- def test_deactivate_auth(self):
- """ deactivate SHA1 authentication """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- session.add_vpp_config()
- session.activate_auth(key)
- session.deactivate_auth()
-
- def test_change_key(self):
- """ change SHA1 key """
- key1 = self.factory.create_random_key(self)
- key2 = self.factory.create_random_key(self)
- while key2.conf_key_id == key1.conf_key_id:
- key2 = self.factory.create_random_key(self)
- key1.add_vpp_config()
- key2.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key1)
- 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(
- sw_if_index=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()
- echo_ip4 = ipaddress.IPv4Address(int(ipaddress.IPv4Address(
- self.loopback0.local_ip4)) ^ 1).packed
- 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.packed, echo_ip4)
- self.assertFalse(echo_source.have_usable_ip6)
-
- self.loopback0.config_ip6()
- echo_ip6 = ipaddress.IPv6Address(int(ipaddress.IPv6Address(
- self.loopback0.local_ip6)) ^ 1).packed
-
- 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.packed, echo_ip4)
- self.assertTrue(echo_source.have_usable_ip6)
- self.assertEqual(echo_source.ip6_addr.packed, 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)
-
-
-class BFDTestSession(object):
- """ BFD session as seen from test framework side """
-
- def __init__(self, test, interface, af, detect_mult=3, sha1_key=None,
- bfd_key_id=None, our_seq_number=None,
- tunnel_header=None, phy_interface=None):
- self.test = test
- self.af = af
- self.sha1_key = sha1_key
- self.bfd_key_id = bfd_key_id
- self.interface = interface
- if phy_interface:
- self.phy_interface = phy_interface
- else:
- self.phy_interface = self.interface
- self.udp_sport = randint(49152, 65535)
- if our_seq_number is None:
- self.our_seq_number = randint(0, 40000000)
- else:
- self.our_seq_number = our_seq_number
- self.vpp_seq_number = None
- self.my_discriminator = 0
- self.desired_min_tx = 300000
- self.required_min_rx = 300000
- self.required_min_echo_rx = None
- self.detect_mult = detect_mult
- self.diag = BFDDiagCode.no_diagnostic
- self.your_discriminator = None
- self.state = BFDState.down
- self.auth_type = BFDAuthType.no_auth
- self.tunnel_header = tunnel_header
-
- def inc_seq_num(self):
- """ increment sequence number, wrapping if needed """
- if self.our_seq_number == 0xFFFFFFFF:
- self.our_seq_number = 0
- else:
- self.our_seq_number += 1
-
- def update(self, my_discriminator=None, your_discriminator=None,
- desired_min_tx=None, required_min_rx=None,
- required_min_echo_rx=None, detect_mult=None,
- diag=None, state=None, auth_type=None):
- """ update BFD parameters associated with session """
- if my_discriminator is not None:
- self.my_discriminator = my_discriminator
- if your_discriminator is not None:
- self.your_discriminator = your_discriminator
- if required_min_rx is not None:
- self.required_min_rx = required_min_rx
- if required_min_echo_rx is not None:
- self.required_min_echo_rx = required_min_echo_rx
- if desired_min_tx is not None:
- self.desired_min_tx = desired_min_tx
- if detect_mult is not None:
- self.detect_mult = detect_mult
- if diag is not None:
- self.diag = diag
- if state is not None:
- self.state = state
- if auth_type is not None:
- self.auth_type = auth_type
-
- def fill_packet_fields(self, packet):
- """ set packet fields with known values in packet """
- bfd = packet[BFD]
- if self.my_discriminator:
- self.test.logger.debug("BFD: setting packet.my_discriminator=%s",
- self.my_discriminator)
- bfd.my_discriminator = self.my_discriminator
- if self.your_discriminator:
- self.test.logger.debug("BFD: setting packet.your_discriminator=%s",
- self.your_discriminator)
- bfd.your_discriminator = self.your_discriminator
- if self.required_min_rx:
- self.test.logger.debug(
- "BFD: setting packet.required_min_rx_interval=%s",
- self.required_min_rx)
- bfd.required_min_rx_interval = self.required_min_rx
- if self.required_min_echo_rx:
- self.test.logger.debug(
- "BFD: setting packet.required_min_echo_rx=%s",
- self.required_min_echo_rx)
- bfd.required_min_echo_rx_interval = self.required_min_echo_rx
- if self.desired_min_tx:
- self.test.logger.debug(
- "BFD: setting packet.desired_min_tx_interval=%s",
- self.desired_min_tx)
- bfd.desired_min_tx_interval = self.desired_min_tx
- if self.detect_mult:
- self.test.logger.debug(
- "BFD: setting packet.detect_mult=%s", self.detect_mult)
- bfd.detect_mult = self.detect_mult
- if self.diag:
- self.test.logger.debug("BFD: setting packet.diag=%s", self.diag)
- bfd.diag = self.diag
- if self.state:
- self.test.logger.debug("BFD: setting packet.state=%s", self.state)
- bfd.state = self.state
- if self.auth_type:
- # this is used by a negative test-case
- self.test.logger.debug("BFD: setting packet.auth_type=%s",
- self.auth_type)
- bfd.auth_type = self.auth_type
-
- def create_packet(self):
- """ create a BFD packet, reflecting the current state of session """
- if self.sha1_key:
- bfd = BFD(flags="A")
- bfd.auth_type = self.sha1_key.auth_type
- bfd.auth_len = BFD.sha1_auth_len
- bfd.auth_key_id = self.bfd_key_id
- bfd.auth_seq_num = self.our_seq_number
- bfd.length = BFD.sha1_auth_len + BFD.bfd_pkt_len
- else:
- bfd = BFD()
- packet = Ether(src=self.phy_interface.remote_mac,
- dst=self.phy_interface.local_mac)
- if self.tunnel_header:
- packet = packet / self.tunnel_header
- if self.af == AF_INET6:
- packet = (packet /
- IPv6(src=self.interface.remote_ip6,
- dst=self.interface.local_ip6,
- hlim=255) /
- UDP(sport=self.udp_sport, dport=BFD.udp_dport) /
- bfd)
- else:
- packet = (packet /
- IP(src=self.interface.remote_ip4,
- dst=self.interface.local_ip4,
- ttl=255) /
- UDP(sport=self.udp_sport, dport=BFD.udp_dport) /
- bfd)
- self.test.logger.debug("BFD: Creating packet")
- self.fill_packet_fields(packet)
- if self.sha1_key:
- hash_material = scapy.compat.raw(
- packet[BFD])[:32] + self.sha1_key.key + \
- b"\0" * (20 - len(self.sha1_key.key))
- self.test.logger.debug("BFD: Calculated SHA1 hash: %s" %
- hashlib.sha1(hash_material).hexdigest())
- packet[BFD].auth_key_hash = hashlib.sha1(hash_material).digest()
- return packet
-
- def send_packet(self, packet=None, interface=None):
- """ send packet on interface, creating the packet if needed """
- if packet is None:
- packet = self.create_packet()
- if interface is None:
- interface = self.phy_interface
- self.test.logger.debug(ppp("Sending packet:", packet))
- interface.add_stream(packet)
- self.test.pg_start()
-
- def verify_sha1_auth(self, packet):
- """ Verify correctness of authentication in BFD layer. """
- bfd = packet[BFD]
- self.test.assert_equal(bfd.auth_len, 28, "Auth section length")
- self.test.assert_equal(bfd.auth_type, self.sha1_key.auth_type,
- BFDAuthType)
- self.test.assert_equal(bfd.auth_key_id, self.bfd_key_id, "Key ID")
- self.test.assert_equal(bfd.auth_reserved, 0, "Reserved")
- if self.vpp_seq_number is None:
- self.vpp_seq_number = bfd.auth_seq_num
- self.test.logger.debug("Received initial sequence number: %s" %
- self.vpp_seq_number)
- else:
- recvd_seq_num = bfd.auth_seq_num
- self.test.logger.debug("Received followup sequence number: %s" %
- recvd_seq_num)
- if self.vpp_seq_number < 0xffffffff:
- if self.sha1_key.auth_type == \
- BFDAuthType.meticulous_keyed_sha1:
- self.test.assert_equal(recvd_seq_num,
- self.vpp_seq_number + 1,
- "BFD sequence number")
- else:
- self.test.assert_in_range(recvd_seq_num,
- self.vpp_seq_number,
- self.vpp_seq_number + 1,
- "BFD sequence number")
- else:
- if self.sha1_key.auth_type == \
- BFDAuthType.meticulous_keyed_sha1:
- self.test.assert_equal(recvd_seq_num, 0,
- "BFD sequence number")
- else:
- self.test.assertIn(recvd_seq_num, (self.vpp_seq_number, 0),
- "BFD sequence number not one of "
- "(%s, 0)" % self.vpp_seq_number)
- self.vpp_seq_number = recvd_seq_num
- # last 20 bytes represent the hash - so replace them with the key,
- # pad the result with zeros and hash the result
- hash_material = bfd.original[:-20] + self.sha1_key.key + \
- b"\0" * (20 - len(self.sha1_key.key))
- expected_hash = hashlib.sha1(hash_material).hexdigest()
- self.test.assert_equal(binascii.hexlify(bfd.auth_key_hash),
- expected_hash.encode(), "Auth key hash")
-
- def verify_bfd(self, packet):
- """ Verify correctness of BFD layer. """
- bfd = packet[BFD]
- self.test.assert_equal(bfd.version, 1, "BFD version")
- self.test.assert_equal(bfd.your_discriminator,
- self.my_discriminator,
- "BFD - your discriminator")
- if self.sha1_key:
- self.verify_sha1_auth(packet)
-
-
-def bfd_session_up(test):
- """ Bring BFD session up """
- test.logger.info("BFD: Waiting for slow hello")
- p = wait_for_bfd_packet(test, 2, is_tunnel=test.vpp_session.is_tunnel)
- old_offset = None
- if hasattr(test, 'vpp_clock_offset'):
- old_offset = test.vpp_clock_offset
- test.vpp_clock_offset = time.time() - float(p.time)
- test.logger.debug("BFD: Calculated vpp clock offset: %s",
- test.vpp_clock_offset)
- if old_offset:
- test.assertAlmostEqual(
- old_offset, test.vpp_clock_offset, delta=0.5,
- msg="vpp clock offset not stable (new: %s, old: %s)" %
- (test.vpp_clock_offset, old_offset))
- test.logger.info("BFD: Sending Init")
- test.test_session.update(my_discriminator=randint(0, 40000000),
- your_discriminator=p[BFD].my_discriminator,
- state=BFDState.init)
- if test.test_session.sha1_key and test.test_session.sha1_key.auth_type == \
- BFDAuthType.meticulous_keyed_sha1:
- test.test_session.inc_seq_num()
- test.test_session.send_packet()
- test.logger.info("BFD: Waiting for event")
- e = test.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(test, e, expected_state=BFDState.up)
- test.logger.info("BFD: Session is Up")
- test.test_session.update(state=BFDState.up)
- if test.test_session.sha1_key and test.test_session.sha1_key.auth_type == \
- BFDAuthType.meticulous_keyed_sha1:
- test.test_session.inc_seq_num()
- test.test_session.send_packet()
- test.assert_equal(test.vpp_session.state, BFDState.up, BFDState)
-
-
-def bfd_session_down(test):
- """ Bring BFD session down """
- test.assert_equal(test.vpp_session.state, BFDState.up, BFDState)
- test.test_session.update(state=BFDState.down)
- if test.test_session.sha1_key and test.test_session.sha1_key.auth_type == \
- BFDAuthType.meticulous_keyed_sha1:
- test.test_session.inc_seq_num()
- test.test_session.send_packet()
- test.logger.info("BFD: Waiting for event")
- e = test.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(test, e, expected_state=BFDState.down)
- test.logger.info("BFD: Session is Down")
- test.assert_equal(test.vpp_session.state, BFDState.down, BFDState)
-
-
-def verify_bfd_session_config(test, session, state=None):
- dump = session.get_bfd_udp_session_dump_entry()
- test.assertIsNotNone(dump)
- # since dump is not none, we have verified that sw_if_index and addresses
- # are valid (in get_bfd_udp_session_dump_entry)
- if state:
- test.assert_equal(dump.state, state, "session state")
- test.assert_equal(dump.required_min_rx, session.required_min_rx,
- "required min rx interval")
- test.assert_equal(dump.desired_min_tx, session.desired_min_tx,
- "desired min tx interval")
- test.assert_equal(dump.detect_mult, session.detect_mult,
- "detect multiplier")
- if session.sha1_key is None:
- test.assert_equal(dump.is_authenticated, 0, "is_authenticated flag")
- else:
- test.assert_equal(dump.is_authenticated, 1, "is_authenticated flag")
- test.assert_equal(dump.bfd_key_id, session.bfd_key_id,
- "bfd key id")
- test.assert_equal(dump.conf_key_id,
- session.sha1_key.conf_key_id,
- "config key id")
-
-
-def verify_ip(test, packet):
- """ Verify correctness of IP layer. """
- if test.vpp_session.af == AF_INET6:
- ip = packet[IPv6]
- local_ip = test.vpp_session.interface.local_ip6
- remote_ip = test.vpp_session.interface.remote_ip6
- test.assert_equal(ip.hlim, 255, "IPv6 hop limit")
- else:
- ip = packet[IP]
- local_ip = test.vpp_session.interface.local_ip4
- remote_ip = test.vpp_session.interface.remote_ip4
- test.assert_equal(ip.ttl, 255, "IPv4 TTL")
- test.assert_equal(ip.src, local_ip, "IP source address")
- test.assert_equal(ip.dst, remote_ip, "IP destination address")
-
-
-def verify_udp(test, packet):
- """ Verify correctness of UDP layer. """
- udp = packet[UDP]
- test.assert_equal(udp.dport, BFD.udp_dport, "UDP destination port")
- test.assert_in_range(udp.sport, BFD.udp_sport_min, BFD.udp_sport_max,
- "UDP source port")
-
-
-def verify_event(test, event, expected_state):
- """ Verify correctness of event values. """
- e = event
- test.logger.debug("BFD: Event: %s" % reprlib.repr(e))
- test.assert_equal(e.sw_if_index,
- test.vpp_session.interface.sw_if_index,
- "BFD interface index")
-
- test.assert_equal(str(e.local_addr), test.vpp_session.local_addr,
- "Local IPv6 address")
- test.assert_equal(str(e.peer_addr), test.vpp_session.peer_addr,
- "Peer IPv6 address")
- test.assert_equal(e.state, expected_state, BFDState)
-
-
-def wait_for_bfd_packet(test, timeout=1, pcap_time_min=None, is_tunnel=False):
- """ wait for BFD packet and verify its correctness
-
- :param timeout: how long to wait
- :param pcap_time_min: ignore packets with pcap timestamp lower than this
-
- :returns: tuple (packet, time spent waiting for packet)
- """
- test.logger.info("BFD: Waiting for BFD packet")
- deadline = time.time() + timeout
- counter = 0
- while True:
- counter += 1
- # sanity check
- test.assert_in_range(counter, 0, 100, "number of packets ignored")
- time_left = deadline - time.time()
- if time_left < 0:
- raise CaptureTimeoutError("Packet did not arrive within timeout")
- p = test.pg0.wait_for_packet(timeout=time_left)
- test.logger.debug(ppp("BFD: Got packet:", p))
- if pcap_time_min is not None and p.time < pcap_time_min:
- test.logger.debug(ppp("BFD: ignoring packet (pcap time %s < "
- "pcap time min %s):" %
- (p.time, pcap_time_min), p))
- else:
- break
- if is_tunnel:
- # strip an IP layer and move to the next
- p = p[IP].payload
-
- bfd = p[BFD]
- if bfd is None:
- raise Exception(ppp("Unexpected or invalid BFD packet:", p))
- if bfd.payload:
- raise Exception(ppp("Unexpected payload in BFD packet:", bfd))
- verify_ip(test, p)
- verify_udp(test, p)
- test.test_session.verify_bfd(p)
- return p
-
-
-@tag_run_solo
-class BFD4TestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD)"""
-
- pg0 = None
- vpp_clock_offset = None
- vpp_session = None
- test_session = None
-
- @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(1)
- cls.loopback0 = cls.lo_interfaces[0]
- cls.loopback0.config_ip4()
- cls.loopback0.admin_up()
- cls.pg0.config_ip4()
- cls.pg0.configure_ipv4_neighbors()
- cls.pg0.admin_up()
- cls.pg0.resolve_arp()
-
- except Exception:
- super(BFD4TestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFD4TestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFD4TestCase, self).setUp()
- self.factory = AuthKeyFactory()
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
- try:
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(self, self.pg0, AF_INET)
- except BaseException:
- self.vapi.want_bfd_events(enable_disable=0)
- raise
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=0)
- self.vapi.collect_events() # clear the event queue
- super(BFD4TestCase, self).tearDown()
-
- def test_session_up(self):
- """ bring BFD session up """
- bfd_session_up(self)
-
- def test_session_up_by_ip(self):
- """ bring BFD session up - first frame looked up by address pair """
- self.logger.info("BFD: Sending Slow control frame")
- self.test_session.update(my_discriminator=randint(0, 40000000))
- self.test_session.send_packet()
- self.pg0.enable_capture()
- p = self.pg0.wait_for_packet(1)
- self.assert_equal(p[BFD].your_discriminator,
- self.test_session.my_discriminator,
- "BFD - your discriminator")
- self.assert_equal(p[BFD].state, BFDState.init, BFDState)
- self.test_session.update(your_discriminator=p[BFD].my_discriminator,
- state=BFDState.up)
- self.logger.info("BFD: Waiting for event")
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.init)
- self.logger.info("BFD: Sending Up")
- self.test_session.send_packet()
- self.logger.info("BFD: Waiting for event")
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.up)
- self.logger.info("BFD: Session is Up")
- self.test_session.update(state=BFDState.up)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_session_down(self):
- """ bring BFD session down """
- bfd_session_up(self)
- bfd_session_down(self)
-
- def test_hold_up(self):
- """ hold BFD session up """
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- wait_for_bfd_packet(self)
- self.test_session.send_packet()
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_slow_timer(self):
- """ verify slow periodic control frames while session down """
- packet_count = 3
- self.logger.info("BFD: Waiting for %d BFD packets", packet_count)
- prev_packet = wait_for_bfd_packet(self, 2)
- for dummy in range(packet_count):
- next_packet = wait_for_bfd_packet(self, 2)
- time_diff = next_packet.time - prev_packet.time
- # spec says the range should be <0.75, 1>, allow extra 0.05 margin
- # to work around timing issues
- self.assert_in_range(
- time_diff, 0.70, 1.05, "time between slow packets")
- prev_packet = next_packet
-
- def test_zero_remote_min_rx(self):
- """ no packets when zero remote required min rx interval """
- bfd_session_up(self)
- self.test_session.update(required_min_rx=0)
- self.test_session.send_packet()
- for dummy in range(self.test_session.detect_mult):
- self.sleep(self.vpp_session.required_min_rx / USEC_IN_SEC,
- "sleep before transmitting bfd packet")
- self.test_session.send_packet()
- try:
- p = wait_for_bfd_packet(self, timeout=0)
- self.logger.error(ppp("Received unexpected packet:", p))
- except CaptureTimeoutError:
- pass
- self.assert_equal(
- len(self.vapi.collect_events()), 0, "number of bfd events")
- self.test_session.update(required_min_rx=300000)
- for dummy in range(3):
- self.test_session.send_packet()
- wait_for_bfd_packet(
- self, timeout=self.test_session.required_min_rx / USEC_IN_SEC)
- self.assert_equal(
- len(self.vapi.collect_events()), 0, "number of bfd events")
-
- def test_conn_down(self):
- """ verify session goes down after inactivity """
- bfd_session_up(self)
- detection_time = self.test_session.detect_mult *\
- self.vpp_session.required_min_rx / USEC_IN_SEC
- self.sleep(detection_time, "waiting for BFD session time-out")
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.down)
-
- def test_peer_discr_reset_sess_down(self):
- """ peer discriminator reset after session goes down """
- bfd_session_up(self)
- detection_time = self.test_session.detect_mult *\
- self.vpp_session.required_min_rx / USEC_IN_SEC
- self.sleep(detection_time, "waiting for BFD session time-out")
- self.test_session.my_discriminator = 0
- wait_for_bfd_packet(self,
- pcap_time_min=time.time() - self.vpp_clock_offset)
-
- def test_large_required_min_rx(self):
- """ large remote required min rx interval """
- bfd_session_up(self)
- p = wait_for_bfd_packet(self)
- interval = 3000000
- self.test_session.update(required_min_rx=interval)
- self.test_session.send_packet()
- time_mark = time.time()
- count = 0
- # busy wait here, trying to collect a packet or event, vpp is not
- # allowed to send packets and the session will timeout first - so the
- # Up->Down event must arrive before any packets do
- while time.time() < time_mark + interval / USEC_IN_SEC:
- try:
- p = wait_for_bfd_packet(self, timeout=0)
- # if vpp managed to send a packet before we did the session
- # session update, then that's fine, ignore it
- if p.time < time_mark - self.vpp_clock_offset:
- continue
- self.logger.error(ppp("Received unexpected packet:", p))
- count += 1
- except CaptureTimeoutError:
- pass
- events = self.vapi.collect_events()
- if len(events) > 0:
- verify_event(self, events[0], BFDState.down)
- break
- self.assert_equal(count, 0, "number of packets received")
-
- def test_immediate_remote_min_rx_reduction(self):
- """ immediately honor remote required min rx reduction """
- self.vpp_session.remove_vpp_config()
- self.vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, desired_min_tx=10000)
- self.pg0.enable_capture()
- self.vpp_session.add_vpp_config()
- self.test_session.update(desired_min_tx=1000000,
- required_min_rx=1000000)
- bfd_session_up(self)
- reference_packet = wait_for_bfd_packet(self)
- time_mark = time.time()
- interval = 300000
- self.test_session.update(required_min_rx=interval)
- self.test_session.send_packet()
- extra_time = time.time() - time_mark
- p = wait_for_bfd_packet(self)
- # first packet is allowed to be late by time we spent doing the update
- # calculated in extra_time
- self.assert_in_range(p.time - reference_packet.time,
- .95 * 0.75 * interval / USEC_IN_SEC,
- 1.05 * interval / USEC_IN_SEC + extra_time,
- "time between BFD packets")
- reference_packet = p
- for dummy in range(3):
- p = wait_for_bfd_packet(self)
- diff = p.time - reference_packet.time
- self.assert_in_range(diff, .95 * .75 * interval / USEC_IN_SEC,
- 1.05 * interval / USEC_IN_SEC,
- "time between BFD packets")
- reference_packet = p
-
- def test_modify_req_min_rx_double(self):
- """ modify session - double required min rx """
- bfd_session_up(self)
- p = wait_for_bfd_packet(self)
- self.test_session.update(desired_min_tx=10000,
- required_min_rx=10000)
- self.test_session.send_packet()
- # double required min rx
- self.vpp_session.modify_parameters(
- required_min_rx=2 * self.vpp_session.required_min_rx)
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- # poll bit needs to be set
- self.assertIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
- # finish poll sequence with final packet
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- timeout = self.test_session.detect_mult * \
- max(self.test_session.desired_min_tx,
- self.vpp_session.required_min_rx) / USEC_IN_SEC
- self.test_session.send_packet(final)
- time_mark = time.time()
- e = self.vapi.wait_for_event(2 * timeout, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.down)
- time_to_event = time.time() - time_mark
- self.assert_in_range(time_to_event, .9 * timeout,
- 1.1 * timeout, "session timeout")
-
- def test_modify_req_min_rx_halve(self):
- """ modify session - halve required min rx """
- self.vpp_session.modify_parameters(
- required_min_rx=2 * self.vpp_session.required_min_rx)
- bfd_session_up(self)
- p = wait_for_bfd_packet(self)
- self.test_session.update(desired_min_tx=10000,
- required_min_rx=10000)
- self.test_session.send_packet()
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- # halve required min rx
- old_required_min_rx = self.vpp_session.required_min_rx
- self.vpp_session.modify_parameters(
- required_min_rx=self.vpp_session.required_min_rx // 2)
- # now we wait 0.8*3*old-req-min-rx and the session should still be up
- self.sleep(0.8 * self.vpp_session.detect_mult *
- old_required_min_rx / USEC_IN_SEC,
- "wait before finishing poll sequence")
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
- p = wait_for_bfd_packet(self)
- # poll bit needs to be set
- self.assertIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
- # finish poll sequence with final packet
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- # now the session should time out under new conditions
- detection_time = self.test_session.detect_mult *\
- self.vpp_session.required_min_rx / USEC_IN_SEC
- before = time.time()
- e = self.vapi.wait_for_event(
- 2 * detection_time, "bfd_udp_session_event")
- after = time.time()
- self.assert_in_range(after - before,
- 0.9 * detection_time,
- 1.1 * detection_time,
- "time before bfd session goes down")
- verify_event(self, e, expected_state=BFDState.down)
-
- def test_modify_detect_mult(self):
- """ modify detect multiplier """
- bfd_session_up(self)
- p = wait_for_bfd_packet(self)
- self.vpp_session.modify_parameters(detect_mult=1)
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assert_equal(self.vpp_session.detect_mult,
- p[BFD].detect_mult,
- "detect mult")
- # poll bit must not be set
- self.assertNotIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
- self.vpp_session.modify_parameters(detect_mult=10)
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assert_equal(self.vpp_session.detect_mult,
- p[BFD].detect_mult,
- "detect mult")
- # poll bit must not be set
- self.assertNotIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
-
- def test_queued_poll(self):
- """ test poll sequence queueing """
- bfd_session_up(self)
- p = wait_for_bfd_packet(self)
- self.vpp_session.modify_parameters(
- required_min_rx=2 * self.vpp_session.required_min_rx)
- p = wait_for_bfd_packet(self)
- poll_sequence_start = time.time()
- poll_sequence_length_min = 0.5
- send_final_after = time.time() + poll_sequence_length_min
- # poll bit needs to be set
- self.assertIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
- self.assert_equal(p[BFD].required_min_rx_interval,
- self.vpp_session.required_min_rx,
- "BFD required min rx interval")
- self.vpp_session.modify_parameters(
- required_min_rx=2 * self.vpp_session.required_min_rx)
- # 2nd poll sequence should be queued now
- # don't send the reply back yet, wait for some time to emulate
- # longer round-trip time
- packet_count = 0
- while time.time() < send_final_after:
- self.test_session.send_packet()
- p = wait_for_bfd_packet(self)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
- self.assert_equal(p[BFD].required_min_rx_interval,
- self.vpp_session.required_min_rx,
- "BFD required min rx interval")
- packet_count += 1
- # poll bit must be set
- self.assertIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit not set in BFD packet")
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- # finish 1st with final
- poll_sequence_length = time.time() - poll_sequence_start
- # vpp must wait for some time before starting new poll sequence
- poll_no_2_started = False
- for dummy in range(2 * packet_count):
- p = wait_for_bfd_packet(self)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
- if "P" in p.sprintf("%BFD.flags%"):
- poll_no_2_started = True
- if time.time() < poll_sequence_start + poll_sequence_length:
- raise Exception("VPP started 2nd poll sequence too soon")
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- break
- else:
- self.test_session.send_packet()
- self.assertTrue(poll_no_2_started, "2nd poll sequence not performed")
- # finish 2nd with final
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- p = wait_for_bfd_packet(self)
- # poll bit must not be set
- self.assertNotIn("P", p.sprintf("%BFD.flags%"),
- "Poll bit set in BFD packet")
-
- # returning inconsistent results requiring retries in per-patch tests
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_poll_response(self):
- """ test correct response to control frame with poll bit set """
- bfd_session_up(self)
- poll = self.test_session.create_packet()
- poll[BFD].flags = "P"
- self.test_session.send_packet(poll)
- final = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assertIn("F", final.sprintf("%BFD.flags%"))
-
- def test_no_periodic_if_remote_demand(self):
- """ no periodic frames outside poll sequence if remote demand set """
- bfd_session_up(self)
- demand = self.test_session.create_packet()
- demand[BFD].flags = "D"
- self.test_session.send_packet(demand)
- transmit_time = 0.9 \
- * max(self.vpp_session.required_min_rx,
- self.test_session.desired_min_tx) \
- / USEC_IN_SEC
- count = 0
- for dummy in range(self.test_session.detect_mult * 2):
- self.sleep(transmit_time)
- self.test_session.send_packet(demand)
- try:
- p = wait_for_bfd_packet(self, timeout=0)
- self.logger.error(ppp("Received unexpected packet:", p))
- count += 1
- except CaptureTimeoutError:
- pass
- events = self.vapi.collect_events()
- for e in events:
- self.logger.error("Received unexpected event: %s", e)
- self.assert_equal(count, 0, "number of packets received")
- self.assert_equal(len(events), 0, "number of events received")
-
- def test_echo_looped_back(self):
- """ echo packets looped back """
- # don't need a session in this case..
- self.vpp_session.remove_vpp_config()
- self.pg0.enable_capture()
- echo_packet_count = 10
- # random source port low enough to increment a few times..
- udp_sport_tx = randint(1, 50000)
- udp_sport_rx = udp_sport_tx
- echo_packet = (Ether(src=self.pg0.remote_mac,
- dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4,
- dst=self.pg0.remote_ip4) /
- UDP(dport=BFD.udp_dport_echo) /
- Raw("this should be looped back"))
- for dummy in range(echo_packet_count):
- self.sleep(.01, "delay between echo packets")
- echo_packet[UDP].sport = udp_sport_tx
- udp_sport_tx += 1
- self.logger.debug(ppp("Sending packet:", echo_packet))
- self.pg0.add_stream(echo_packet)
- self.pg_start()
- for dummy in range(echo_packet_count):
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- ether = p[Ether]
- self.assert_equal(self.pg0.remote_mac,
- ether.dst, "Destination MAC")
- self.assert_equal(self.pg0.local_mac, ether.src, "Source MAC")
- ip = p[IP]
- self.assert_equal(self.pg0.remote_ip4, ip.dst, "Destination IP")
- self.assert_equal(self.pg0.remote_ip4, ip.src, "Destination IP")
- udp = p[UDP]
- self.assert_equal(udp.dport, BFD.udp_dport_echo,
- "UDP destination port")
- self.assert_equal(udp.sport, udp_sport_rx, "UDP source port")
- udp_sport_rx += 1
- # need to compare the hex payload here, otherwise BFD_vpp_echo
- # gets in way
- self.assertEqual(scapy.compat.raw(p[UDP].payload),
- scapy.compat.raw(echo_packet[UDP].payload),
- "Received packet is not the echo packet sent")
- self.assert_equal(udp_sport_tx, udp_sport_rx, "UDP source port (== "
- "ECHO packet identifier for test purposes)")
-
- def test_echo(self):
- """ echo function """
- bfd_session_up(self)
- 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(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(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- 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(
- sw_if_index=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
- while time.time() < loop_until:
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- if p[UDP].dport == BFD.udp_dport_echo:
- self.assert_equal(
- p[IP].dst, self.pg0.local_ip4, "BFD ECHO dst IP")
- self.assertNotEqual(p[IP].src, self.loopback0.local_ip4,
- "BFD ECHO src IP equal to loopback IP")
- self.logger.debug(ppp("Looping back packet:", p))
- self.assert_equal(p[Ether].dst, self.pg0.remote_mac,
- "ECHO packet destination MAC address")
- p[Ether].dst = self.pg0.local_mac
- self.pg0.add_stream(p)
- self.pg_start()
- echo_seen = True
- elif p.haslayer(BFD):
- 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"
- self.test_session.send_packet(final)
- else:
- raise Exception(ppp("Received unknown packet:", p))
-
- 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_echo_fail(self):
- """ session goes down if echo function fails """
- bfd_session_up(self)
- 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
- self.vapi.bfd_udp_set_echo_source(
- sw_if_index=self.loopback0.sw_if_index)
- # echo function should be used now, but we will drop the echo packets
- verified_diag = False
- for dummy in range(3):
- loop_until = time.time() + 0.75 * detection_time
- while time.time() < loop_until:
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- if p[UDP].dport == BFD.udp_dport_echo:
- # dropped
- pass
- elif p.haslayer(BFD):
- if "P" in p.sprintf("%BFD.flags%"):
- self.assertGreaterEqual(
- p[BFD].required_min_rx_interval,
- 1000000)
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- if p[BFD].state == BFDState.down:
- self.assert_equal(p[BFD].diag,
- BFDDiagCode.echo_function_failed,
- BFDDiagCode)
- verified_diag = True
- else:
- raise Exception(ppp("Received unknown packet:", p))
- self.test_session.send_packet()
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 1, "number of bfd events")
- self.assert_equal(events[0].state, BFDState.down, BFDState)
- self.assertTrue(verified_diag, "Incorrect diagnostics code received")
-
- 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=150000)
- self.test_session.send_packet()
- self.vapi.bfd_udp_set_echo_source(
- sw_if_index=self.loopback0.sw_if_index)
- # wait for first echo packet
- while True:
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- if p[UDP].dport == BFD.udp_dport_echo:
- self.logger.debug(ppp("Looping back packet:", p))
- p[Ether].dst = self.pg0.local_mac
- self.pg0.add_stream(p)
- self.pg_start()
- break
- elif p.haslayer(BFD):
- # ignore BFD
- pass
- else:
- raise Exception(ppp("Received unknown packet:", p))
- self.test_session.update(required_min_echo_rx=0)
- self.test_session.send_packet()
- # echo packets shouldn't arrive anymore
- for dummy in range(5):
- wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.test_session.send_packet()
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 0, "number of bfd events")
-
- 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=150000)
- self.test_session.send_packet()
- self.vapi.bfd_udp_set_echo_source(
- sw_if_index=self.loopback0.sw_if_index)
- # wait for first echo packet
- while True:
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- if p[UDP].dport == BFD.udp_dport_echo:
- self.logger.debug(ppp("Looping back packet:", p))
- p[Ether].dst = self.pg0.local_mac
- self.pg0.add_stream(p)
- self.pg_start()
- break
- elif p.haslayer(BFD):
- # ignore BFD
- pass
- else:
- raise Exception(ppp("Received unknown packet:", p))
- self.vapi.bfd_udp_del_echo_source()
- self.test_session.send_packet()
- # echo packets shouldn't arrive anymore
- for dummy in range(5):
- wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.test_session.send_packet()
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 0, "number of bfd events")
-
- 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=150000)
- self.vapi.bfd_udp_set_echo_source(
- sw_if_index=self.loopback0.sw_if_index)
- self.test_session.send_packet()
- # should be turned on - loopback echo packets
- echo_packet = None
- timeout_at = None
- timeout_ok = False
- for dummy in range(10 * self.vpp_session.detect_mult):
- p = self.pg0.wait_for_packet(1)
- if p[UDP].dport == BFD.udp_dport_echo:
- if echo_packet is None:
- self.logger.debug(ppp("Got first echo packet:", p))
- echo_packet = p
- timeout_at = time.time() + self.vpp_session.detect_mult * \
- self.test_session.required_min_echo_rx / USEC_IN_SEC
- else:
- self.logger.debug(ppp("Got followup echo packet:", p))
- self.logger.debug(ppp("Looping back first echo packet:", p))
- echo_packet[Ether].dst = self.pg0.local_mac
- self.pg0.add_stream(echo_packet)
- self.pg_start()
- elif p.haslayer(BFD):
- self.logger.debug(ppp("Got packet:", p))
- if "P" in p.sprintf("%BFD.flags%"):
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- if p[BFD].state == BFDState.down:
- self.assertIsNotNone(
- timeout_at,
- "Session went down before first echo packet received")
- now = time.time()
- self.assertGreaterEqual(
- now, timeout_at,
- "Session timeout at %s, but is expected at %s" %
- (now, timeout_at))
- self.assert_equal(p[BFD].diag,
- BFDDiagCode.echo_function_failed,
- BFDDiagCode)
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 1, "number of bfd events")
- self.assert_equal(events[0].state, BFDState.down, BFDState)
- timeout_ok = True
- break
- else:
- raise Exception(ppp("Received unknown packet:", p))
- self.test_session.send_packet()
- self.assertTrue(timeout_ok, "Expected timeout event didn't occur")
-
- 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=150000)
- self.vapi.bfd_udp_set_echo_source(
- sw_if_index=self.loopback0.sw_if_index)
- self.test_session.send_packet()
- # should be turned on - loopback echo packets
- timeout_at = None
- timeout_ok = False
- for dummy in range(10 * self.vpp_session.detect_mult):
- p = self.pg0.wait_for_packet(1)
- if p[UDP].dport == BFD.udp_dport_echo:
- self.logger.debug(ppp("Got echo packet:", p))
- if timeout_at is None:
- timeout_at = time.time() + self.vpp_session.detect_mult * \
- self.test_session.required_min_echo_rx / USEC_IN_SEC
- p[BFD_vpp_echo].checksum = getrandbits(64)
- p[Ether].dst = self.pg0.local_mac
- self.logger.debug(ppp("Looping back modified echo packet:", p))
- self.pg0.add_stream(p)
- self.pg_start()
- elif p.haslayer(BFD):
- self.logger.debug(ppp("Got packet:", p))
- if "P" in p.sprintf("%BFD.flags%"):
- final = self.test_session.create_packet()
- final[BFD].flags = "F"
- self.test_session.send_packet(final)
- if p[BFD].state == BFDState.down:
- self.assertIsNotNone(
- timeout_at,
- "Session went down before first echo packet received")
- now = time.time()
- self.assertGreaterEqual(
- now, timeout_at,
- "Session timeout at %s, but is expected at %s" %
- (now, timeout_at))
- self.assert_equal(p[BFD].diag,
- BFDDiagCode.echo_function_failed,
- BFDDiagCode)
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 1, "number of bfd events")
- self.assert_equal(events[0].state, BFDState.down, BFDState)
- timeout_ok = True
- break
- else:
- raise Exception(ppp("Received unknown packet:", p))
- self.test_session.send_packet()
- self.assertTrue(timeout_ok, "Expected timeout event didn't occur")
-
- def test_admin_up_down(self):
- """ put session admin-up and admin-down """
- bfd_session_up(self)
- self.vpp_session.admin_down()
- self.pg0.enable_capture()
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.admin_down)
- for dummy in range(2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.admin_down, BFDState)
- # try to bring session up - shouldn't be possible
- self.test_session.update(state=BFDState.init)
- self.test_session.send_packet()
- for dummy in range(2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.admin_down, BFDState)
- self.vpp_session.admin_up()
- self.test_session.update(state=BFDState.down)
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.down)
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assert_equal(p[BFD].state, BFDState.down, BFDState)
- self.test_session.send_packet()
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assert_equal(p[BFD].state, BFDState.init, BFDState)
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.init)
- self.test_session.update(state=BFDState.up)
- self.test_session.send_packet()
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.up)
-
- def test_config_change_remote_demand(self):
- """ configuration change while peer in demand mode """
- bfd_session_up(self)
- demand = self.test_session.create_packet()
- demand[BFD].flags = "D"
- self.test_session.send_packet(demand)
- self.vpp_session.modify_parameters(
- required_min_rx=2 * self.vpp_session.required_min_rx)
- p = wait_for_bfd_packet(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- # poll bit must be set
- self.assertIn("P", p.sprintf("%BFD.flags%"), "Poll bit not set")
- # terminate poll sequence
- final = self.test_session.create_packet()
- final[BFD].flags = "D+F"
- self.test_session.send_packet(final)
- # vpp should be quiet now again
- transmit_time = 0.9 \
- * max(self.vpp_session.required_min_rx,
- self.test_session.desired_min_tx) \
- / USEC_IN_SEC
- count = 0
- for dummy in range(self.test_session.detect_mult * 2):
- self.sleep(transmit_time)
- self.test_session.send_packet(demand)
- try:
- p = wait_for_bfd_packet(self, timeout=0)
- self.logger.error(ppp("Received unexpected packet:", p))
- count += 1
- except CaptureTimeoutError:
- pass
- events = self.vapi.collect_events()
- for e in events:
- self.logger.error("Received unexpected event: %s", e)
- 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_event")
- self.assert_equal(e.sw_if_index, sw_if_index, "sw_if_index")
- self.assertFalse(vpp_session.query_vpp_config())
-
-
-@tag_run_solo
-@tag_fixme_vpp_workers
-class BFD6TestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD) (IPv6) """
-
- pg0 = None
- vpp_clock_offset = None
- vpp_session = None
- test_session = None
-
- @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(1)
- cls.loopback0 = cls.lo_interfaces[0]
- cls.loopback0.config_ip6()
- cls.loopback0.admin_up()
-
- except Exception:
- super(BFD6TestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFD6TestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFD6TestCase, self).setUp()
- self.factory = AuthKeyFactory()
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
- try:
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip6,
- af=AF_INET6)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(self, self.pg0, AF_INET6)
- self.logger.debug(self.vapi.cli("show adj nbr"))
- except BaseException:
- self.vapi.want_bfd_events(enable_disable=0)
- raise
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=0)
- self.vapi.collect_events() # clear the event queue
- super(BFD6TestCase, self).tearDown()
-
- def test_session_up(self):
- """ bring BFD session up """
- bfd_session_up(self)
-
- def test_session_up_by_ip(self):
- """ bring BFD session up - first frame looked up by address pair """
- self.logger.info("BFD: Sending Slow control frame")
- self.test_session.update(my_discriminator=randint(0, 40000000))
- self.test_session.send_packet()
- self.pg0.enable_capture()
- p = self.pg0.wait_for_packet(1)
- self.assert_equal(p[BFD].your_discriminator,
- self.test_session.my_discriminator,
- "BFD - your discriminator")
- self.assert_equal(p[BFD].state, BFDState.init, BFDState)
- self.test_session.update(your_discriminator=p[BFD].my_discriminator,
- state=BFDState.up)
- self.logger.info("BFD: Waiting for event")
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.init)
- self.logger.info("BFD: Sending Up")
- self.test_session.send_packet()
- self.logger.info("BFD: Waiting for event")
- e = self.vapi.wait_for_event(1, "bfd_udp_session_event")
- verify_event(self, e, expected_state=BFDState.up)
- self.logger.info("BFD: Session is Up")
- self.test_session.update(state=BFDState.up)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_hold_up(self):
- """ hold BFD session up """
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- wait_for_bfd_packet(self)
- self.test_session.send_packet()
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_echo_looped_back(self):
- """ echo packets looped back """
- # don't need a session in this case..
- self.vpp_session.remove_vpp_config()
- self.pg0.enable_capture()
- echo_packet_count = 10
- # random source port low enough to increment a few times..
- udp_sport_tx = randint(1, 50000)
- udp_sport_rx = udp_sport_tx
- echo_packet = (Ether(src=self.pg0.remote_mac,
- dst=self.pg0.local_mac) /
- IPv6(src=self.pg0.remote_ip6,
- dst=self.pg0.remote_ip6) /
- UDP(dport=BFD.udp_dport_echo) /
- Raw("this should be looped back"))
- for dummy in range(echo_packet_count):
- self.sleep(.01, "delay between echo packets")
- echo_packet[UDP].sport = udp_sport_tx
- udp_sport_tx += 1
- self.logger.debug(ppp("Sending packet:", echo_packet))
- self.pg0.add_stream(echo_packet)
- self.pg_start()
- for dummy in range(echo_packet_count):
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- ether = p[Ether]
- self.assert_equal(self.pg0.remote_mac,
- ether.dst, "Destination MAC")
- self.assert_equal(self.pg0.local_mac, ether.src, "Source MAC")
- ip = p[IPv6]
- self.assert_equal(self.pg0.remote_ip6, ip.dst, "Destination IP")
- self.assert_equal(self.pg0.remote_ip6, ip.src, "Destination IP")
- udp = p[UDP]
- self.assert_equal(udp.dport, BFD.udp_dport_echo,
- "UDP destination port")
- self.assert_equal(udp.sport, udp_sport_rx, "UDP source port")
- udp_sport_rx += 1
- # need to compare the hex payload here, otherwise BFD_vpp_echo
- # gets in way
- self.assertEqual(scapy.compat.raw(p[UDP].payload),
- scapy.compat.raw(echo_packet[UDP].payload),
- "Received packet is not the echo packet sent")
- self.assert_equal(udp_sport_tx, udp_sport_rx, "UDP source port (== "
- "ECHO packet identifier for test purposes)")
- self.assert_equal(udp_sport_tx, udp_sport_rx, "UDP source port (== "
- "ECHO packet identifier for test purposes)")
-
- def test_echo(self):
- """ echo function """
- bfd_session_up(self)
- 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(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(
- self, pcap_time_min=time.time() - self.vpp_clock_offset)
- 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(
- sw_if_index=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
- while time.time() < loop_until:
- p = self.pg0.wait_for_packet(1)
- self.logger.debug(ppp("Got packet:", p))
- if p[UDP].dport == BFD.udp_dport_echo:
- self.assert_equal(
- p[IPv6].dst, self.pg0.local_ip6, "BFD ECHO dst IP")
- self.assertNotEqual(p[IPv6].src, self.loopback0.local_ip6,
- "BFD ECHO src IP equal to loopback IP")
- self.logger.debug(ppp("Looping back packet:", p))
- self.assert_equal(p[Ether].dst, self.pg0.remote_mac,
- "ECHO packet destination MAC address")
- p[Ether].dst = self.pg0.local_mac
- self.pg0.add_stream(p)
- self.pg_start()
- echo_seen = True
- elif p.haslayer(BFD):
- 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"
- self.test_session.send_packet(final)
- else:
- raise Exception(ppp("Received unknown packet:", p))
-
- 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_event")
- self.assert_equal(e.sw_if_index, sw_if_index, "sw_if_index")
- self.assertFalse(vpp_session.query_vpp_config())
-
-
-@tag_run_solo
-class BFDFIBTestCase(VppTestCase):
- """ BFD-FIB interactions (IPv6) """
-
- vpp_session = None
- test_session = None
-
- @classmethod
- def setUpClass(cls):
- super(BFDFIBTestCase, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(BFDFIBTestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDFIBTestCase, self).setUp()
- self.create_pg_interfaces(range(1))
-
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
-
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip6()
- i.configure_ipv6_neighbors()
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=False)
-
- super(BFDFIBTestCase, self).tearDown()
-
- @staticmethod
- def pkt_is_not_data_traffic(p):
- """ not data traffic implies BFD or the usual IPv6 ND/RA"""
- if p.haslayer(BFD) or is_ipv6_misc(p):
- return True
- return False
-
- def test_session_with_fib(self):
- """ BFD-FIB interactions """
-
- # 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) /
- Raw(b'\xa5' * 100)),
- (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(src="3001::1", dst="2002::1") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))]
-
- # A recursive and a non-recursive route via a next-hop that
- # will have a BFD session
- ip_2001_s_64 = VppIpRoute(self, "2001::", 64,
- [VppRoutePath(self.pg0.remote_ip6,
- self.pg0.sw_if_index)])
- ip_2002_s_64 = VppIpRoute(self, "2002::", 64,
- [VppRoutePath(self.pg0.remote_ip6,
- 0xffffffff)])
- ip_2001_s_64.add_vpp_config()
- ip_2002_s_64.add_vpp_config()
-
- # bring the session up now the routes are present
- self.vpp_session = VppBFDUDPSession(self,
- self.pg0,
- self.pg0.remote_ip6,
- af=AF_INET6)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(self, self.pg0, AF_INET6)
-
- # session is up - traffic passes
- bfd_session_up(self)
-
- self.pg0.add_stream(p)
- self.pg_start()
- for packet in p:
- captured = self.pg0.wait_for_packet(
- 1,
- filter_out_fn=self.pkt_is_not_data_traffic)
- self.assertEqual(captured[IPv6].dst,
- packet[IPv6].dst)
-
- # session is up - traffic is dropped
- bfd_session_down(self)
-
- self.pg0.add_stream(p)
- self.pg_start()
- with self.assertRaises(CaptureTimeoutError):
- self.pg0.wait_for_packet(1, self.pkt_is_not_data_traffic)
-
- # session is up - traffic passes
- bfd_session_up(self)
-
- self.pg0.add_stream(p)
- self.pg_start()
- for packet in p:
- captured = self.pg0.wait_for_packet(
- 1,
- filter_out_fn=self.pkt_is_not_data_traffic)
- self.assertEqual(captured[IPv6].dst,
- packet[IPv6].dst)
-
-
-@unittest.skipUnless(running_extended_tests, "part of extended tests")
-class BFDTunTestCase(VppTestCase):
- """ BFD over GRE tunnel """
-
- vpp_session = None
- test_session = None
-
- @classmethod
- def setUpClass(cls):
- super(BFDTunTestCase, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(BFDTunTestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDTunTestCase, self).setUp()
- self.create_pg_interfaces(range(1))
-
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
-
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip4()
- i.resolve_arp()
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=0)
-
- super(BFDTunTestCase, self).tearDown()
-
- @staticmethod
- def pkt_is_not_data_traffic(p):
- """ not data traffic implies BFD or the usual IPv6 ND/RA"""
- if p.haslayer(BFD) or is_ipv6_misc(p):
- return True
- return False
-
- def test_bfd_o_gre(self):
- """ BFD-o-GRE """
-
- # A GRE interface over which to run a BFD session
- gre_if = VppGreInterface(self,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip4()
-
- # bring the session up now the routes are present
- self.vpp_session = VppBFDUDPSession(self,
- gre_if,
- gre_if.remote_ip4,
- is_tunnel=True)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
-
- self.test_session = BFDTestSession(
- self, gre_if, AF_INET,
- tunnel_header=(IP(src=self.pg0.remote_ip4,
- dst=self.pg0.local_ip4) /
- GRE()),
- phy_interface=self.pg0)
-
- # packets to match against both of the routes
- p = [(Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IP(src=self.pg0.remote_ip4, dst=gre_if.remote_ip4) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))]
-
- # session is up - traffic passes
- bfd_session_up(self)
-
- self.send_and_expect(self.pg0, p, self.pg0)
-
- # bring session down
- bfd_session_down(self)
-
-
-@tag_run_solo
-class BFDSHA1TestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD) (SHA1 auth) """
-
- pg0 = None
- vpp_clock_offset = None
- vpp_session = None
- test_session = None
-
- @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()
- cls.pg0.admin_up()
- cls.pg0.resolve_arp()
-
- except Exception:
- super(BFDSHA1TestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFDSHA1TestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDSHA1TestCase, self).setUp()
- self.factory = AuthKeyFactory()
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=False)
- self.vapi.collect_events() # clear the event queue
- super(BFDSHA1TestCase, self).tearDown()
-
- def test_session_up(self):
- """ bring BFD session up """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4,
- sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
-
- def test_hold_up(self):
- """ hold BFD session up """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4,
- sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- wait_for_bfd_packet(self)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_hold_up_meticulous(self):
- """ hold BFD session up - meticulous auth """
- key = self.factory.create_random_key(
- self, BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- # specify sequence number so that it wraps
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id,
- our_seq_number=0xFFFFFFFF - 4)
- bfd_session_up(self)
- for dummy in range(30):
- wait_for_bfd_packet(self)
- self.test_session.inc_seq_num()
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_send_bad_seq_number(self):
- """ session is not kept alive by msgs with bad sequence numbers"""
- key = self.factory.create_random_key(
- self, BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- detection_time = self.test_session.detect_mult *\
- self.vpp_session.required_min_rx / USEC_IN_SEC
- send_until = time.time() + 2 * detection_time
- while time.time() < send_until:
- self.test_session.send_packet()
- self.sleep(0.7 * self.vpp_session.required_min_rx / USEC_IN_SEC,
- "time between bfd packets")
- e = self.vapi.collect_events()
- # session should be down now, because the sequence numbers weren't
- # updated
- self.assert_equal(len(e), 1, "number of bfd events")
- verify_event(self, e[0], expected_state=BFDState.down)
-
- def execute_rogue_session_scenario(self, vpp_bfd_udp_session,
- legitimate_test_session,
- rogue_test_session,
- rogue_bfd_values=None):
- """ execute a rogue session interaction scenario
-
- 1. create vpp session, add config
- 2. bring the legitimate session up
- 3. copy the bfd values from legitimate session to rogue session
- 4. apply rogue_bfd_values to rogue session
- 5. set rogue session state to down
- 6. send message to take the session down from the rogue session
- 7. assert that the legitimate session is unaffected
- """
-
- self.vpp_session = vpp_bfd_udp_session
- self.vpp_session.add_vpp_config()
- self.test_session = legitimate_test_session
- # bring vpp session up
- bfd_session_up(self)
- # send packet from rogue session
- rogue_test_session.update(
- my_discriminator=self.test_session.my_discriminator,
- your_discriminator=self.test_session.your_discriminator,
- desired_min_tx=self.test_session.desired_min_tx,
- required_min_rx=self.test_session.required_min_rx,
- detect_mult=self.test_session.detect_mult,
- diag=self.test_session.diag,
- state=self.test_session.state,
- auth_type=self.test_session.auth_type)
- if rogue_bfd_values:
- rogue_test_session.update(**rogue_bfd_values)
- rogue_test_session.update(state=BFDState.down)
- rogue_test_session.send_packet()
- wait_for_bfd_packet(self)
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
-
- def test_mismatch_auth(self):
- """ session is not brought down by unauthenticated msg """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=key)
- legitimate_test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id)
- rogue_test_session = BFDTestSession(self, self.pg0, AF_INET)
- self.execute_rogue_session_scenario(vpp_session,
- legitimate_test_session,
- rogue_test_session)
-
- def test_mismatch_bfd_key_id(self):
- """ session is not brought down by msg with non-existent key-id """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=key)
- # pick a different random bfd key id
- x = randint(0, 255)
- while x == vpp_session.bfd_key_id:
- x = randint(0, 255)
- legitimate_test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id)
- rogue_test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key, bfd_key_id=x)
- self.execute_rogue_session_scenario(vpp_session,
- legitimate_test_session,
- rogue_test_session)
-
- def test_mismatched_auth_type(self):
- """ session is not brought down by msg with wrong auth type """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=key)
- legitimate_test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id)
- rogue_test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id)
- self.execute_rogue_session_scenario(
- vpp_session, legitimate_test_session, rogue_test_session,
- {'auth_type': BFDAuthType.keyed_md5})
-
- def test_restart(self):
- """ simulate remote peer restart and resynchronization """
- key = self.factory.create_random_key(
- self, BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id, our_seq_number=0)
- bfd_session_up(self)
- # don't send any packets for 2*detection_time
- detection_time = self.test_session.detect_mult *\
- self.vpp_session.required_min_rx / USEC_IN_SEC
- self.sleep(2 * detection_time, "simulating peer restart")
- events = self.vapi.collect_events()
- self.assert_equal(len(events), 1, "number of bfd events")
- verify_event(self, events[0], expected_state=BFDState.down)
- self.test_session.update(state=BFDState.down)
- # reset sequence number
- self.test_session.our_seq_number = 0
- self.test_session.vpp_seq_number = None
- # now throw away any pending packets
- self.pg0.enable_capture()
- self.test_session.my_discriminator = 0
- bfd_session_up(self)
-
-
-@tag_run_solo
-class BFDAuthOnOffTestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD) (changing auth) """
-
- pg0 = None
- vpp_session = None
- test_session = None
-
- @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()
- cls.pg0.admin_up()
- cls.pg0.resolve_arp()
-
- except Exception:
- super(BFDAuthOnOffTestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFDAuthOnOffTestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDAuthOnOffTestCase, self).setUp()
- self.factory = AuthKeyFactory()
- self.vapi.want_bfd_events()
- self.pg0.enable_capture()
-
- def tearDown(self):
- if not self.vpp_dead:
- self.vapi.want_bfd_events(enable_disable=False)
- self.vapi.collect_events() # clear the event queue
- super(BFDAuthOnOffTestCase, self).tearDown()
-
- def test_auth_on_immediate(self):
- """ turn auth on without disturbing session state (immediate) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(self, self.pg0, AF_INET)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.vpp_session.activate_auth(key)
- self.test_session.bfd_key_id = self.vpp_session.bfd_key_id
- self.test_session.sha1_key = key
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_auth_off_immediate(self):
- """ turn auth off without disturbing session state (immediate) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- # self.vapi.want_bfd_events(enable_disable=0)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.inc_seq_num()
- self.test_session.send_packet()
- self.vpp_session.deactivate_auth()
- self.test_session.bfd_key_id = None
- self.test_session.sha1_key = None
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.inc_seq_num()
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_auth_change_key_immediate(self):
- """ change auth key without disturbing session state (immediate) """
- key1 = self.factory.create_random_key(self)
- key1.add_vpp_config()
- key2 = self.factory.create_random_key(self)
- key2.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key1)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key1,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.vpp_session.activate_auth(key2)
- self.test_session.bfd_key_id = self.vpp_session.bfd_key_id
- self.test_session.sha1_key = key2
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_auth_on_delayed(self):
- """ turn auth on without disturbing session state (delayed) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(self, self.pg0, AF_INET)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- wait_for_bfd_packet(self)
- self.test_session.send_packet()
- self.vpp_session.activate_auth(key, delayed=True)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.test_session.bfd_key_id = self.vpp_session.bfd_key_id
- self.test_session.sha1_key = key
- self.test_session.send_packet()
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_auth_off_delayed(self):
- """ turn auth off without disturbing session state (delayed) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key)
- self.vpp_session.add_vpp_config()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.vpp_session.deactivate_auth(delayed=True)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.test_session.bfd_key_id = None
- self.test_session.sha1_key = None
- self.test_session.send_packet()
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
- def test_auth_change_key_delayed(self):
- """ change auth key without disturbing session state (delayed) """
- key1 = self.factory.create_random_key(self)
- key1.add_vpp_config()
- key2 = self.factory.create_random_key(self)
- key2.add_vpp_config()
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip4, sha1_key=key1)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = BFDTestSession(
- self, self.pg0, AF_INET, sha1_key=key1,
- bfd_key_id=self.vpp_session.bfd_key_id)
- bfd_session_up(self)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.vpp_session.activate_auth(key2, delayed=True)
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.test_session.bfd_key_id = self.vpp_session.bfd_key_id
- self.test_session.sha1_key = key2
- self.test_session.send_packet()
- for dummy in range(self.test_session.detect_mult * 2):
- p = wait_for_bfd_packet(self)
- self.assert_equal(p[BFD].state, BFDState.up, BFDState)
- self.test_session.send_packet()
- self.assert_equal(self.vpp_session.state, BFDState.up, BFDState)
- self.assert_equal(len(self.vapi.collect_events()), 0,
- "number of bfd events")
-
-
-@tag_run_solo
-class BFDCLITestCase(VppTestCase):
- """Bidirectional Forwarding Detection (BFD) (CLI) """
- pg0 = None
-
- @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()
- cls.pg0.config_ip6()
- cls.pg0.resolve_arp()
- cls.pg0.resolve_ndp()
-
- except Exception:
- super(BFDCLITestCase, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(BFDCLITestCase, cls).tearDownClass()
-
- def setUp(self):
- super(BFDCLITestCase, self).setUp()
- self.factory = AuthKeyFactory()
- self.pg0.enable_capture()
-
- def tearDown(self):
- try:
- self.vapi.want_bfd_events(enable_disable=False)
- except UnexpectedApiReturnValueError:
- # some tests aren't subscribed, so this is not an issue
- pass
- self.vapi.collect_events() # clear the event queue
- super(BFDCLITestCase, self).tearDown()
-
- def cli_verify_no_response(self, cli):
- """ execute a CLI, asserting that the response is empty """
- self.assert_equal(self.vapi.cli(cli),
- "",
- "CLI command response")
-
- def cli_verify_response(self, cli, expected):
- """ execute a CLI, asserting that the response matches expectation """
- try:
- reply = self.vapi.cli(cli)
- except CliFailedCommandError as cli_error:
- reply = str(cli_error)
- self.assert_equal(reply.strip(),
- expected,
- "CLI command response")
-
- def test_show(self):
- """ show commands """
- k1 = self.factory.create_random_key(self)
- k1.add_vpp_config()
- k2 = self.factory.create_random_key(
- self, auth_type=BFDAuthType.meticulous_keyed_sha1)
- k2.add_vpp_config()
- s1 = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- s1.add_vpp_config()
- s2 = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip6, af=AF_INET6,
- sha1_key=k2)
- s2.add_vpp_config()
- self.logger.info(self.vapi.ppcli("show bfd keys"))
- self.logger.info(self.vapi.ppcli("show bfd sessions"))
- self.logger.info(self.vapi.ppcli("show bfd"))
-
- def test_set_del_sha1_key(self):
- """ set/delete SHA1 auth key """
- k = self.factory.create_random_key(self)
- self.registry.register(k, self.logger)
- self.cli_verify_no_response(
- "bfd key set conf-key-id %s type keyed-sha1 secret %s" %
- (k.conf_key_id,
- "".join("{:02x}".format(scapy.compat.orb(c)) for c in k.key)))
- self.assertTrue(k.query_vpp_config())
- self.vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=k)
- self.vpp_session.add_vpp_config()
- self.test_session = \
- BFDTestSession(self, self.pg0, AF_INET, sha1_key=k,
- bfd_key_id=self.vpp_session.bfd_key_id)
- self.vapi.want_bfd_events()
- bfd_session_up(self)
- bfd_session_down(self)
- # try to replace the secret for the key - should fail because the key
- # is in-use
- k2 = self.factory.create_random_key(self)
- self.cli_verify_response(
- "bfd key set conf-key-id %s type keyed-sha1 secret %s" %
- (k.conf_key_id,
- "".join("{:02x}".format(scapy.compat.orb(c)) for c in k2.key)),
- "bfd key set: `bfd_auth_set_key' API call failed, "
- "rv=-103:BFD object in use")
- # manipulating the session using old secret should still work
- bfd_session_up(self)
- bfd_session_down(self)
- self.vpp_session.remove_vpp_config()
- self.cli_verify_no_response(
- "bfd key del conf-key-id %s" % k.conf_key_id)
- self.assertFalse(k.query_vpp_config())
-
- def test_set_del_meticulous_sha1_key(self):
- """ set/delete meticulous SHA1 auth key """
- k = self.factory.create_random_key(
- self, auth_type=BFDAuthType.meticulous_keyed_sha1)
- self.registry.register(k, self.logger)
- self.cli_verify_no_response(
- "bfd key set conf-key-id %s type meticulous-keyed-sha1 secret %s" %
- (k.conf_key_id,
- "".join("{:02x}".format(scapy.compat.orb(c)) for c in k.key)))
- self.assertTrue(k.query_vpp_config())
- self.vpp_session = VppBFDUDPSession(self, self.pg0,
- self.pg0.remote_ip6, af=AF_INET6,
- sha1_key=k)
- self.vpp_session.add_vpp_config()
- self.vpp_session.admin_up()
- self.test_session = \
- BFDTestSession(self, self.pg0, AF_INET6, sha1_key=k,
- bfd_key_id=self.vpp_session.bfd_key_id)
- self.vapi.want_bfd_events()
- bfd_session_up(self)
- bfd_session_down(self)
- # try to replace the secret for the key - should fail because the key
- # is in-use
- k2 = self.factory.create_random_key(self)
- self.cli_verify_response(
- "bfd key set conf-key-id %s type keyed-sha1 secret %s" %
- (k.conf_key_id,
- "".join("{:02x}".format(scapy.compat.orb(c)) for c in k2.key)),
- "bfd key set: `bfd_auth_set_key' API call failed, "
- "rv=-103:BFD object in use")
- # manipulating the session using old secret should still work
- bfd_session_up(self)
- bfd_session_down(self)
- self.vpp_session.remove_vpp_config()
- self.cli_verify_no_response(
- "bfd key del conf-key-id %s" % k.conf_key_id)
- self.assertFalse(k.query_vpp_config())
-
- def test_add_mod_del_bfd_udp(self):
- """ create/modify/delete IPv4 BFD UDP session """
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4)
- self.registry.register(vpp_session, self.logger)
- cli_add_cmd = "bfd udp session add interface %s local-addr %s " \
- "peer-addr %s desired-min-tx %s required-min-rx %s "\
- "detect-mult %s" % (self.pg0.name, self.pg0.local_ip4,
- self.pg0.remote_ip4,
- vpp_session.desired_min_tx,
- vpp_session.required_min_rx,
- vpp_session.detect_mult)
- self.cli_verify_no_response(cli_add_cmd)
- # 2nd add should fail
- self.cli_verify_response(
- cli_add_cmd,
- "bfd udp session add: `bfd_add_add_session' API call"
- " failed, rv=-101:Duplicate BFD object")
- verify_bfd_session_config(self, vpp_session)
- mod_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4,
- required_min_rx=2 * vpp_session.required_min_rx,
- desired_min_tx=3 * vpp_session.desired_min_tx,
- detect_mult=4 * vpp_session.detect_mult)
- self.cli_verify_no_response(
- "bfd udp session mod interface %s local-addr %s peer-addr %s "
- "desired-min-tx %s required-min-rx %s detect-mult %s" %
- (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4,
- mod_session.desired_min_tx, mod_session.required_min_rx,
- mod_session.detect_mult))
- verify_bfd_session_config(self, mod_session)
- cli_del_cmd = "bfd udp session del interface %s local-addr %s "\
- "peer-addr %s" % (self.pg0.name,
- self.pg0.local_ip4, self.pg0.remote_ip4)
- self.cli_verify_no_response(cli_del_cmd)
- # 2nd del is expected to fail
- self.cli_verify_response(
- cli_del_cmd, "bfd udp session del: `bfd_udp_del_session' API call"
- " failed, rv=-102:No such BFD object")
- self.assertFalse(vpp_session.query_vpp_config())
-
- def test_add_mod_del_bfd_udp6(self):
- """ create/modify/delete IPv6 BFD UDP session """
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip6, af=AF_INET6)
- self.registry.register(vpp_session, self.logger)
- cli_add_cmd = "bfd udp session add interface %s local-addr %s " \
- "peer-addr %s desired-min-tx %s required-min-rx %s "\
- "detect-mult %s" % (self.pg0.name, self.pg0.local_ip6,
- self.pg0.remote_ip6,
- vpp_session.desired_min_tx,
- vpp_session.required_min_rx,
- vpp_session.detect_mult)
- self.cli_verify_no_response(cli_add_cmd)
- # 2nd add should fail
- self.cli_verify_response(
- cli_add_cmd,
- "bfd udp session add: `bfd_add_add_session' API call"
- " failed, rv=-101:Duplicate BFD object")
- verify_bfd_session_config(self, vpp_session)
- mod_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip6, af=AF_INET6,
- required_min_rx=2 * vpp_session.required_min_rx,
- desired_min_tx=3 * vpp_session.desired_min_tx,
- detect_mult=4 * vpp_session.detect_mult)
- self.cli_verify_no_response(
- "bfd udp session mod interface %s local-addr %s peer-addr %s "
- "desired-min-tx %s required-min-rx %s detect-mult %s" %
- (self.pg0.name, self.pg0.local_ip6, self.pg0.remote_ip6,
- mod_session.desired_min_tx,
- mod_session.required_min_rx, mod_session.detect_mult))
- verify_bfd_session_config(self, mod_session)
- cli_del_cmd = "bfd udp session del interface %s local-addr %s "\
- "peer-addr %s" % (self.pg0.name,
- self.pg0.local_ip6, self.pg0.remote_ip6)
- self.cli_verify_no_response(cli_del_cmd)
- # 2nd del is expected to fail
- self.cli_verify_response(
- cli_del_cmd,
- "bfd udp session del: `bfd_udp_del_session' API call"
- " failed, rv=-102:No such BFD object")
- self.assertFalse(vpp_session.query_vpp_config())
-
- def test_add_mod_del_bfd_udp_auth(self):
- """ create/modify/delete IPv4 BFD UDP session (authenticated) """
- key = self.factory.create_random_key(self)
- key.add_vpp_config()
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=key)
- self.registry.register(vpp_session, self.logger)
- cli_add_cmd = "bfd udp session add interface %s local-addr %s " \
- "peer-addr %s desired-min-tx %s required-min-rx %s "\
- "detect-mult %s conf-key-id %s bfd-key-id %s"\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4,
- vpp_session.desired_min_tx, vpp_session.required_min_rx,
- vpp_session.detect_mult, key.conf_key_id,
- vpp_session.bfd_key_id)
- self.cli_verify_no_response(cli_add_cmd)
- # 2nd add should fail
- self.cli_verify_response(
- cli_add_cmd,
- "bfd udp session add: `bfd_add_add_session' API call"
- " failed, rv=-101:Duplicate BFD object")
- verify_bfd_session_config(self, vpp_session)
- mod_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip4, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id,
- required_min_rx=2 * vpp_session.required_min_rx,
- desired_min_tx=3 * vpp_session.desired_min_tx,
- detect_mult=4 * vpp_session.detect_mult)
- self.cli_verify_no_response(
- "bfd udp session mod interface %s local-addr %s peer-addr %s "
- "desired-min-tx %s required-min-rx %s detect-mult %s" %
- (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4,
- mod_session.desired_min_tx,
- mod_session.required_min_rx, mod_session.detect_mult))
- verify_bfd_session_config(self, mod_session)
- cli_del_cmd = "bfd udp session del interface %s local-addr %s "\
- "peer-addr %s" % (self.pg0.name,
- self.pg0.local_ip4, self.pg0.remote_ip4)
- self.cli_verify_no_response(cli_del_cmd)
- # 2nd del is expected to fail
- self.cli_verify_response(
- cli_del_cmd,
- "bfd udp session del: `bfd_udp_del_session' API call"
- " failed, rv=-102:No such BFD object")
- self.assertFalse(vpp_session.query_vpp_config())
-
- def test_add_mod_del_bfd_udp6_auth(self):
- """ create/modify/delete IPv6 BFD UDP session (authenticated) """
- key = self.factory.create_random_key(
- self, auth_type=BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- vpp_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip6, af=AF_INET6, sha1_key=key)
- self.registry.register(vpp_session, self.logger)
- cli_add_cmd = "bfd udp session add interface %s local-addr %s " \
- "peer-addr %s desired-min-tx %s required-min-rx %s "\
- "detect-mult %s conf-key-id %s bfd-key-id %s" \
- % (self.pg0.name, self.pg0.local_ip6, self.pg0.remote_ip6,
- vpp_session.desired_min_tx, vpp_session.required_min_rx,
- vpp_session.detect_mult, key.conf_key_id,
- vpp_session.bfd_key_id)
- self.cli_verify_no_response(cli_add_cmd)
- # 2nd add should fail
- self.cli_verify_response(
- cli_add_cmd,
- "bfd udp session add: `bfd_add_add_session' API call"
- " failed, rv=-101:Duplicate BFD object")
- verify_bfd_session_config(self, vpp_session)
- mod_session = VppBFDUDPSession(
- self, self.pg0, self.pg0.remote_ip6, af=AF_INET6, sha1_key=key,
- bfd_key_id=vpp_session.bfd_key_id,
- required_min_rx=2 * vpp_session.required_min_rx,
- desired_min_tx=3 * vpp_session.desired_min_tx,
- detect_mult=4 * vpp_session.detect_mult)
- self.cli_verify_no_response(
- "bfd udp session mod interface %s local-addr %s peer-addr %s "
- "desired-min-tx %s required-min-rx %s detect-mult %s" %
- (self.pg0.name, self.pg0.local_ip6, self.pg0.remote_ip6,
- mod_session.desired_min_tx,
- mod_session.required_min_rx, mod_session.detect_mult))
- verify_bfd_session_config(self, mod_session)
- cli_del_cmd = "bfd udp session del interface %s local-addr %s "\
- "peer-addr %s" % (self.pg0.name,
- self.pg0.local_ip6, self.pg0.remote_ip6)
- self.cli_verify_no_response(cli_del_cmd)
- # 2nd del is expected to fail
- self.cli_verify_response(
- cli_del_cmd,
- "bfd udp session del: `bfd_udp_del_session' API call"
- " failed, rv=-102:No such BFD object")
- self.assertFalse(vpp_session.query_vpp_config())
-
- def test_auth_on_off(self):
- """ turn authentication on and off """
- key = self.factory.create_random_key(
- self, auth_type=BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- auth_session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key)
- session.add_vpp_config()
- cli_activate = \
- "bfd udp session auth activate interface %s local-addr %s "\
- "peer-addr %s conf-key-id %s bfd-key-id %s"\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4,
- key.conf_key_id, auth_session.bfd_key_id)
- self.cli_verify_no_response(cli_activate)
- verify_bfd_session_config(self, auth_session)
- self.cli_verify_no_response(cli_activate)
- verify_bfd_session_config(self, auth_session)
- cli_deactivate = \
- "bfd udp session auth deactivate interface %s local-addr %s "\
- "peer-addr %s "\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4)
- self.cli_verify_no_response(cli_deactivate)
- verify_bfd_session_config(self, session)
- self.cli_verify_no_response(cli_deactivate)
- verify_bfd_session_config(self, session)
-
- def test_auth_on_off_delayed(self):
- """ turn authentication on and off (delayed) """
- key = self.factory.create_random_key(
- self, auth_type=BFDAuthType.meticulous_keyed_sha1)
- key.add_vpp_config()
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- auth_session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
- sha1_key=key)
- session.add_vpp_config()
- cli_activate = \
- "bfd udp session auth activate interface %s local-addr %s "\
- "peer-addr %s conf-key-id %s bfd-key-id %s delayed yes"\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4,
- key.conf_key_id, auth_session.bfd_key_id)
- self.cli_verify_no_response(cli_activate)
- verify_bfd_session_config(self, auth_session)
- self.cli_verify_no_response(cli_activate)
- verify_bfd_session_config(self, auth_session)
- cli_deactivate = \
- "bfd udp session auth deactivate interface %s local-addr %s "\
- "peer-addr %s delayed yes"\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4)
- self.cli_verify_no_response(cli_deactivate)
- verify_bfd_session_config(self, session)
- self.cli_verify_no_response(cli_deactivate)
- verify_bfd_session_config(self, session)
-
- def test_admin_up_down(self):
- """ put session admin-up and admin-down """
- session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4)
- session.add_vpp_config()
- cli_down = \
- "bfd udp session set-flags admin down interface %s local-addr %s "\
- "peer-addr %s "\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4)
- cli_up = \
- "bfd udp session set-flags admin up interface %s local-addr %s "\
- "peer-addr %s "\
- % (self.pg0.name, self.pg0.local_ip4, self.pg0.remote_ip4)
- self.cli_verify_no_response(cli_down)
- verify_bfd_session_config(self, session, state=BFDState.admin_down)
- self.cli_verify_no_response(cli_up)
- verify_bfd_session_config(self, session, state=BFDState.down)
-
- 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()
- self.cli_verify_response("show bfd echo-source",
- "UDP echo source is not set.")
- cli_set = "bfd udp echo-source set interface %s" % self.loopback0.name
- self.cli_verify_no_response(cli_set)
- self.cli_verify_response("show bfd echo-source",
- "UDP echo source is: %s\n"
- "IPv4 address usable as echo source: none\n"
- "IPv6 address usable as echo source: none" %
- self.loopback0.name)
- self.loopback0.config_ip4()
- echo_ip4 = str(ipaddress.IPv4Address(int(ipaddress.IPv4Address(
- self.loopback0.local_ip4)) ^ 1))
- self.cli_verify_response("show bfd echo-source",
- "UDP echo source is: %s\n"
- "IPv4 address usable as echo source: %s\n"
- "IPv6 address usable as echo source: none" %
- (self.loopback0.name, echo_ip4))
- echo_ip6 = str(ipaddress.IPv6Address(int(ipaddress.IPv6Address(
- self.loopback0.local_ip6)) ^ 1))
- self.loopback0.config_ip6()
- self.cli_verify_response("show bfd echo-source",
- "UDP echo source is: %s\n"
- "IPv4 address usable as echo source: %s\n"
- "IPv6 address usable as echo source: %s" %
- (self.loopback0.name, echo_ip4, echo_ip6))
- cli_del = "bfd udp echo-source del"
- self.cli_verify_no_response(cli_del)
- self.cli_verify_response("show bfd echo-source",
- "UDP echo source is not set.")
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/bier/test/test_bier.py b/src/vnet/bier/test/test_bier.py
deleted file mode 100644
index 2f649bbde53..00000000000
--- a/src/vnet/bier/test/test_bier.py
+++ /dev/null
@@ -1,862 +0,0 @@
-#!/usr/bin/env python3
-
-import unittest
-
-from framework import VppTestCase, VppTestRunner, running_extended_tests
-from vpp_ip import DpoProto
-from vpp_ip_route import VppIpRoute, VppRoutePath, \
- VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
- MPLS_LABEL_INVALID, \
- VppMplsLabel, FibPathProto, FibPathType
-from vpp_bier import BIER_HDR_PAYLOAD, VppBierImp, VppBierDispEntry, \
- VppBierDispTable, VppBierTable, VppBierTableID, VppBierRoute
-from vpp_udp_encap import VppUdpEncap
-from vpp_papi import VppEnum
-
-import scapy.compat
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether
-from scapy.layers.inet import IP, UDP
-from scapy.layers.inet6 import IPv6
-from scapy.contrib.mpls import MPLS
-from scapy.contrib.bier import BIER, BIERLength, BIFT
-
-NUM_PKTS = 67
-
-
-class TestBFIB(VppTestCase):
- """ BIER FIB Test Case """
-
- def test_bfib(self):
- """ BFIB Unit Tests """
- error = self.vapi.cli("test bier")
-
- if error:
- self.logger.critical(error)
- self.assertNotIn("Failed", error)
-
-
-class TestBier(VppTestCase):
- """ BIER Test Case """
-
- def setUp(self):
- super(TestBier, self).setUp()
-
- # create 2 pg interfaces
- self.create_pg_interfaces(range(3))
-
- # create the default MPLS table
- self.tables = []
- tbl = VppMplsTable(self, 0)
- tbl.add_vpp_config()
- self.tables.append(tbl)
-
- tbl = VppIpTable(self, 10)
- tbl.add_vpp_config()
- self.tables.append(tbl)
-
- # setup both interfaces
- for i in self.pg_interfaces:
- if i == self.pg2:
- i.set_table_ip4(10)
- i.admin_up()
- i.config_ip4()
- i.resolve_arp()
- i.enable_mpls()
-
- def tearDown(self):
- for i in self.pg_interfaces:
- i.disable_mpls()
- i.unconfig_ip4()
- i.set_table_ip4(0)
- i.admin_down()
- super(TestBier, self).tearDown()
-
- def bier_midpoint(self, hdr_len_id, n_bytes, max_bp):
- """BIER midpoint"""
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(0, 0, hdr_len_id)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- #
- # A packet with no bits set gets dropped
- #
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=hdr_len_id) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
- UDP(sport=1234, dport=1234) /
- Raw())
- pkts = [p]
-
- self.send_and_assert_no_replies(self.pg0, pkts,
- "Empty Bit-String")
-
- #
- # Add a BIER route for each bit-position in the table via a different
- # next-hop. Testing whether the BIER walk and replicate forwarding
- # function works for all bit posisitons.
- #
- nh_routes = []
- bier_routes = []
- for i in range(1, max_bp+1):
- nh = "10.0.%d.%d" % (i / 255, i % 255)
- nh_routes.append(
- VppIpRoute(self, nh, 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[VppMplsLabel(2000+i)])]))
- nh_routes[-1].add_vpp_config()
-
- bier_routes.append(
- VppBierRoute(self, bti, i,
- [VppRoutePath(nh, 0xffffffff,
- labels=[VppMplsLabel(100+i)])]))
- bier_routes[-1].add_vpp_config()
-
- #
- # A packet with all bits set gets replicated once for each bit
- #
- pkt_sizes = [64, 1400]
-
- for pkt_size in pkt_sizes:
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=hdr_len_id,
- BitString=scapy.compat.chb(255)*n_bytes) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
- UDP(sport=1234, dport=1234) /
- Raw(scapy.compat.chb(5) * pkt_size))
- pkts = p
-
- self.pg0.add_stream(pkts)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(max_bp)
-
- for rxp in rx:
- #
- # The packets are not required to be sent in bit-position order
- # when we setup the routes above we used the bit-position to
- # construct the out-label. so use that here to determine the BP
- #
- olabel = rxp[MPLS]
- bp = olabel.label - 2000
-
- blabel = olabel[MPLS].payload
- self.assertEqual(blabel.label, 100+bp)
- self.assertEqual(blabel.ttl, 254)
-
- bier_hdr = blabel[MPLS].payload
-
- self.assertEqual(bier_hdr.id, 5)
- self.assertEqual(bier_hdr.version, 0)
- self.assertEqual(bier_hdr.length, hdr_len_id)
- self.assertEqual(bier_hdr.entropy, 0)
- self.assertEqual(bier_hdr.OAM, 0)
- self.assertEqual(bier_hdr.RSV, 0)
- self.assertEqual(bier_hdr.DSCP, 0)
- self.assertEqual(bier_hdr.Proto, 5)
-
- # The bit-string should consist only of the BP given by i.
- byte_array = [b'\0'] * (n_bytes)
- byte_val = scapy.compat.chb(1 << (bp - 1) % 8)
- byte_pos = n_bytes - (((bp - 1) // 8) + 1)
- byte_array[byte_pos] = byte_val
- bitstring = b''.join(byte_array)
-
- self.assertEqual(len(bitstring), len(bier_hdr.BitString))
- self.assertEqual(bitstring, bier_hdr.BitString)
-
- #
- # cleanup. not strictly necessary, but it's much quicker this way
- # because the bier_fib_dump and ip_fib_dump will be empty when the
- # auto-cleanup kicks in
- #
- for br in bier_routes:
- br.remove_vpp_config()
- for nhr in nh_routes:
- nhr.remove_vpp_config()
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_midpoint_1024(self):
- """BIER midpoint BSL:1024"""
- self.bier_midpoint(BIERLength.BIER_LEN_1024, 128, 1024)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_midpoint_512(self):
- """BIER midpoint BSL:512"""
- self.bier_midpoint(BIERLength.BIER_LEN_512, 64, 512)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_midpoint_256(self):
- """BIER midpoint BSL:256"""
- self.bier_midpoint(BIERLength.BIER_LEN_256, 32, 256)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_midpoint_128(self):
- """BIER midpoint BSL:128"""
- self.bier_midpoint(BIERLength.BIER_LEN_128, 16, 128)
-
- def test_bier_midpoint_64(self):
- """BIER midpoint BSL:64"""
- self.bier_midpoint(BIERLength.BIER_LEN_64, 8, 64)
-
- def test_bier_load_balance(self):
- """BIER load-balance"""
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_64)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- #
- # packets with varying entropy
- #
- pkts = []
- for ii in range(257):
- pkts.append((Ether(dst=self.pg0.local_mac,
- src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=BIERLength.BIER_LEN_64,
- entropy=ii,
- BitString=scapy.compat.chb(255)*16) /
- IPv6(src=self.pg0.remote_ip6,
- dst=self.pg0.remote_ip6) /
- UDP(sport=1234, dport=1234) /
- Raw()))
-
- #
- # 4 next hops
- #
- nhs = [{'ip': "10.0.0.1", 'label': 201},
- {'ip': "10.0.0.2", 'label': 202},
- {'ip': "10.0.0.3", 'label': 203},
- {'ip': "10.0.0.4", 'label': 204}]
-
- for nh in nhs:
- ipr = VppIpRoute(
- self, nh['ip'], 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[VppMplsLabel(nh['label'])])])
- ipr.add_vpp_config()
-
- bier_route = VppBierRoute(
- self, bti, 1,
- [VppRoutePath(nhs[0]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]),
- VppRoutePath(nhs[1]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)])])
- bier_route.add_vpp_config()
-
- rx = self.send_and_expect(self.pg0, pkts, self.pg1)
-
- #
- # we should have recieved a packet from each neighbor
- #
- for nh in nhs[:2]:
- self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))
-
- #
- # add the other paths
- #
- bier_route.update_paths(
- [VppRoutePath(nhs[0]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]),
- VppRoutePath(nhs[1]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]),
- VppRoutePath(nhs[2]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]),
- VppRoutePath(nhs[3]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)])])
-
- rx = self.send_and_expect(self.pg0, pkts, self.pg1)
-
- for nh in nhs:
- self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))
-
- #
- # remove first two paths
- #
- bier_route.remove_path(VppRoutePath(nhs[0]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]))
- bier_route.remove_path(VppRoutePath(nhs[1]['ip'], 0xffffffff,
- labels=[VppMplsLabel(101)]))
-
- rx = self.send_and_expect(self.pg0, pkts, self.pg1)
- for nh in nhs[2:]:
- self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))
-
- #
- # remove the last of the paths, deleteing the entry
- #
- bier_route.remove_all_paths()
-
- self.send_and_assert_no_replies(self.pg0, pkts)
-
- def test_bier_head(self):
- """BIER head"""
-
- MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
- MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- #
- # 2 bit positions via two next hops
- #
- nh1 = "10.0.0.1"
- nh2 = "10.0.0.2"
- ip_route_1 = VppIpRoute(self, nh1, 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[VppMplsLabel(2001)])])
- ip_route_2 = VppIpRoute(self, nh2, 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[VppMplsLabel(2002)])])
- ip_route_1.add_vpp_config()
- ip_route_2.add_vpp_config()
-
- bier_route_1 = VppBierRoute(self, bti, 1,
- [VppRoutePath(nh1, 0xffffffff,
- labels=[VppMplsLabel(101)])])
- bier_route_2 = VppBierRoute(self, bti, 2,
- [VppRoutePath(nh2, 0xffffffff,
- labels=[VppMplsLabel(102)])])
- bier_route_1.add_vpp_config()
- bier_route_2.add_vpp_config()
-
- #
- # An imposition object with both bit-positions set
- #
- bi = VppBierImp(self, bti, 333, scapy.compat.chb(0x3) * 32)
- bi.add_vpp_config()
-
- #
- # Add a multicast route that will forward into the BIER doamin
- #
- route_ing_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg0.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
- VppMRoutePath(0xffffffff,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- type=FibPathType.FIB_PATH_TYPE_BIER_IMP,
- bier_imp=bi.bi_index)])
- route_ing_232_1_1_1.add_vpp_config()
-
- #
- # inject an IP packet. We expect it to be BIER encapped and
- # replicated.
- #
- p = (Ether(dst=self.pg0.local_mac,
- src=self.pg0.remote_mac) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234))
-
- self.pg0.add_stream([p])
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(2)
-
- #
- # Encap Stack is; eth, MPLS, MPLS, BIER
- #
- igp_mpls = rx[0][MPLS]
- self.assertEqual(igp_mpls.label, 2001)
- self.assertEqual(igp_mpls.ttl, 64)
- self.assertEqual(igp_mpls.s, 0)
- bier_mpls = igp_mpls[MPLS].payload
- self.assertEqual(bier_mpls.label, 101)
- self.assertEqual(bier_mpls.ttl, 64)
- self.assertEqual(bier_mpls.s, 1)
- self.assertEqual(rx[0][BIER].length, 2)
-
- igp_mpls = rx[1][MPLS]
- self.assertEqual(igp_mpls.label, 2002)
- self.assertEqual(igp_mpls.ttl, 64)
- self.assertEqual(igp_mpls.s, 0)
- bier_mpls = igp_mpls[MPLS].payload
- self.assertEqual(bier_mpls.label, 102)
- self.assertEqual(bier_mpls.ttl, 64)
- self.assertEqual(bier_mpls.s, 1)
- self.assertEqual(rx[0][BIER].length, 2)
-
- def test_bier_tail(self):
- """BIER Tail"""
-
- MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
- MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- #
- # disposition table
- #
- bdt = VppBierDispTable(self, 8)
- bdt.add_vpp_config()
-
- #
- # BIER route in table that's for-us
- #
- bier_route_1 = VppBierRoute(
- self, bti, 1,
- [VppRoutePath("0.0.0.0",
- 0xffffffff,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- nh_table_id=8)])
- bier_route_1.add_vpp_config()
-
- #
- # An entry in the disposition table
- #
- bier_de_1 = VppBierDispEntry(self, bdt.id, 99,
- BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
- FibPathProto.FIB_PATH_NH_PROTO_BIER,
- "0.0.0.0", 0, rpf_id=8192)
- bier_de_1.add_vpp_config()
-
- #
- # A multicast route to forward post BIER disposition
- #
- route_eg_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg1.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
- route_eg_232_1_1_1.add_vpp_config()
- route_eg_232_1_1_1.update_rpf_id(8192)
-
- #
- # A packet with all bits set gets spat out to BP:1
- #
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=BIERLength.BIER_LEN_256,
- BitString=scapy.compat.chb(255)*32,
- BFRID=99) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw())
-
- self.send_and_expect(self.pg0, [p], self.pg1)
-
- #
- # A packet that does not match the Disposition entry gets dropped
- #
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=BIERLength.BIER_LEN_256,
- BitString=scapy.compat.chb(255)*32,
- BFRID=77) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw())
- self.send_and_assert_no_replies(self.pg0, p*2,
- "no matching disposition entry")
-
- #
- # Add the default route to the disposition table
- #
- bier_de_2 = VppBierDispEntry(self, bdt.id, 0,
- BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
- FibPathProto.FIB_PATH_NH_PROTO_BIER,
- "0.0.0.0", 0, rpf_id=8192)
- bier_de_2.add_vpp_config()
-
- #
- # now the previous packet is forwarded
- #
- self.send_and_expect(self.pg0, [p], self.pg1)
-
- #
- # A multicast route to forward post BIER disposition that needs
- # a check against sending back into the BIER core
- #
- bi = VppBierImp(self, bti, 333, scapy.compat.chb(0x3) * 32)
- bi.add_vpp_config()
-
- route_eg_232_1_1_2 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.2", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(0xffffffff,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
- proto=DpoProto.DPO_PROTO_BIER,
- type=FibPathType.FIB_PATH_TYPE_BIER_IMP,
- bier_imp=bi.bi_index),
- VppMRoutePath(self.pg1.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
- route_eg_232_1_1_2.add_vpp_config()
- route_eg_232_1_1_2.update_rpf_id(8192)
-
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- MPLS(label=77, ttl=255) /
- BIER(length=BIERLength.BIER_LEN_256,
- BitString=scapy.compat.chb(255)*32,
- BFRID=77) /
- IP(src="1.1.1.1", dst="232.1.1.2") /
- UDP(sport=1234, dport=1234) /
- Raw())
- self.send_and_expect(self.pg0, [p], self.pg1)
-
- def bier_e2e(self, hdr_len_id, n_bytes, max_bp):
- """ BIER end-to-end"""
-
- MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
- MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(0, 0, hdr_len_id)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- lowest = [b'\0'] * (n_bytes)
- lowest[-1] = scapy.compat.chb(1)
- highest = [b'\0'] * (n_bytes)
- highest[0] = scapy.compat.chb(128)
-
- #
- # Impostion Sets bit strings
- #
- bi_low = VppBierImp(self, bti, 333, lowest)
- bi_low.add_vpp_config()
- bi_high = VppBierImp(self, bti, 334, highest)
- bi_high.add_vpp_config()
-
- #
- # Add a multicast route that will forward into the BIER doamin
- #
- route_ing_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg0.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
- VppMRoutePath(0xffffffff,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- type=FibPathType.FIB_PATH_TYPE_BIER_IMP,
- bier_imp=bi_low.bi_index)])
- route_ing_232_1_1_1.add_vpp_config()
- route_ing_232_1_1_2 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.2", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg0.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
- VppMRoutePath(0xffffffff,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- type=FibPathType.FIB_PATH_TYPE_BIER_IMP,
- bier_imp=bi_high.bi_index)])
- route_ing_232_1_1_2.add_vpp_config()
-
- #
- # disposition table 8
- #
- bdt = VppBierDispTable(self, 8)
- bdt.add_vpp_config()
-
- #
- # BIER routes in table that are for-us, resolving through
- # disp table 8.
- #
- bier_route_1 = VppBierRoute(
- self, bti, 1,
- [VppRoutePath("0.0.0.0",
- 0xffffffff,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- nh_table_id=8)])
- bier_route_1.add_vpp_config()
- bier_route_max = VppBierRoute(
- self, bti, max_bp,
- [VppRoutePath("0.0.0.0",
- 0xffffffff,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- nh_table_id=8)])
- bier_route_max.add_vpp_config()
-
- #
- # An entry in the disposition table for sender 333
- # lookup in VRF 10
- #
- bier_de_1 = VppBierDispEntry(self, bdt.id, 333,
- BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
- FibPathProto.FIB_PATH_NH_PROTO_BIER,
- "0.0.0.0", 10, rpf_id=8192)
- bier_de_1.add_vpp_config()
- bier_de_1 = VppBierDispEntry(self, bdt.id, 334,
- BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
- FibPathProto.FIB_PATH_NH_PROTO_BIER,
- "0.0.0.0", 10, rpf_id=8193)
- bier_de_1.add_vpp_config()
-
- #
- # Add a multicast routes that will forward the traffic
- # post-disposition
- #
- route_eg_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- table_id=10,
- paths=[VppMRoutePath(self.pg1.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
- route_eg_232_1_1_1.add_vpp_config()
- route_eg_232_1_1_1.update_rpf_id(8192)
- route_eg_232_1_1_2 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.2", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- table_id=10,
- paths=[VppMRoutePath(self.pg1.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
- route_eg_232_1_1_2.add_vpp_config()
- route_eg_232_1_1_2.update_rpf_id(8193)
-
- #
- # inject a packet in VRF-0. We expect it to be BIER encapped,
- # replicated, then hit the disposition and be forwarded
- # out of VRF 10, i.e. on pg1
- #
- p = (Ether(dst=self.pg0.local_mac,
- src=self.pg0.remote_mac) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw(scapy.compat.chb(5) * 32))
-
- rx = self.send_and_expect(self.pg0, p*NUM_PKTS, self.pg1)
-
- self.assertEqual(rx[0][IP].src, "1.1.1.1")
- self.assertEqual(rx[0][IP].dst, "232.1.1.1")
-
- p = (Ether(dst=self.pg0.local_mac,
- src=self.pg0.remote_mac) /
- IP(src="1.1.1.1", dst="232.1.1.2") /
- UDP(sport=1234, dport=1234) /
- Raw(scapy.compat.chb(5) * 512))
-
- rx = self.send_and_expect(self.pg0, p*NUM_PKTS, self.pg1)
- self.assertEqual(rx[0][IP].src, "1.1.1.1")
- self.assertEqual(rx[0][IP].dst, "232.1.1.2")
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_e2e_1024(self):
- """ BIER end-to-end BSL:1024"""
- self.bier_e2e(BIERLength.BIER_LEN_1024, 128, 1024)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_e2e_512(self):
- """ BIER end-to-end BSL:512"""
- self.bier_e2e(BIERLength.BIER_LEN_512, 64, 512)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_e2e_256(self):
- """ BIER end-to-end BSL:256"""
- self.bier_e2e(BIERLength.BIER_LEN_256, 32, 256)
-
- @unittest.skipUnless(running_extended_tests, "part of extended tests")
- def test_bier_e2e_128(self):
- """ BIER end-to-end BSL:128"""
- self.bier_e2e(BIERLength.BIER_LEN_128, 16, 128)
-
- def test_bier_e2e_64(self):
- """ BIER end-to-end BSL:64"""
- self.bier_e2e(BIERLength.BIER_LEN_64, 8, 64)
-
- def test_bier_head_o_udp(self):
- """BIER head over UDP"""
-
- MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
- MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
-
- #
- # Add a BIER table for sub-domain 1, set 0, and BSL 256
- #
- bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
- bt = VppBierTable(self, bti, 77)
- bt.add_vpp_config()
-
- #
- # 1 bit positions via 1 next hops
- #
- nh1 = "10.0.0.1"
- ip_route = VppIpRoute(self, nh1, 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[VppMplsLabel(2001)])])
- ip_route.add_vpp_config()
-
- udp_encap = VppUdpEncap(self,
- self.pg0.local_ip4,
- nh1,
- 330, 8138)
- udp_encap.add_vpp_config()
-
- bier_route = VppBierRoute(
- self, bti, 1,
- [VppRoutePath("0.0.0.0",
- 0xFFFFFFFF,
- type=FibPathType.FIB_PATH_TYPE_UDP_ENCAP,
- next_hop_id=udp_encap.id)])
- bier_route.add_vpp_config()
-
- #
- # An 2 imposition objects with all bit-positions set
- # only use the second, but creating 2 tests with a non-zero
- # value index in the route add
- #
- bi = VppBierImp(self, bti, 333, scapy.compat.chb(0xff) * 32)
- bi.add_vpp_config()
- bi2 = VppBierImp(self, bti, 334, scapy.compat.chb(0xff) * 32)
- bi2.add_vpp_config()
-
- #
- # Add a multicast route that will forward into the BIER doamin
- #
- route_ing_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg0.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
- VppMRoutePath(0xffffffff,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- type=FibPathType.FIB_PATH_TYPE_BIER_IMP,
- bier_imp=bi2.bi_index)])
- route_ing_232_1_1_1.add_vpp_config()
-
- #
- # inject a packet an IP. We expect it to be BIER and UDP encapped,
- #
- p = (Ether(dst=self.pg0.local_mac,
- src=self.pg0.remote_mac) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234))
-
- self.pg0.add_stream([p])
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(1)
-
- #
- # Encap Stack is, eth, IP, UDP, BIFT, BIER
- #
- self.assertEqual(rx[0][IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[0][IP].dst, nh1)
- self.assertEqual(rx[0][UDP].sport, 330)
- self.assertEqual(rx[0][UDP].dport, 8138)
- self.assertEqual(rx[0][BIFT].bsl, BIERLength.BIER_LEN_256)
- self.assertEqual(rx[0][BIFT].sd, 1)
- self.assertEqual(rx[0][BIFT].set, 0)
- self.assertEqual(rx[0][BIFT].ttl, 64)
- self.assertEqual(rx[0][BIER].length, 2)
-
- def test_bier_tail_o_udp(self):
- """BIER Tail over UDP"""
-
- MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
- MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
-
- #
- # Add a BIER table for sub-domain 0, set 0, and BSL 256
- #
- bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
- bt = VppBierTable(self, bti, MPLS_LABEL_INVALID)
- bt.add_vpp_config()
-
- #
- # disposition table
- #
- bdt = VppBierDispTable(self, 8)
- bdt.add_vpp_config()
-
- #
- # BIER route in table that's for-us
- #
- bier_route_1 = VppBierRoute(
- self, bti, 1,
- [VppRoutePath("0.0.0.0",
- 0xffffffff,
- proto=FibPathProto.FIB_PATH_NH_PROTO_BIER,
- nh_table_id=8)])
- bier_route_1.add_vpp_config()
-
- #
- # An entry in the disposition table
- #
- bier_de_1 = VppBierDispEntry(self, bdt.id, 99,
- BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
- FibPathProto.FIB_PATH_NH_PROTO_BIER,
- "0.0.0.0", 0, rpf_id=8192)
- bier_de_1.add_vpp_config()
-
- #
- # A multicast route to forward post BIER disposition
- #
- route_eg_232_1_1_1 = VppIpMRoute(
- self,
- "0.0.0.0",
- "232.1.1.1", 32,
- MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
- paths=[VppMRoutePath(self.pg1.sw_if_index,
- MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
- route_eg_232_1_1_1.add_vpp_config()
- route_eg_232_1_1_1.update_rpf_id(8192)
-
- #
- # A packet with all bits set gets spat out to BP:1
- #
- p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
- UDP(sport=333, dport=8138) /
- BIFT(sd=1, set=0, bsl=2, ttl=255) /
- BIER(length=BIERLength.BIER_LEN_256,
- BitString=scapy.compat.chb(255)*32,
- BFRID=99) /
- IP(src="1.1.1.1", dst="232.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw())
-
- rx = self.send_and_expect(self.pg0, [p], self.pg1)
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/bier/test/vpp_bier.py b/src/vnet/bier/test/vpp_bier.py
deleted file mode 100644
index 6e087a8ee0b..00000000000
--- a/src/vnet/bier/test/vpp_bier.py
+++ /dev/null
@@ -1,293 +0,0 @@
-"""
- BIER Tables and Routes
-"""
-
-import socket
-from vpp_object import VppObject
-from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath, VppMplsLabel
-
-
-class BIER_HDR_PAYLOAD:
- BIER_HDR_PROTO_MPLS_DOWN_STREAM = 1
- BIER_HDR_PROTO_MPLS_UP_STREAM = 2
- BIER_HDR_PROTO_ETHERNET = 3
- BIER_HDR_PROTO_IPV4 = 4
- BIER_HDR_PROTO_IPV6 = 5
- BIER_HDR_PROTO_VXLAN = 6
- BIER_HDR_PROTO_CTRL = 7
- BIER_HDR_PROTO_OAM = 8
-
-
-class VppBierTableID():
- def __init__(self, sub_domain_id, set_id, hdr_len_id):
- self.set_id = set_id
- self.sub_domain_id = sub_domain_id
- self.hdr_len_id = hdr_len_id
-
-
-def find_bier_table(test, bti):
- tables = test.vapi.bier_table_dump()
- for t in tables:
- if bti.set_id == t.bt_tbl_id.bt_set \
- and bti.sub_domain_id == t.bt_tbl_id.bt_sub_domain \
- and bti.hdr_len_id == t.bt_tbl_id.bt_hdr_len_id:
- return True
- return False
-
-
-def find_bier_route(test, bti, bp):
- routes = test.vapi.bier_route_dump(bti)
- for r in routes:
- if bti.set_id == r.br_route.br_tbl_id.bt_set \
- and bti.sub_domain_id == r.br_route.br_tbl_id.bt_sub_domain \
- and bti.hdr_len_id == r.br_route.br_tbl_id.bt_hdr_len_id \
- and bp == r.br_route.br_bp:
- return True
- return False
-
-
-def find_bier_disp_table(test, bdti):
- tables = test.vapi.bier_disp_table_dump()
- for t in tables:
- if bdti == t.bdt_tbl_id:
- return True
- return False
-
-
-def find_bier_disp_entry(test, bdti, bp):
- entries = test.vapi.bier_disp_entry_dump(bdti)
- for e in entries:
- if bp == e.bde_bp \
- and bdti == e.bde_tbl_id:
- return True
- return False
-
-
-def find_bier_imp(test, bti, bp):
- imps = test.vapi.bier_imp_dump()
- for i in imps:
- if bti.set_id == i.bi_tbl_id.bt_set \
- and bti.sub_domain_id == i.bi_tbl_id.bt_sub_domain \
- and bti.hdr_len_id == i.bi_tbl_id.bt_hdr_len_id \
- and bp == i.bi_src:
- return True
- return False
-
-
-class VppBierTable(VppObject):
- """
- BIER Table
- """
-
- def __init__(self, test, id, mpls_label):
- self._test = test
- self.id = id
- self.mpls_label = mpls_label
-
- def add_vpp_config(self):
- self._test.vapi.bier_table_add_del(
- self.id,
- self.mpls_label,
- is_add=1)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self._test.vapi.bier_table_add_del(
- self.id,
- self.mpls_label,
- is_add=0)
-
- def object_id(self):
- return "bier-table;[%d:%d:%d]" % (self.id.set_id,
- self.id.sub_domain_id,
- self.id.hdr_len_id)
-
- def query_vpp_config(self):
- return find_bier_table(self._test, self.id)
-
-
-class VppBierRoute(VppObject):
- """
- BIER route
- """
-
- def __init__(self, test, tbl_id, bp, paths):
- self._test = test
- self.tbl_id = tbl_id
- self.bp = bp
- self.paths = paths
- self.encoded_paths = []
- for path in self.paths:
- self.encoded_paths.append(path.encode())
-
- def add_vpp_config(self):
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- self.encoded_paths,
- is_add=1)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- self.encoded_paths,
- is_add=0)
-
- def update_paths(self, paths):
- self.paths = paths
- self.encoded_paths = []
- for path in self.paths:
- self.encoded_paths.append(path.encode())
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- self.encoded_paths,
- is_replace=1)
-
- def add_path(self, path):
- self.encoded_paths.append(path.encode())
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- [path.encode()],
- is_add=1,
- is_replace=0)
- self.paths.append(path)
- self._test.registry.register(self, self._test.logger)
-
- def remove_path(self, path):
- self.encoded_paths.remove(path.encode())
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- [path.encode()],
- is_add=0,
- is_replace=0)
- self.paths.remove(path)
-
- def remove_all_paths(self):
- self._test.vapi.bier_route_add_del(
- self.tbl_id,
- self.bp,
- [],
- is_add=0,
- is_replace=1)
- self.paths = []
-
- def object_id(self):
- return "bier-route;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
- self.tbl_id.sub_domain_id,
- self.tbl_id.hdr_len_id,
- self.bp)
-
- def query_vpp_config(self):
- return find_bier_route(self._test, self.tbl_id, self.bp)
-
-
-class VppBierImp(VppObject):
- """
- BIER route
- """
-
- def __init__(self, test, tbl_id, src, ibytes):
- self._test = test
- self.tbl_id = tbl_id
- self.ibytes = ibytes
- self.src = src
-
- def add_vpp_config(self):
- res = self._test.vapi.bier_imp_add(
- self.tbl_id,
- self.src,
- self.ibytes)
- self.bi_index = res.bi_index
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self._test.vapi.bier_imp_del(
- self.bi_index)
-
- def object_id(self):
- return "bier-imp;[%d:%d:%d:%d]" % (self.tbl_id.set_id,
- self.tbl_id.sub_domain_id,
- self.tbl_id.hdr_len_id,
- self.src)
-
- def query_vpp_config(self):
- return find_bier_imp(self._test, self.tbl_id, self.src)
-
-
-class VppBierDispTable(VppObject):
- """
- BIER Disposition Table
- """
-
- def __init__(self, test, id):
- self._test = test
- self.id = id
-
- def add_vpp_config(self):
- self._test.vapi.bier_disp_table_add_del(
- self.id,
- is_add=1)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self._test.vapi.bier_disp_table_add_del(
- self.id,
- is_add=0)
-
- def object_id(self):
- return "bier-disp-table;[%d]" % (self.id)
-
- def query_vpp_config(self):
- return find_bier_disp_table(self._test, self.id)
-
-
-class VppBierDispEntry(VppObject):
- """
- BIER Disposition Entry
- """
-
- def __init__(self, test, tbl_id, bp, payload_proto, nh_proto,
- nh, nh_tbl, rpf_id=~0):
- self._test = test
- self.tbl_id = tbl_id
- self.nh_tbl = nh_tbl
- self.nh_proto = nh_proto
- self.bp = bp
- self.payload_proto = payload_proto
- self.rpf_id = rpf_id
- self.nh = socket.inet_pton(socket.AF_INET, nh)
-
- def add_vpp_config(self):
- self._test.vapi.bier_disp_entry_add_del(
- self.tbl_id,
- self.bp,
- self.payload_proto,
- self.nh_proto,
- self.nh,
- self.nh_tbl,
- self.rpf_id,
- is_add=1)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self._test.vapi.bier_disp_entry_add_del(
- self.tbl_id,
- self.bp,
- self.payload_proto,
- self.nh_proto,
- self.nh,
- self.nh_tbl,
- self.rpf_id,
- is_add=0)
-
- def object_id(self):
- return "bier-disp-entry;[%d:%d]" % (self.tbl_id,
- self.bp)
-
- def query_vpp_config(self):
- return find_bier_disp_entry(self._test, self.tbl_id, self.bp)
diff --git a/src/vnet/bonding/test/test_bond.py b/src/vnet/bonding/test/test_bond.py
deleted file mode 100644
index 5df86ae5b0f..00000000000
--- a/src/vnet/bonding/test/test_bond.py
+++ /dev/null
@@ -1,321 +0,0 @@
-#!/usr/bin/env python3
-
-import socket
-import unittest
-
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether
-from scapy.layers.inet import IP, UDP
-
-from framework import VppTestCase, VppTestRunner
-from vpp_bond_interface import VppBondInterface
-from vpp_papi import MACAddress, VppEnum
-
-
-class TestBondInterface(VppTestCase):
- """Bond Test Case
-
- """
-
- @classmethod
- def setUpClass(cls):
- super(TestBondInterface, cls).setUpClass()
- # Test variables
- cls.pkts_per_burst = 257 # Number of packets per burst
- # create 3 pg interfaces
- cls.create_pg_interfaces(range(4))
-
- # packet sizes
- cls.pg_if_packet_sizes = [64, 512, 1518] # , 9018]
-
- # setup all interfaces
- for i in cls.pg_interfaces:
- i.admin_up()
-
- @classmethod
- def tearDownClass(cls):
- super(TestBondInterface, cls).tearDownClass()
-
- def setUp(self):
- super(TestBondInterface, self).setUp()
-
- def tearDown(self):
- super(TestBondInterface, self).tearDown()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.ppcli("show interface"))
-
- def test_bond_traffic(self):
- """ Bond traffic test """
-
- # topology
- #
- # RX-> TX->
- #
- # pg2 ------+ +------pg0 (member)
- # | |
- # BondEthernet0 (10.10.10.1)
- # | |
- # pg3 ------+ +------pg1 (memberx)
- #
-
- # create interface (BondEthernet0)
- # self.logger.info("create bond")
- bond0_mac = "02:fe:38:30:59:3c"
- mac = MACAddress(bond0_mac).packed
- bond0 = VppBondInterface(
- self,
- mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_XOR,
- lb=VppEnum.vl_api_bond_lb_algo_t.BOND_API_LB_ALGO_L34,
- numa_only=0,
- use_custom_mac=1,
- mac_address=mac)
- bond0.add_vpp_config()
- bond0.admin_up()
- self.vapi.sw_interface_add_del_address(
- sw_if_index=bond0.sw_if_index,
- prefix="10.10.10.1/24")
-
- self.pg2.config_ip4()
- self.pg2.resolve_arp()
- self.pg3.config_ip4()
- self.pg3.resolve_arp()
-
- self.logger.info(self.vapi.cli("show interface"))
- self.logger.info(self.vapi.cli("show interface address"))
- self.logger.info(self.vapi.cli("show ip neighbors"))
-
- # add member pg0 and pg1 to BondEthernet0
- self.logger.info("bond add member interface pg0 to BondEthernet0")
- bond0.add_member_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
- self.logger.info("bond add_member interface pg1 to BondEthernet0")
- bond0.add_member_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index)
-
- # verify both members in BondEthernet0
- if_dump = self.vapi.sw_member_interface_dump(bond0.sw_if_index)
- self.assertTrue(self.pg0.is_interface_config_in_dump(if_dump))
- self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))
-
- # generate a packet from pg2 -> BondEthernet0 -> pg1
- # BondEthernet0 TX hashes this packet to pg1
- p2 = (Ether(src=bond0_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.local_ip4, dst="10.10.10.12") /
- UDP(sport=1235, dport=1235) /
- Raw(b'\xa5' * 100))
- self.pg2.add_stream(p2)
-
- # generate a packet from pg3 -> BondEthernet0 -> pg0
- # BondEthernet0 TX hashes this packet to pg0
- # notice the ip address and ports are different than p2 packet
- p3 = (Ether(src=bond0_mac, dst=self.pg3.local_mac) /
- IP(src=self.pg3.local_ip4, dst="10.10.10.11") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- self.pg3.add_stream(p3)
-
- self.pg_enable_capture(self.pg_interfaces)
-
- # set up the static arp entries pointing to the BondEthernet0 interface
- # so that it does not try to resolve the ip address
- self.logger.info(self.vapi.cli(
- "set ip neighbor static BondEthernet0 10.10.10.12 abcd.abcd.0002"))
- self.logger.info(self.vapi.cli(
- "set ip neighbor static BondEthernet0 10.10.10.11 abcd.abcd.0004"))
-
- # clear the interface counters
- self.logger.info(self.vapi.cli("clear interfaces"))
-
- self.pg_start()
-
- self.logger.info("check the interface counters")
-
- # verify counters
-
- # BondEthernet0 tx bytes = 284
- intfs = self.vapi.cli("show interface BondEthernet0").split("\n")
- found = 0
- for intf in intfs:
- if "tx bytes" in intf and "284" in intf:
- found = 1
- self.assertEqual(found, 1)
-
- # BondEthernet0 tx bytes = 284
- intfs = self.vapi.cli("show interface BondEthernet0").split("\n")
- found = 0
- for intf in intfs:
- if "tx bytes" in intf and "284" in intf:
- found = 1
- self.assertEqual(found, 1)
-
- # pg2 rx bytes = 142
- intfs = self.vapi.cli("show interface pg2").split("\n")
- found = 0
- for intf in intfs:
- if "rx bytes" in intf and "142" in intf:
- found = 1
- self.assertEqual(found, 1)
-
- # pg3 rx bytes = 142
- intfs = self.vapi.cli("show interface pg3").split("\n")
- found = 0
- for intf in intfs:
- if "rx bytes" in intf and "142" in intf:
- found = 1
- self.assertEqual(found, 1)
-
- bond0.remove_vpp_config()
-
- def test_bond_add_member(self):
- """ Bond add_member/detach member test """
-
- # create interface (BondEthernet0) and set bond mode to LACP
- self.logger.info("create bond")
- bond0 = VppBondInterface(
- self,
- mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP,
- enable_gso=0)
- bond0.add_vpp_config()
- bond0.admin_up()
-
- # verify that interfaces can be added as_member and detached two times
- for i in range(2):
- # verify pg0 and pg1 not in BondEthernet0
- if_dump = self.vapi.sw_member_interface_dump(bond0.sw_if_index)
- self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
- self.assertFalse(self.pg1.is_interface_config_in_dump(if_dump))
-
- # add_member pg0 and pg1 to BondEthernet0
- self.logger.info("bond add_member interface pg0 to BondEthernet0")
- bond0.add_member_vpp_bond_interface(
- sw_if_index=self.pg0.sw_if_index,
- is_passive=0,
- is_long_timeout=0)
-
- self.logger.info("bond add_member interface pg1 to BondEthernet0")
- bond0.add_member_vpp_bond_interface(
- sw_if_index=self.pg1.sw_if_index,
- is_passive=0,
- is_long_timeout=0)
- # verify both members in BondEthernet0
- if_dump = self.vapi.sw_member_interface_dump(bond0.sw_if_index)
- self.assertTrue(self.pg0.is_interface_config_in_dump(if_dump))
- self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))
-
- # detach interface pg0
- self.logger.info("detach interface pg0")
- bond0.detach_vpp_bond_interface(sw_if_index=self.pg0.sw_if_index)
-
- # verify pg0 is not in BondEthernet0, but pg1 is
- if_dump = self.vapi.sw_member_interface_dump(bond0.sw_if_index)
- self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
- self.assertTrue(self.pg1.is_interface_config_in_dump(if_dump))
-
- # detach interface pg1
- self.logger.info("detach interface pg1")
- bond0.detach_vpp_bond_interface(sw_if_index=self.pg1.sw_if_index)
-
- # verify pg0 and pg1 not in BondEthernet0
- if_dump = self.vapi.sw_member_interface_dump(bond0.sw_if_index)
- self.assertFalse(self.pg0.is_interface_config_in_dump(if_dump))
- self.assertFalse(self.pg1.is_interface_config_in_dump(if_dump))
-
- bond0.remove_vpp_config()
-
- def test_bond(self):
- """ Bond add/delete interface test """
- self.logger.info("Bond add interfaces")
-
- # create interface 1 (BondEthernet0)
- bond0 = VppBondInterface(
- self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_LACP)
- bond0.add_vpp_config()
- bond0.admin_up()
-
- # create interface 2 (BondEthernet1)
- bond1 = VppBondInterface(
- self, mode=VppEnum.vl_api_bond_mode_t.BOND_API_MODE_XOR)
- bond1.add_vpp_config()
- bond1.admin_up()
-
- # verify both interfaces in the show
- ifs = self.vapi.cli("show interface")
- self.assertIn('BondEthernet0', ifs)
- self.assertIn('BondEthernet1', ifs)
-
- # verify they are in the dump also
- if_dump = self.vapi.sw_bond_interface_dump(sw_if_index=0xFFFFFFFF)
- self.assertTrue(bond0.is_interface_config_in_dump(if_dump))
- self.assertTrue(bond1.is_interface_config_in_dump(if_dump))
-
- # delete BondEthernet1
- self.logger.info("Deleting BondEthernet1")
- bond1.remove_vpp_config()
-
- self.logger.info("Verifying BondEthernet1 is deleted")
-
- ifs = self.vapi.cli("show interface")
- # verify BondEthernet0 still in the show
- self.assertIn('BondEthernet0', ifs)
-
- # verify BondEthernet1 not in the show
- self.assertNotIn('BondEthernet1', ifs)
-
- # verify BondEthernet1 is not in the dump
- if_dump = self.vapi.sw_bond_interface_dump(sw_if_index=0xFFFFFFFF)
- self.assertFalse(bond1.is_interface_config_in_dump(if_dump))
-
- # verify BondEthernet0 is still in the dump
- self.assertTrue(bond0.is_interface_config_in_dump(if_dump))
-
- # delete BondEthernet0
- self.logger.info("Deleting BondEthernet0")
- bond0.remove_vpp_config()
-
- self.logger.info("Verifying BondEthernet0 is deleted")
-
- # verify BondEthernet0 not in the show
- ifs = self.vapi.cli("show interface")
- self.assertNotIn('BondEthernet0', ifs)
-
- # verify BondEthernet0 is not in the dump
- if_dump = self.vapi.sw_bond_interface_dump(
- sw_if_index=bond0.sw_if_index)
- self.assertFalse(bond0.is_interface_config_in_dump(if_dump))
-
- def test_bond_link(self):
- """ Bond hw interface link state test """
-
- # for convenience
- bond_modes = VppEnum.vl_api_bond_mode_t
- intf_flags = VppEnum.vl_api_if_status_flags_t
-
- # create interface 1 (BondEthernet0)
- self.logger.info("Create bond interface")
- # use round-robin mode to avoid negotiation required by LACP
- bond0 = VppBondInterface(self,
- mode=bond_modes.BOND_API_MODE_ROUND_ROBIN)
- bond0.add_vpp_config()
-
- # set bond admin up.
- self.logger.info("set interface BondEthernet0 admin up")
- bond0.admin_up()
- # confirm link up
- bond0.assert_interface_state(intf_flags.IF_STATUS_API_FLAG_ADMIN_UP,
- intf_flags.IF_STATUS_API_FLAG_LINK_UP)
-
- # toggle bond admin state
- self.logger.info("toggle interface BondEthernet0")
- bond0.admin_down()
- bond0.admin_up()
-
- # confirm link is still up
- bond0.assert_interface_state(intf_flags.IF_STATUS_API_FLAG_ADMIN_UP,
- intf_flags.IF_STATUS_API_FLAG_LINK_UP)
-
- # delete BondEthernet0
- self.logger.info("Deleting BondEthernet0")
- bond0.remove_vpp_config()
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/bonding/test/vpp_bond_interface.py b/src/vnet/bonding/test/vpp_bond_interface.py
deleted file mode 100644
index 60c1ac1557b..00000000000
--- a/src/vnet/bonding/test/vpp_bond_interface.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from vpp_object import VppObject
-from vpp_interface import VppInterface
-
-
-class VppBondInterface(VppInterface):
- """VPP bond interface."""
-
- def __init__(self, test, mode, lb=0, numa_only=0, enable_gso=0,
- use_custom_mac=0, mac_address='', id=0xFFFFFFFF):
-
- """ Create VPP Bond interface """
- super(VppBondInterface, self).__init__(test)
- self.mode = mode
- self.lb = lb
- self.numa_only = numa_only
- self.enable_gso = enable_gso
- self.use_custom_mac = use_custom_mac
- self.mac_address = mac_address
- self.id = id
-
- def add_vpp_config(self):
- r = self.test.vapi.bond_create2(self.mode,
- self.lb,
- self.numa_only,
- self.enable_gso,
- self.use_custom_mac,
- self.mac_address,
- self.id)
- self.set_sw_if_index(r.sw_if_index)
-
- def remove_vpp_config(self):
- self.test.vapi.bond_delete(self.sw_if_index)
-
- def add_member_vpp_bond_interface(self,
- sw_if_index,
- is_passive=0,
- is_long_timeout=0):
- self.test.vapi.bond_add_member(sw_if_index,
- self.sw_if_index,
- is_passive,
- is_long_timeout)
-
- def detach_vpp_bond_interface(self,
- sw_if_index):
- self.test.vapi.bond_detach_member(sw_if_index)
-
- def is_interface_config_in_dump(self, dump):
- for i in dump:
- if i.sw_if_index == self.sw_if_index:
- return True
- else:
- return False
diff --git a/src/vnet/classify/test/test_classifier.py b/src/vnet/classify/test/test_classifier.py
deleted file mode 100644
index 11c0985f4d4..00000000000
--- a/src/vnet/classify/test/test_classifier.py
+++ /dev/null
@@ -1,569 +0,0 @@
-#!/usr/bin/env python3
-
-import binascii
-import socket
-import unittest
-
-from framework import VppTestCase, VppTestRunner
-
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether
-from scapy.layers.inet import IP, UDP, TCP
-from util import ppp
-from template_classifier import TestClassifier
-from vpp_ip_route import VppIpRoute, VppRoutePath
-from vpp_ip import INVALID_INDEX
-
-
-# Tests split to different test case classes because of issue reported in
-# ticket VPP-1336
-class TestClassifierIP(TestClassifier):
- """ Classifier IP Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierIP, cls).tearDownClass()
-
- def test_iacl_src_ip(self):
- """ Source IP iACL test
-
- Test scenario for basic IP ACL with source IP
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with source IP address.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with source IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip_src'
- self.create_classify_table(key, self.build_ip_mask(src_ip='ffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(src_ip=self.pg0.remote_ip4))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_dst_ip(self):
- """ Destination IP iACL test
-
- Test scenario for basic IP ACL with destination IP
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with destination IP address.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with destination IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip_dst'
- self.create_classify_table(key, self.build_ip_mask(dst_ip='ffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(dst_ip=self.pg1.remote_ip4))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_src_dst_ip(self):
- """ Source and destination IP iACL test
-
- Test scenario for basic IP ACL with source and destination IP
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with source and destination IP addresses.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with source and destination IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip'
- self.create_classify_table(
- key, self.build_ip_mask(src_ip='ffffffff', dst_ip='ffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(src_ip=self.pg0.remote_ip4,
- dst_ip=self.pg1.remote_ip4))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierUDP(TestClassifier):
- """ Classifier UDP proto Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierUDP, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierUDP, cls).tearDownClass()
-
- def test_iacl_proto_udp(self):
- """ UDP protocol iACL test
-
- Test scenario for basic protocol ACL with UDP protocol
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP protocol
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'proto_udp'
- self.create_classify_table(key, self.build_ip_mask(proto='ff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_UDP))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_sport(self):
- """ UDP source port iACL test
-
- Test scenario for basic protocol ACL with UDP and sport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined sport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and sport
- sport = 38
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=sport, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'proto_udp_sport'
- self.create_classify_table(
- key, self.build_ip_mask(proto='ff', src_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_UDP, src_port=sport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_dport(self):
- """ UDP destination port iACL test
-
- Test scenario for basic protocol ACL with UDP and dport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and dport
- dport = 427
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=1234, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'proto_udp_dport'
- self.create_classify_table(
- key, self.build_ip_mask(proto='ff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_UDP, dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_sport_dport(self):
- """ UDP source and destination ports iACL test
-
- Test scenario for basic protocol ACL with UDP and sport and dport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined sport and dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and sport and dport
- sport = 13720
- dport = 9080
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=sport, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'proto_udp_ports'
- self.create_classify_table(
- key,
- self.build_ip_mask(proto='ff', src_port='ffff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_UDP, src_port=sport,
- dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierTCP(TestClassifier):
- """ Classifier TCP proto Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierTCP, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierTCP, cls).tearDownClass()
-
- def test_iacl_proto_tcp(self):
- """ TCP protocol iACL test
-
- Test scenario for basic protocol ACL with TCP protocol
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP protocol
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=1234, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'proto_tcp'
- self.create_classify_table(key, self.build_ip_mask(proto='ff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_TCP))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_sport(self):
- """ TCP source port iACL test
-
- Test scenario for basic protocol ACL with TCP and sport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined sport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and sport
- sport = 38
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=sport, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'proto_tcp_sport'
- self.create_classify_table(
- key, self.build_ip_mask(proto='ff', src_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_TCP, src_port=sport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_dport(self):
- """ TCP destination port iACL test
-
- Test scenario for basic protocol ACL with TCP and dport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and dport
- dport = 427
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=1234, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'proto_tcp_sport'
- self.create_classify_table(
- key, self.build_ip_mask(proto='ff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_TCP, dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_sport_dport(self):
- """ TCP source and destination ports iACL test
-
- Test scenario for basic protocol ACL with TCP and sport and dport
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined sport and dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and sport and dport
- sport = 13720
- dport = 9080
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=sport, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'proto_tcp_ports'
- self.create_classify_table(
- key,
- self.build_ip_mask(proto='ff', src_port='ffff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(proto=socket.IPPROTO_TCP, src_port=sport,
- dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierIPOut(TestClassifier):
- """ Classifier output IP Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIPOut, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierIPOut, cls).tearDownClass()
-
- def test_acl_ip_out(self):
- """ Output IP ACL test
-
- Test scenario for basic IP ACL with source IP
- - Create IPv4 stream for pg1 -> pg0 interface.
- - Create ACL with source IP address.
- - Send and verify received packets on pg0 interface.
- """
-
- # Basic oACL testing with source IP
- pkts = self.create_stream(self.pg1, self.pg0, self.pg_if_packet_sizes)
- self.pg1.add_stream(pkts)
-
- key = 'ip_out'
- self.create_classify_table(
- key, self.build_ip_mask(src_ip='ffffffff'), data_offset=0)
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(src_ip=self.pg1.remote_ip4))
- self.output_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg0.get_capture(len(pkts))
- self.verify_capture(self.pg0, pkts)
- self.pg1.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierMAC(TestClassifier):
- """ Classifier MAC Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierMAC, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierMAC, cls).tearDownClass()
-
- def test_acl_mac(self):
- """ MAC ACL test
-
- Test scenario for basic MAC ACL with source MAC
- - Create IPv4 stream for pg0 -> pg2 interface.
- - Create ACL with source MAC address.
- - Send and verify received packets on pg2 interface.
- """
-
- # Basic iACL testing with source MAC
- pkts = self.create_stream(self.pg0, self.pg2, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'mac'
- self.create_classify_table(
- key, self.build_mac_mask(src_mac='ffffffffffff'), data_offset=-14)
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_mac_match(src_mac=self.pg0.remote_mac))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg2.get_capture(len(pkts))
- self.verify_capture(self.pg2, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg1.assert_nothing_captured(remark="packets forwarded")
- self.pg3.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierPBR(TestClassifier):
- """ Classifier PBR Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierPBR, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierPBR, cls).tearDownClass()
-
- def test_acl_pbr(self):
- """ IP PBR test
-
- Test scenario for PBR with source IP
- - Create IPv4 stream for pg0 -> pg3 interface.
- - Configure PBR fib entry for packet forwarding.
- - Send and verify received packets on pg3 interface.
- """
-
- # PBR testing with source IP
- pkts = self.create_stream(self.pg0, self.pg3, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'pbr'
- self.create_classify_table(key, self.build_ip_mask(src_ip='ffffffff'))
- pbr_option = 1
- # this will create the VRF/table in which we will insert the route
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(src_ip=self.pg0.remote_ip4),
- pbr_option, self.pbr_vrfid)
- self.assertTrue(self.verify_vrf(self.pbr_vrfid))
- r = VppIpRoute(self, self.pg3.local_ip4, 24,
- [VppRoutePath(self.pg3.remote_ip4,
- INVALID_INDEX)],
- table_id=self.pbr_vrfid)
- r.add_vpp_config()
-
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg3.get_capture(len(pkts))
- self.verify_capture(self.pg3, pkts)
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key), 0)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg1.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- # remove the classify session and the route
- r.remove_vpp_config()
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip_match(src_ip=self.pg0.remote_ip4),
- pbr_option, self.pbr_vrfid, is_add=0)
-
- # and the table should be gone.
- self.assertFalse(self.verify_vrf(self.pbr_vrfid))
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/classify/test/test_classifier_ip6.py b/src/vnet/classify/test/test_classifier_ip6.py
deleted file mode 100644
index 211374b5ec6..00000000000
--- a/src/vnet/classify/test/test_classifier_ip6.py
+++ /dev/null
@@ -1,490 +0,0 @@
-#!/usr/bin/env python3
-
-import unittest
-import socket
-import binascii
-
-from framework import VppTestCase, VppTestRunner
-
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether
-from scapy.layers.inet6 import IPv6, UDP, TCP
-from util import ppp
-from template_classifier import TestClassifier
-
-
-class TestClassifierIP6(TestClassifier):
- """ Classifier IP6 Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP6, cls).setUpClass()
- cls.af = socket.AF_INET6
-
- @classmethod
- def tearDownClass(cls):
- super(TestClassifierIP6, cls).tearDownClass()
-
- def test_iacl_src_ip(self):
- """ Source IP6 iACL test
-
- Test scenario for basic IP ACL with source IP
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with source IP address.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with source IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip6_src'
- self.create_classify_table(
- key,
- self.build_ip6_mask(src_ip='ffffffffffffffffffffffffffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(src_ip=self.pg0.remote_ip6))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_dst_ip(self):
- """ Destination IP6 iACL test
-
- Test scenario for basic IP ACL with destination IP
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with destination IP address.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with destination IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip6_dst'
- self.create_classify_table(
- key,
- self.build_ip6_mask(dst_ip='ffffffffffffffffffffffffffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(dst_ip=self.pg1.remote_ip6))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_src_dst_ip(self):
- """ Source and destination IP6 iACL test
-
- Test scenario for basic IP ACL with source and destination IP
- - Create IPv4 stream for pg0 -> pg1 interface.
- - Create iACL with source and destination IP addresses.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with source and destination IP
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'ip6'
- self.create_classify_table(
- key,
- self.build_ip6_mask(src_ip='ffffffffffffffffffffffffffffffff',
- dst_ip='ffffffffffffffffffffffffffffffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(src_ip=self.pg0.remote_ip6,
- dst_ip=self.pg1.remote_ip6))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
-
-# Tests split to different test case classes because of issue reported in
-# ticket VPP-1336
-class TestClassifierIP6UDP(TestClassifier):
- """ Classifier IP6 UDP proto Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP6UDP, cls).setUpClass()
- cls.af = socket.AF_INET6
-
- def test_iacl_proto_udp(self):
- """ IP6 UDP protocol iACL test
-
- Test scenario for basic protocol ACL with UDP protocol
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP protocol
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'nh_udp'
- self.create_classify_table(key, self.build_ip6_mask(nh='ff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_UDP))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_sport(self):
- """ IP6 UDP source port iACL test
-
- Test scenario for basic protocol ACL with UDP and sport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined sport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and sport
- sport = 38
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=sport, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'nh_udp_sport'
- self.create_classify_table(
- key, self.build_ip6_mask(nh='ff', src_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_UDP, src_port=sport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_dport(self):
- """ IP6 UDP destination port iACL test
-
- Test scenario for basic protocol ACL with UDP and dport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and dport
- dport = 427
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=1234, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'nh_udp_dport'
- self.create_classify_table(
- key, self.build_ip6_mask(nh='ff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_UDP, dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_udp_sport_dport(self):
- """ IP6 UDP source and destination ports iACL test
-
- Test scenario for basic protocol ACL with UDP and sport and dport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with UDP IP protocol and defined sport and dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with UDP and sport and dport
- sport = 13720
- dport = 9080
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- UDP(sport=sport, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'nh_udp_ports'
- self.create_classify_table(
- key,
- self.build_ip6_mask(nh='ff', src_port='ffff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_UDP, src_port=sport,
- dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierIP6TCP(TestClassifier):
- """ Classifier IP6 TCP proto Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP6TCP, cls).setUpClass()
- cls.af = socket.AF_INET6
-
- def test_iacl_proto_tcp(self):
- """ IP6 TCP protocol iACL test
-
- Test scenario for basic protocol ACL with TCP protocol
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP protocol
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=1234, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'nh_tcp'
- self.create_classify_table(key, self.build_ip6_mask(nh='ff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_TCP))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_sport(self):
- """ IP6 TCP source port iACL test
-
- Test scenario for basic protocol ACL with TCP and sport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined sport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and sport
- sport = 38
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=sport, dport=5678))
- self.pg0.add_stream(pkts)
-
- key = 'nh_tcp_sport'
- self.create_classify_table(
- key, self.build_ip6_mask(nh='ff', src_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_TCP, src_port=sport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_dport(self):
- """ IP6 TCP destination port iACL test
-
- Test scenario for basic protocol ACL with TCP and dport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and dport
- dport = 427
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=1234, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'nh_tcp_dport'
- self.create_classify_table(
- key, self.build_ip6_mask(nh='ff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_TCP, dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
- def test_iacl_proto_tcp_sport_dport(self):
- """ IP6 TCP source and destination ports iACL test
-
- Test scenario for basic protocol ACL with TCP and sport and dport
- - Create IPv6 stream for pg0 -> pg1 interface.
- - Create iACL with TCP IP protocol and defined sport and dport.
- - Send and verify received packets on pg1 interface.
- """
-
- # Basic iACL testing with TCP and sport and dport
- sport = 13720
- dport = 9080
- pkts = self.create_stream(self.pg0, self.pg1, self.pg_if_packet_sizes,
- TCP(sport=sport, dport=dport))
- self.pg0.add_stream(pkts)
-
- key = 'nh_tcp_ports'
- self.create_classify_table(
- key,
- self.build_ip6_mask(nh='ff', src_port='ffff', dst_port='ffff'))
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(nh=socket.IPPROTO_TCP, src_port=sport,
- dst_port=dport))
- self.input_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg1.get_capture(len(pkts))
- self.verify_capture(self.pg1, pkts, TCP)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierIP6Out(TestClassifier):
- """ Classifier output IP6 Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP6Out, cls).setUpClass()
- cls.af = socket.AF_INET6
-
- def test_acl_ip_out(self):
- """ Output IP6 ACL test
-
- Test scenario for basic IP ACL with source IP
- - Create IPv6 stream for pg1 -> pg0 interface.
- - Create ACL with source IP address.
- - Send and verify received packets on pg0 interface.
- """
-
- # Basic oACL testing with source IP
- pkts = self.create_stream(self.pg1, self.pg0, self.pg_if_packet_sizes)
- self.pg1.add_stream(pkts)
-
- key = 'ip6_out'
- self.create_classify_table(
- key,
- self.build_ip6_mask(src_ip='ffffffffffffffffffffffffffffffff'),
- data_offset=0)
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_ip6_match(src_ip=self.pg1.remote_ip6))
- self.output_acl_set_interface(
- self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg0.get_capture(len(pkts))
- self.verify_capture(self.pg0, pkts)
- self.pg1.assert_nothing_captured(remark="packets forwarded")
- self.pg2.assert_nothing_captured(remark="packets forwarded")
-
-
-class TestClassifierIP6MAC(TestClassifier):
- """ Classifier IP6 MAC Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestClassifierIP6MAC, cls).setUpClass()
- cls.af = socket.AF_INET6
-
- def test_acl_mac(self):
- """ IP6 MAC iACL test
-
- Test scenario for basic MAC ACL with source MAC
- - Create IPv6 stream for pg0 -> pg2 interface.
- - Create ACL with source MAC address.
- - Send and verify received packets on pg2 interface.
- """
-
- # Basic iACL testing with source MAC
- pkts = self.create_stream(self.pg0, self.pg2, self.pg_if_packet_sizes)
- self.pg0.add_stream(pkts)
-
- key = 'mac'
- self.create_classify_table(
- key, self.build_mac_mask(src_mac='ffffffffffff'), data_offset=-14)
- self.create_classify_session(
- self.acl_tbl_idx.get(key),
- self.build_mac_match(src_mac=self.pg0.remote_mac))
- self.input_acl_set_interface(self.pg0, self.acl_tbl_idx.get(key))
- self.acl_active_table = key
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- pkts = self.pg2.get_capture(len(pkts))
- self.verify_capture(self.pg2, pkts)
- self.pg0.assert_nothing_captured(remark="packets forwarded")
- self.pg1.assert_nothing_captured(remark="packets forwarded")
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/crypto/test/test_crypto.py b/src/vnet/crypto/test/test_crypto.py
deleted file mode 100644
index aa62dba1bab..00000000000
--- a/src/vnet/crypto/test/test_crypto.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-
-import unittest
-
-from framework import VppTestCase, VppTestRunner
-
-
-class TestCrypto(VppTestCase):
- """ Crypto Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestCrypto, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestCrypto, cls).tearDownClass()
-
- def test_crypto(self):
- """ Crypto Unit Tests """
- error = self.vapi.cli("test crypto")
-
- if error:
- self.logger.critical(error)
- self.assertNotIn("FAIL", error)
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/fib/test/test_dvr.py b/src/vnet/fib/test/test_dvr.py
deleted file mode 100644
index 8531b8553ca..00000000000
--- a/src/vnet/fib/test/test_dvr.py
+++ /dev/null
@@ -1,410 +0,0 @@
-#!/usr/bin/env python3
-import unittest
-
-from framework import VppTestCase, VppTestRunner
-from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathType
-from vpp_l2 import L2_PORT_TYPE
-from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
-from vpp_acl import AclRule, VppAcl, VppAclInterface
-
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether, Dot1Q
-from scapy.layers.inet import IP, UDP
-from socket import AF_INET, inet_pton
-from ipaddress import IPv4Network
-
-NUM_PKTS = 67
-
-
-class TestDVR(VppTestCase):
- """ Distributed Virtual Router """
-
- @classmethod
- def setUpClass(cls):
- super(TestDVR, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestDVR, cls).tearDownClass()
-
- def setUp(self):
- super(TestDVR, self).setUp()
-
- self.create_pg_interfaces(range(4))
- self.create_loopback_interfaces(1)
-
- for i in self.pg_interfaces:
- i.admin_up()
-
- self.loop0.config_ip4()
-
- def tearDown(self):
- for i in self.pg_interfaces:
- i.admin_down()
- self.loop0.unconfig_ip4()
-
- super(TestDVR, self).tearDown()
-
- def assert_same_mac_addr(self, tx, rx):
- t_eth = tx[Ether]
- for p in rx:
- r_eth = p[Ether]
- self.assertEqual(t_eth.src, r_eth.src)
- self.assertEqual(t_eth.dst, r_eth.dst)
-
- def assert_has_vlan_tag(self, tag, rx):
- for p in rx:
- r_1q = p[Dot1Q]
- self.assertEqual(tag, r_1q.vlan)
-
- def assert_has_no_tag(self, rx):
- for p in rx:
- self.assertFalse(p.haslayer(Dot1Q))
-
- def test_dvr(self):
- """ Distributed Virtual Router """
-
- #
- # A packet destined to an IP address that is L2 bridged via
- # a non-tag interface
- #
- ip_non_tag_bridged = "10.10.10.10"
- ip_tag_bridged = "10.10.10.11"
- any_src_addr = "1.1.1.1"
-
- pkt_no_tag = (Ether(src=self.pg0.remote_mac,
- dst=self.loop0.local_mac) /
- IP(src=any_src_addr,
- dst=ip_non_tag_bridged) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- pkt_tag = (Ether(src=self.pg0.remote_mac,
- dst=self.loop0.local_mac) /
- IP(src=any_src_addr,
- dst=ip_tag_bridged) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
-
- #
- # Two sub-interfaces so we can test VLAN tag push/pop
- #
- sub_if_on_pg2 = VppDot1QSubint(self, self.pg2, 92)
- sub_if_on_pg3 = VppDot1QSubint(self, self.pg3, 93)
- sub_if_on_pg2.admin_up()
- sub_if_on_pg3.admin_up()
-
- #
- # Put all the interfaces into a new bridge domain
- #
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg0.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg2.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg3.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.loop0.sw_if_index, bd_id=1,
- port_type=L2_PORT_TYPE.BVI)
-
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=sub_if_on_pg2.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=92)
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=sub_if_on_pg3.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=93)
-
- #
- # Add routes to bridge the traffic via a tagged an nontagged interface
- #
- route_no_tag = VppIpRoute(
- self, ip_non_tag_bridged, 32,
- [VppRoutePath("0.0.0.0",
- self.pg1.sw_if_index,
- type=FibPathType.FIB_PATH_TYPE_DVR)])
- route_no_tag.add_vpp_config()
-
- #
- # Inject the packet that arrives and leaves on a non-tagged interface
- # Since it's 'bridged' expect that the MAC headed is unchanged.
- #
- rx = self.send_and_expect(self.pg0, pkt_no_tag * NUM_PKTS, self.pg1)
- self.assert_same_mac_addr(pkt_no_tag, rx)
- self.assert_has_no_tag(rx)
-
- #
- # Add routes to bridge the traffic via a tagged interface
- #
- route_with_tag = VppIpRoute(
- self, ip_tag_bridged, 32,
- [VppRoutePath("0.0.0.0",
- sub_if_on_pg3.sw_if_index,
- type=FibPathType.FIB_PATH_TYPE_DVR)])
- route_with_tag.add_vpp_config()
-
- #
- # Inject the packet that arrives non-tag and leaves on a tagged
- # interface
- #
- rx = self.send_and_expect(self.pg0, pkt_tag * NUM_PKTS, self.pg3)
- self.assert_same_mac_addr(pkt_tag, rx)
- self.assert_has_vlan_tag(93, rx)
-
- #
- # Tag to tag
- #
- pkt_tag_to_tag = (Ether(src=self.pg2.remote_mac,
- dst=self.loop0.local_mac) /
- Dot1Q(vlan=92) /
- IP(src=any_src_addr,
- dst=ip_tag_bridged) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
-
- rx = self.send_and_expect(self.pg2,
- pkt_tag_to_tag * NUM_PKTS,
- self.pg3)
- self.assert_same_mac_addr(pkt_tag_to_tag, rx)
- self.assert_has_vlan_tag(93, rx)
-
- #
- # Tag to non-Tag
- #
- pkt_tag_to_non_tag = (Ether(src=self.pg2.remote_mac,
- dst=self.loop0.local_mac) /
- Dot1Q(vlan=92) /
- IP(src=any_src_addr,
- dst=ip_non_tag_bridged) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
-
- rx = self.send_and_expect(self.pg2,
- pkt_tag_to_non_tag * NUM_PKTS,
- self.pg1)
- self.assert_same_mac_addr(pkt_tag_to_tag, rx)
- self.assert_has_no_tag(rx)
-
- #
- # Add an output L3 ACL that will block the traffic
- #
- rule_1 = AclRule(is_permit=0, proto=17, ports=1234,
- src_prefix=IPv4Network((any_src_addr, 32)),
- dst_prefix=IPv4Network((ip_non_tag_bridged, 32)))
- acl = VppAcl(self, rules=[rule_1])
- acl.add_vpp_config()
-
- #
- # Apply the ACL on the output interface
- #
- acl_if1 = VppAclInterface(self, sw_if_index=self.pg1.sw_if_index,
- n_input=0, acls=[acl])
- acl_if1.add_vpp_config()
-
- #
- # Send packet's that should match the ACL and be dropped
- #
- rx = self.send_and_assert_no_replies(self.pg2,
- pkt_tag_to_non_tag * NUM_PKTS)
-
- #
- # cleanup
- #
- acl_if1.remove_vpp_config()
- acl.remove_vpp_config()
-
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg0.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg2.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg3.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.loop0.sw_if_index, bd_id=1,
- port_type=L2_PORT_TYPE.BVI, enable=0)
-
- #
- # Do a FIB dump to make sure the paths are correctly reported as DVR
- #
- routes = self.vapi.ip_route_dump(0)
-
- for r in routes:
- if (ip_tag_bridged == str(r.route.prefix.network_address)):
- self.assertEqual(r.route.paths[0].sw_if_index,
- sub_if_on_pg3.sw_if_index)
- self.assertEqual(r.route.paths[0].type,
- FibPathType.FIB_PATH_TYPE_DVR)
- if (ip_non_tag_bridged == str(r.route.prefix.network_address)):
- self.assertEqual(r.route.paths[0].sw_if_index,
- self.pg1.sw_if_index)
- self.assertEqual(r.route.paths[0].type,
- FibPathType.FIB_PATH_TYPE_DVR)
-
- #
- # the explicit route delete is require so it happens before
- # the sbu-interface delete. subinterface delete is required
- # because that object type does not use the object registry
- #
- route_no_tag.remove_vpp_config()
- route_with_tag.remove_vpp_config()
- sub_if_on_pg3.remove_vpp_config()
- sub_if_on_pg2.remove_vpp_config()
-
- def test_l2_emulation(self):
- """ L2 Emulation """
-
- #
- # non distinct L3 packets, in the tag/non-tag combos
- #
- pkt_no_tag = (Ether(src=self.pg0.remote_mac,
- dst=self.pg1.remote_mac) /
- IP(src="2.2.2.2",
- dst="1.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- pkt_to_tag = (Ether(src=self.pg0.remote_mac,
- dst=self.pg2.remote_mac) /
- IP(src="2.2.2.2",
- dst="1.1.1.2") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- pkt_from_tag = (Ether(src=self.pg3.remote_mac,
- dst=self.pg2.remote_mac) /
- Dot1Q(vlan=93) /
- IP(src="2.2.2.2",
- dst="1.1.1.1") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- pkt_from_to_tag = (Ether(src=self.pg3.remote_mac,
- dst=self.pg2.remote_mac) /
- Dot1Q(vlan=93) /
- IP(src="2.2.2.2",
- dst="1.1.1.2") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
- pkt_bcast = (Ether(src=self.pg0.remote_mac,
- dst="ff:ff:ff:ff:ff:ff") /
- IP(src="2.2.2.2",
- dst="255.255.255.255") /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
-
- #
- # A couple of sub-interfaces for tags
- #
- sub_if_on_pg2 = VppDot1QSubint(self, self.pg2, 92)
- sub_if_on_pg3 = VppDot1QSubint(self, self.pg3, 93)
- sub_if_on_pg2.admin_up()
- sub_if_on_pg3.admin_up()
-
- #
- # Put all the interfaces into a new bridge domain
- #
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg0.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg2.sw_if_index, bd_id=1)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg3.sw_if_index, bd_id=1)
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=sub_if_on_pg2.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=92)
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=sub_if_on_pg3.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=93)
-
- #
- # Disable UU flooding, learning and ARP termination. makes this test
- # easier as unicast packets are dropped if not extracted.
- #
- self.vapi.bridge_flags(bd_id=1, is_set=0,
- flags=(1 << 0) | (1 << 3) | (1 << 4))
-
- #
- # Add a DVR route to steer traffic at L3
- #
- route_1 = VppIpRoute(
- self, "1.1.1.1", 32,
- [VppRoutePath("0.0.0.0",
- self.pg1.sw_if_index,
- type=FibPathType.FIB_PATH_TYPE_DVR)])
- route_2 = VppIpRoute(
- self, "1.1.1.2", 32,
- [VppRoutePath("0.0.0.0",
- sub_if_on_pg2.sw_if_index,
- type=FibPathType.FIB_PATH_TYPE_DVR)])
- route_1.add_vpp_config()
- route_2.add_vpp_config()
-
- #
- # packets are dropped because bridge does not flood unknown unicast
- #
- self.send_and_assert_no_replies(self.pg0, pkt_no_tag)
-
- #
- # Enable L3 extraction on pgs
- #
- self.vapi.l2_emulation(self.pg0.sw_if_index)
- self.vapi.l2_emulation(self.pg1.sw_if_index)
- self.vapi.l2_emulation(sub_if_on_pg2.sw_if_index)
- self.vapi.l2_emulation(sub_if_on_pg3.sw_if_index)
-
- #
- # now we expect the packet forward according to the DVR route
- #
- rx = self.send_and_expect(self.pg0, pkt_no_tag * NUM_PKTS, self.pg1)
- self.assert_same_mac_addr(pkt_no_tag, rx)
- self.assert_has_no_tag(rx)
-
- rx = self.send_and_expect(self.pg0, pkt_to_tag * NUM_PKTS, self.pg2)
- self.assert_same_mac_addr(pkt_to_tag, rx)
- self.assert_has_vlan_tag(92, rx)
-
- rx = self.send_and_expect(self.pg3, pkt_from_tag * NUM_PKTS, self.pg1)
- self.assert_same_mac_addr(pkt_from_tag, rx)
- self.assert_has_no_tag(rx)
-
- rx = self.send_and_expect(self.pg3,
- pkt_from_to_tag * NUM_PKTS,
- self.pg2)
- self.assert_same_mac_addr(pkt_from_tag, rx)
- self.assert_has_vlan_tag(92, rx)
-
- #
- # but broadcast packets are still flooded
- #
- self.send_and_expect(self.pg0, pkt_bcast * 33, self.pg2)
-
- #
- # cleanup
- #
- self.vapi.l2_emulation(self.pg0.sw_if_index,
- enable=0)
- self.vapi.l2_emulation(self.pg1.sw_if_index,
- enable=0)
- self.vapi.l2_emulation(sub_if_on_pg2.sw_if_index,
- enable=0)
- self.vapi.l2_emulation(sub_if_on_pg3.sw_if_index,
- enable=0)
-
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg0.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg2.sw_if_index, bd_id=1, enable=0)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=sub_if_on_pg3.sw_if_index, bd_id=1, enable=0)
-
- route_1.remove_vpp_config()
- route_2.remove_vpp_config()
- sub_if_on_pg3.remove_vpp_config()
- sub_if_on_pg2.remove_vpp_config()
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/fib/test/test_fib.py b/src/vnet/fib/test/test_fib.py
deleted file mode 100644
index 7c08722d803..00000000000
--- a/src/vnet/fib/test/test_fib.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python3
-
-import unittest
-
-from framework import tag_fixme_vpp_workers
-from framework import VppTestCase, VppTestRunner
-
-
-@tag_fixme_vpp_workers
-class TestFIB(VppTestCase):
- """ FIB Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestFIB, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestFIB, cls).tearDownClass()
-
- def test_fib(self):
- """ FIB Unit Tests """
- error = self.vapi.cli("test fib")
-
- # shameless test of CLIs to bump lcov results...
- # no i mean to ensure they don't crash
- self.logger.info(self.vapi.cli("sh fib source"))
- self.logger.info(self.vapi.cli("sh fib source prio"))
- self.logger.info(self.vapi.cli("sh fib memory"))
- self.logger.info(self.vapi.cli("sh fib entry"))
- self.logger.info(self.vapi.cli("sh fib entry 0"))
- self.logger.info(self.vapi.cli("sh fib entry 10000"))
- self.logger.info(self.vapi.cli("sh fib entry-delegate"))
- self.logger.info(self.vapi.cli("sh fib paths"))
- self.logger.info(self.vapi.cli("sh fib paths 0"))
- self.logger.info(self.vapi.cli("sh fib paths 10000"))
- self.logger.info(self.vapi.cli("sh fib path-list"))
- self.logger.info(self.vapi.cli("sh fib path-list 0"))
- self.logger.info(self.vapi.cli("sh fib path-list 10000"))
- self.logger.info(self.vapi.cli("sh fib walk"))
- self.logger.info(self.vapi.cli("sh fib uRPF"))
-
- if error:
- self.logger.critical(error)
- self.assertNotIn("Failed", error)
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/gre/test/test_gre.py b/src/vnet/gre/test/test_gre.py
deleted file mode 100644
index ba20ba8dec0..00000000000
--- a/src/vnet/gre/test/test_gre.py
+++ /dev/null
@@ -1,1296 +0,0 @@
-#!/usr/bin/env python3
-
-import unittest
-
-import scapy.compat
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether, Dot1Q, GRE
-from scapy.layers.inet import IP, UDP
-from scapy.layers.inet6 import IPv6
-from scapy.volatile import RandMAC, RandIP
-
-from framework import tag_fixme_vpp_workers
-from framework import VppTestCase, VppTestRunner
-from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
-from vpp_gre_interface import VppGreInterface
-from vpp_teib import VppTeib
-from vpp_ip import DpoProto
-from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, FibPathProto, \
- VppMplsLabel
-from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
-from util import ppp, ppc
-from vpp_papi import VppEnum
-
-
-@tag_fixme_vpp_workers
-class TestGREInputNodes(VppTestCase):
- """ GRE Input Nodes Test Case """
-
- def setUp(self):
- super(TestGREInputNodes, self).setUp()
-
- # create 3 pg interfaces - set one in a non-default table.
- self.create_pg_interfaces(range(1))
-
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip4()
-
- def tearDown(self):
- for i in self.pg_interfaces:
- i.unconfig_ip4()
- i.admin_down()
- super(TestGREInputNodes, self).tearDown()
-
- def test_gre_input_node(self):
- """ GRE gre input nodes not registerd unless configured """
- pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
- GRE())
-
- self.pg0.add_stream(pkt)
- self.pg_start()
- # no tunnel created, gre-input not registered
- err = self.statistics.get_counter(
- '/err/ip4-local/unknown ip protocol')[0]
- self.assertEqual(err, 1)
- err_count = err
-
- # create gre tunnel
- gre_if = VppGreInterface(self, self.pg0.local_ip4, "1.1.1.2")
- gre_if.add_vpp_config()
-
- self.pg0.add_stream(pkt)
- self.pg_start()
- # tunnel created, gre-input registered
- err = self.statistics.get_counter(
- '/err/ip4-local/unknown ip protocol')[0]
- # expect no new errors
- self.assertEqual(err, err_count)
-
-
-class TestGRE(VppTestCase):
- """ GRE Test Case """
-
- @classmethod
- def setUpClass(cls):
- super(TestGRE, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- super(TestGRE, cls).tearDownClass()
-
- def setUp(self):
- super(TestGRE, self).setUp()
-
- # create 3 pg interfaces - set one in a non-default table.
- self.create_pg_interfaces(range(5))
-
- self.tbl = VppIpTable(self, 1)
- self.tbl.add_vpp_config()
- self.pg1.set_table_ip4(1)
-
- for i in self.pg_interfaces:
- i.admin_up()
-
- self.pg0.config_ip4()
- self.pg0.resolve_arp()
- self.pg1.config_ip4()
- self.pg1.resolve_arp()
- self.pg2.config_ip6()
- self.pg2.resolve_ndp()
- self.pg3.config_ip4()
- self.pg3.resolve_arp()
- self.pg4.config_ip4()
- self.pg4.resolve_arp()
-
- def tearDown(self):
- for i in self.pg_interfaces:
- i.unconfig_ip4()
- i.unconfig_ip6()
- i.admin_down()
- self.pg1.set_table_ip4(0)
- super(TestGRE, self).tearDown()
-
- def create_stream_ip4(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
- pkts = []
- tos = (dscp << 2) | ecn
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=src_ip, dst=dst_ip, tos=tos) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_stream_ip6(self, src_if, src_ip, dst_ip, dscp=0, ecn=0):
- pkts = []
- tc = (dscp << 2) | ecn
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IPv6(src=src_ip, dst=dst_ip, tc=tc) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_tunnel_stream_4o4(self, src_if,
- tunnel_src, tunnel_dst,
- src_ip, dst_ip):
- pkts = []
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=tunnel_src, dst=tunnel_dst) /
- GRE() /
- IP(src=src_ip, dst=dst_ip) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_tunnel_stream_6o4(self, src_if,
- tunnel_src, tunnel_dst,
- src_ip, dst_ip):
- pkts = []
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=tunnel_src, dst=tunnel_dst) /
- GRE() /
- IPv6(src=src_ip, dst=dst_ip) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_tunnel_stream_6o6(self, src_if,
- tunnel_src, tunnel_dst,
- src_ip, dst_ip):
- pkts = []
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IPv6(src=tunnel_src, dst=tunnel_dst) /
- GRE() /
- IPv6(src=src_ip, dst=dst_ip) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_tunnel_stream_l2o4(self, src_if,
- tunnel_src, tunnel_dst):
- pkts = []
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=tunnel_src, dst=tunnel_dst) /
- GRE() /
- Ether(dst=RandMAC('*:*:*:*:*:*'),
- src=RandMAC('*:*:*:*:*:*')) /
- IP(src=scapy.compat.raw(RandIP()),
- dst=scapy.compat.raw(RandIP())) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def create_tunnel_stream_vlano4(self, src_if,
- tunnel_src, tunnel_dst, vlan):
- pkts = []
- for i in range(0, 257):
- info = self.create_packet_info(src_if, src_if)
- payload = self.info_to_payload(info)
- p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=tunnel_src, dst=tunnel_dst) /
- GRE() /
- Ether(dst=RandMAC('*:*:*:*:*:*'),
- src=RandMAC('*:*:*:*:*:*')) /
- Dot1Q(vlan=vlan) /
- IP(src=scapy.compat.raw(RandIP()),
- dst=scapy.compat.raw(RandIP())) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
- info.data = p.copy()
- pkts.append(p)
- return pkts
-
- def verify_tunneled_4o4(self, src_if, capture, sent,
- tunnel_src, tunnel_dst,
- dscp=0, ecn=0):
-
- self.assertEqual(len(capture), len(sent))
- tos = (dscp << 2) | ecn
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IP]
- rx_ip = rx[IP]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
- self.assertEqual(rx_ip.tos, tos)
- self.assertEqual(rx_ip.len, len(rx_ip))
-
- rx_gre = rx[GRE]
- rx_ip = rx_gre[IP]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- # IP processing post pop has decremented the TTL
- self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_tunneled_6o6(self, src_if, capture, sent,
- tunnel_src, tunnel_dst,
- dscp=0, ecn=0):
-
- self.assertEqual(len(capture), len(sent))
- tc = (dscp << 2) | ecn
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IPv6]
- rx_ip = rx[IPv6]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
- self.assertEqual(rx_ip.tc, tc)
-
- rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
-
- self.assertEqual(rx_ip.plen, len(rx_gre))
-
- rx_ip = rx_gre[IPv6]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_tunneled_4o6(self, src_if, capture, sent,
- tunnel_src, tunnel_dst):
-
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- rx_ip = rx[IPv6]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
-
- rx_gre = GRE(scapy.compat.raw(rx_ip[IPv6].payload))
-
- self.assertEqual(rx_ip.plen, len(rx_gre))
-
- tx_ip = tx[IP]
- rx_ip = rx_gre[IP]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_tunneled_6o4(self, src_if, capture, sent,
- tunnel_src, tunnel_dst):
-
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- rx_ip = rx[IP]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
- self.assertEqual(rx_ip.len, len(rx_ip))
-
- rx_gre = GRE(scapy.compat.raw(rx_ip[IP].payload))
- rx_ip = rx_gre[IPv6]
- tx_ip = tx[IPv6]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_tunneled_l2o4(self, src_if, capture, sent,
- tunnel_src, tunnel_dst):
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IP]
- rx_ip = rx[IP]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
- self.assertEqual(rx_ip.len, len(rx_ip))
-
- rx_gre = rx[GRE]
- rx_l2 = rx_gre[Ether]
- rx_ip = rx_l2[IP]
- tx_gre = tx[GRE]
- tx_l2 = tx_gre[Ether]
- tx_ip = tx_l2[IP]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- # bridged, not L3 forwarded, so no TTL decrement
- self.assertEqual(rx_ip.ttl, tx_ip.ttl)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_tunneled_vlano4(self, src_if, capture, sent,
- tunnel_src, tunnel_dst, vlan):
- try:
- self.assertEqual(len(capture), len(sent))
- except:
- ppc("Unexpected packets captured:", capture)
- raise
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IP]
- rx_ip = rx[IP]
-
- self.assertEqual(rx_ip.src, tunnel_src)
- self.assertEqual(rx_ip.dst, tunnel_dst)
-
- rx_gre = rx[GRE]
- rx_l2 = rx_gre[Ether]
- rx_vlan = rx_l2[Dot1Q]
- rx_ip = rx_l2[IP]
-
- self.assertEqual(rx_vlan.vlan, vlan)
-
- tx_gre = tx[GRE]
- tx_l2 = tx_gre[Ether]
- tx_ip = tx_l2[IP]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- # bridged, not L3 forwarded, so no TTL decrement
- self.assertEqual(rx_ip.ttl, tx_ip.ttl)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_decapped_4o4(self, src_if, capture, sent):
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IP]
- rx_ip = rx[IP]
- tx_gre = tx[GRE]
- tx_ip = tx_gre[IP]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- # IP processing post pop has decremented the TTL
- self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_decapped_6o4(self, src_if, capture, sent):
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IP]
- rx_ip = rx[IPv6]
- tx_gre = tx[GRE]
- tx_ip = tx_gre[IPv6]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def verify_decapped_6o6(self, src_if, capture, sent):
- self.assertEqual(len(capture), len(sent))
-
- for i in range(len(capture)):
- try:
- tx = sent[i]
- rx = capture[i]
-
- tx_ip = tx[IPv6]
- rx_ip = rx[IPv6]
- tx_gre = tx[GRE]
- tx_ip = tx_gre[IPv6]
-
- self.assertEqual(rx_ip.src, tx_ip.src)
- self.assertEqual(rx_ip.dst, tx_ip.dst)
- self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
-
- except:
- self.logger.error(ppp("Rx:", rx))
- self.logger.error(ppp("Tx:", tx))
- raise
-
- def test_gre(self):
- """ GRE IPv4 tunnel Tests """
-
- #
- # Create an L3 GRE tunnel.
- # - set it admin up
- # - assign an IP Addres
- # - Add a route via the tunnel
- #
- gre_if = VppGreInterface(self,
- self.pg0.local_ip4,
- "1.1.1.2")
- gre_if.add_vpp_config()
-
- #
- # The double create (create the same tunnel twice) should fail,
- # and we should still be able to use the original
- #
- try:
- gre_if.add_vpp_config()
- except Exception:
- pass
- else:
- self.fail("Double GRE tunnel add does not fail")
-
- gre_if.admin_up()
- gre_if.config_ip4()
-
- route_via_tun = VppIpRoute(self, "4.4.4.4", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index)])
-
- route_via_tun.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - they are all dropped since the tunnel's destintation IP
- # is unresolved - or resolves via the default route - which
- # which is a drop.
- #
- tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
-
- self.send_and_assert_no_replies(self.pg0, tx)
-
- #
- # Add a route that resolves the tunnel's destination
- #
- route_tun_dst = VppIpRoute(self, "1.1.1.2", 32,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index)])
- route_tun_dst.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - packets are GRE encapped
- #
- tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "4.4.4.4")
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_4o4(self.pg0, rx, tx,
- self.pg0.local_ip4, "1.1.1.2")
-
- #
- # Send tunneled packets that match the created tunnel and
- # are decapped and forwarded
- #
- tx = self.create_tunnel_stream_4o4(self.pg0,
- "1.1.1.2",
- self.pg0.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_decapped_4o4(self.pg0, rx, tx)
-
- #
- # Send tunneled packets that do not match the tunnel's src
- #
- self.vapi.cli("clear trace")
- tx = self.create_tunnel_stream_4o4(self.pg0,
- "1.1.1.3",
- self.pg0.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- self.send_and_assert_no_replies(
- self.pg0, tx,
- remark="GRE packets forwarded despite no SRC address match")
-
- #
- # Configure IPv6 on the PG interface so we can route IPv6
- # packets
- #
- self.pg0.config_ip6()
- self.pg0.resolve_ndp()
-
- #
- # Send IPv6 tunnel encapslated packets
- # - dropped since IPv6 is not enabled on the tunnel
- #
- tx = self.create_tunnel_stream_6o4(self.pg0,
- "1.1.1.2",
- self.pg0.local_ip4,
- self.pg0.local_ip6,
- self.pg0.remote_ip6)
- self.send_and_assert_no_replies(self.pg0, tx,
- "IPv6 GRE packets forwarded "
- "despite IPv6 not enabled on tunnel")
-
- #
- # Enable IPv6 on the tunnel
- #
- gre_if.config_ip6()
-
- #
- # Send IPv6 tunnel encapslated packets
- # - forwarded since IPv6 is enabled on the tunnel
- #
- tx = self.create_tunnel_stream_6o4(self.pg0,
- "1.1.1.2",
- self.pg0.local_ip4,
- self.pg0.local_ip6,
- self.pg0.remote_ip6)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_decapped_6o4(self.pg0, rx, tx)
-
- #
- # Send v6 packets for v4 encap
- #
- route6_via_tun = VppIpRoute(
- self, "2001::1", 128,
- [VppRoutePath("::",
- gre_if.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)])
- route6_via_tun.add_vpp_config()
-
- tx = self.create_stream_ip6(self.pg0, "2001::2", "2001::1")
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
-
- self.verify_tunneled_6o4(self.pg0, rx, tx,
- self.pg0.local_ip4, "1.1.1.2")
-
- #
- # add a labelled route through the tunnel
- #
- label_via_tun = VppIpRoute(self, "5.4.3.2", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index,
- labels=[VppMplsLabel(33)])])
- label_via_tun.add_vpp_config()
-
- tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.2")
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_4o4(self.pg0, rx, tx,
- self.pg0.local_ip4, "1.1.1.2")
-
- #
- # an MPLS tunnel over the GRE tunnel add a route through
- # the mpls tunnel
- #
- mpls_tun = VppMPLSTunnelInterface(
- self,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index,
- labels=[VppMplsLabel(44),
- VppMplsLabel(46)])])
- mpls_tun.add_vpp_config()
- mpls_tun.admin_up()
-
- label_via_mpls = VppIpRoute(self, "5.4.3.1", 32,
- [VppRoutePath("0.0.0.0",
- mpls_tun.sw_if_index,
- labels=[VppMplsLabel(33)])])
- label_via_mpls.add_vpp_config()
-
- tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "5.4.3.1")
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_4o4(self.pg0, rx, tx,
- self.pg0.local_ip4, "1.1.1.2")
-
- mpls_tun_l2 = VppMPLSTunnelInterface(
- self,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index,
- labels=[VppMplsLabel(44),
- VppMplsLabel(46)])],
- is_l2=1)
- mpls_tun_l2.add_vpp_config()
- mpls_tun_l2.admin_up()
-
- #
- # test case cleanup
- #
- route_tun_dst.remove_vpp_config()
- route_via_tun.remove_vpp_config()
- route6_via_tun.remove_vpp_config()
- label_via_mpls.remove_vpp_config()
- label_via_tun.remove_vpp_config()
- mpls_tun.remove_vpp_config()
- mpls_tun_l2.remove_vpp_config()
- gre_if.remove_vpp_config()
-
- self.pg0.unconfig_ip6()
-
- def test_gre6(self):
- """ GRE IPv6 tunnel Tests """
-
- self.pg1.config_ip6()
- self.pg1.resolve_ndp()
-
- #
- # Create an L3 GRE tunnel.
- # - set it admin up
- # - assign an IP Address
- # - Add a route via the tunnel
- #
- gre_if = VppGreInterface(self,
- self.pg2.local_ip6,
- "1002::1")
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip6()
-
- route_via_tun = VppIpRoute(self, "4004::1", 128,
- [VppRoutePath("0::0",
- gre_if.sw_if_index)])
-
- route_via_tun.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - they are all dropped since the tunnel's destintation IP
- # is unresolved - or resolves via the default route - which
- # which is a drop.
- #
- tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
- self.send_and_assert_no_replies(
- self.pg2, tx,
- "GRE packets forwarded without DIP resolved")
-
- #
- # Add a route that resolves the tunnel's destination
- #
- route_tun_dst = VppIpRoute(self, "1002::1", 128,
- [VppRoutePath(self.pg2.remote_ip6,
- self.pg2.sw_if_index)])
- route_tun_dst.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - packets are GRE encapped
- #
- tx = self.create_stream_ip6(self.pg2, "5005::1", "4004::1")
- rx = self.send_and_expect(self.pg2, tx, self.pg2)
- self.verify_tunneled_6o6(self.pg2, rx, tx,
- self.pg2.local_ip6, "1002::1")
-
- #
- # Test decap. decapped packets go out pg1
- #
- tx = self.create_tunnel_stream_6o6(self.pg2,
- "1002::1",
- self.pg2.local_ip6,
- "2001::1",
- self.pg1.remote_ip6)
- rx = self.send_and_expect(self.pg2, tx, self.pg1)
-
- #
- # RX'd packet is UDP over IPv6, test the GRE header is gone.
- #
- self.assertFalse(rx[0].haslayer(GRE))
- self.assertEqual(rx[0][IPv6].dst, self.pg1.remote_ip6)
-
- #
- # Send v4 over v6
- #
- route4_via_tun = VppIpRoute(self, "1.1.1.1", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index)])
- route4_via_tun.add_vpp_config()
-
- tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "1.1.1.1")
- rx = self.send_and_expect(self.pg0, tx, self.pg2)
-
- self.verify_tunneled_4o6(self.pg0, rx, tx,
- self.pg2.local_ip6, "1002::1")
-
- #
- # test case cleanup
- #
- route_tun_dst.remove_vpp_config()
- route_via_tun.remove_vpp_config()
- route4_via_tun.remove_vpp_config()
- gre_if.remove_vpp_config()
-
- self.pg2.unconfig_ip6()
- self.pg1.unconfig_ip6()
-
- def test_gre_vrf(self):
- """ GRE tunnel VRF Tests """
-
- e = VppEnum.vl_api_tunnel_encap_decap_flags_t
-
- #
- # Create an L3 GRE tunnel whose destination is in the non-default
- # table. The underlay is thus non-default - the overlay is still
- # the default.
- # - set it admin up
- # - assign an IP Addres
- #
- gre_if = VppGreInterface(
- self, self.pg1.local_ip4,
- "2.2.2.2",
- outer_table_id=1,
- flags=(e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP |
- e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN))
-
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip4()
-
- #
- # Add a route via the tunnel - in the overlay
- #
- route_via_tun = VppIpRoute(self, "9.9.9.9", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index)])
- route_via_tun.add_vpp_config()
-
- #
- # Add a route that resolves the tunnel's destination - in the
- # underlay table
- #
- route_tun_dst = VppIpRoute(self, "2.2.2.2", 32, table_id=1,
- paths=[VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index)])
- route_tun_dst.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # packets are sent in on pg0 which is in the default table
- # - packets are GRE encapped
- #
- self.vapi.cli("clear trace")
- tx = self.create_stream_ip4(self.pg0, "5.5.5.5", "9.9.9.9",
- dscp=5, ecn=3)
- rx = self.send_and_expect(self.pg0, tx, self.pg1)
- self.verify_tunneled_4o4(self.pg1, rx, tx,
- self.pg1.local_ip4, "2.2.2.2",
- dscp=5, ecn=3)
-
- #
- # Send tunneled packets that match the created tunnel and
- # are decapped and forwarded. This tests the decap lookup
- # does not happen in the encap table
- #
- self.vapi.cli("clear trace")
- tx = self.create_tunnel_stream_4o4(self.pg1,
- "2.2.2.2",
- self.pg1.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- rx = self.send_and_expect(self.pg1, tx, self.pg0)
- self.verify_decapped_4o4(self.pg0, rx, tx)
-
- #
- # Send tunneled packets that match the created tunnel
- # but arrive on an interface that is not in the tunnel's
- # encap VRF, these are dropped.
- # IP enable the interface so they aren't dropped due to
- # IP not being enabled.
- #
- self.pg2.config_ip4()
- self.vapi.cli("clear trace")
- tx = self.create_tunnel_stream_4o4(self.pg2,
- "2.2.2.2",
- self.pg1.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- rx = self.send_and_assert_no_replies(
- self.pg2, tx,
- "GRE decap packets in wrong VRF")
-
- self.pg2.unconfig_ip4()
-
- #
- # test case cleanup
- #
- route_tun_dst.remove_vpp_config()
- route_via_tun.remove_vpp_config()
- gre_if.remove_vpp_config()
-
- def test_gre_l2(self):
- """ GRE tunnel L2 Tests """
-
- #
- # Add routes to resolve the tunnel destinations
- #
- route_tun1_dst = VppIpRoute(self, "2.2.2.2", 32,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index)])
- route_tun2_dst = VppIpRoute(self, "2.2.2.3", 32,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index)])
-
- route_tun1_dst.add_vpp_config()
- route_tun2_dst.add_vpp_config()
-
- #
- # Create 2 L2 GRE tunnels and x-connect them
- #
- gre_if1 = VppGreInterface(self, self.pg0.local_ip4,
- "2.2.2.2",
- type=(VppEnum.vl_api_gre_tunnel_type_t.
- GRE_API_TUNNEL_TYPE_TEB))
- gre_if2 = VppGreInterface(self, self.pg0.local_ip4,
- "2.2.2.3",
- type=(VppEnum.vl_api_gre_tunnel_type_t.
- GRE_API_TUNNEL_TYPE_TEB))
- gre_if1.add_vpp_config()
- gre_if2.add_vpp_config()
-
- gre_if1.admin_up()
- gre_if2.admin_up()
-
- self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
- gre_if2.sw_if_index,
- enable=1)
- self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
- gre_if1.sw_if_index,
- enable=1)
-
- #
- # Send in tunnel encapped L2. expect out tunnel encapped L2
- # in both directions
- #
- tx = self.create_tunnel_stream_l2o4(self.pg0,
- "2.2.2.2",
- self.pg0.local_ip4)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_l2o4(self.pg0, rx, tx,
- self.pg0.local_ip4,
- "2.2.2.3")
-
- tx = self.create_tunnel_stream_l2o4(self.pg0,
- "2.2.2.3",
- self.pg0.local_ip4)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_l2o4(self.pg0, rx, tx,
- self.pg0.local_ip4,
- "2.2.2.2")
-
- self.vapi.sw_interface_set_l2_xconnect(gre_if1.sw_if_index,
- gre_if2.sw_if_index,
- enable=0)
- self.vapi.sw_interface_set_l2_xconnect(gre_if2.sw_if_index,
- gre_if1.sw_if_index,
- enable=0)
-
- #
- # Create a VLAN sub-interfaces on the GRE TEB interfaces
- # then x-connect them
- #
- gre_if_11 = VppDot1QSubint(self, gre_if1, 11)
- gre_if_12 = VppDot1QSubint(self, gre_if2, 12)
-
- # gre_if_11.add_vpp_config()
- # gre_if_12.add_vpp_config()
-
- gre_if_11.admin_up()
- gre_if_12.admin_up()
-
- self.vapi.sw_interface_set_l2_xconnect(gre_if_11.sw_if_index,
- gre_if_12.sw_if_index,
- enable=1)
- self.vapi.sw_interface_set_l2_xconnect(gre_if_12.sw_if_index,
- gre_if_11.sw_if_index,
- enable=1)
-
- #
- # Configure both to pop thier respective VLAN tags,
- # so that during the x-coonect they will subsequently push
- #
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=gre_if_12.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=12)
- self.vapi.l2_interface_vlan_tag_rewrite(
- sw_if_index=gre_if_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
- push_dot1q=11)
-
- #
- # Send traffic in both directiond - expect the VLAN tags to
- # be swapped.
- #
- tx = self.create_tunnel_stream_vlano4(self.pg0,
- "2.2.2.2",
- self.pg0.local_ip4,
- 11)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_vlano4(self.pg0, rx, tx,
- self.pg0.local_ip4,
- "2.2.2.3",
- 12)
-
- tx = self.create_tunnel_stream_vlano4(self.pg0,
- "2.2.2.3",
- self.pg0.local_ip4,
- 12)
- rx = self.send_and_expect(self.pg0, tx, self.pg0)
- self.verify_tunneled_vlano4(self.pg0, rx, tx,
- self.pg0.local_ip4,
- "2.2.2.2",
- 11)
-
- #
- # Cleanup Test resources
- #
- gre_if_11.remove_vpp_config()
- gre_if_12.remove_vpp_config()
- gre_if1.remove_vpp_config()
- gre_if2.remove_vpp_config()
- route_tun1_dst.add_vpp_config()
- route_tun2_dst.add_vpp_config()
-
- def test_gre_loop(self):
- """ GRE tunnel loop Tests """
-
- #
- # Create an L3 GRE tunnel.
- # - set it admin up
- # - assign an IP Addres
- #
- gre_if = VppGreInterface(self,
- self.pg0.local_ip4,
- "1.1.1.2")
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip4()
-
- #
- # add a route to the tunnel's destination that points
- # through the tunnel, hence forming a loop in the forwarding
- # graph
- #
- route_dst = VppIpRoute(self, "1.1.1.2", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index)])
- route_dst.add_vpp_config()
-
- #
- # packets to the tunnels destination should be dropped
- #
- tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "1.1.1.2")
- self.send_and_assert_no_replies(self.pg2, tx)
-
- self.logger.info(self.vapi.ppcli("sh adj 7"))
-
- #
- # break the loop
- #
- route_dst.modify([VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index)])
- route_dst.add_vpp_config()
-
- rx = self.send_and_expect(self.pg0, tx, self.pg1)
-
- #
- # a good route throught the tunnel to check it restacked
- #
- route_via_tun_2 = VppIpRoute(self, "2.2.2.2", 32,
- [VppRoutePath("0.0.0.0",
- gre_if.sw_if_index)])
- route_via_tun_2.add_vpp_config()
-
- tx = self.create_stream_ip4(self.pg0, "2.2.2.3", "2.2.2.2")
- rx = self.send_and_expect(self.pg0, tx, self.pg1)
- self.verify_tunneled_4o4(self.pg1, rx, tx,
- self.pg0.local_ip4, "1.1.1.2")
-
- #
- # cleanup
- #
- route_via_tun_2.remove_vpp_config()
- gre_if.remove_vpp_config()
-
- def test_mgre(self):
- """ mGRE IPv4 tunnel Tests """
-
- for itf in self.pg_interfaces[3:]:
- #
- # one underlay nh for each overlay/tunnel peer
- #
- itf.generate_remote_hosts(4)
- itf.configure_ipv4_neighbors()
-
- #
- # Create an L3 GRE tunnel.
- # - set it admin up
- # - assign an IP Addres
- # - Add a route via the tunnel
- #
- gre_if = VppGreInterface(self,
- itf.local_ip4,
- "0.0.0.0",
- mode=(VppEnum.vl_api_tunnel_mode_t.
- TUNNEL_API_MODE_MP))
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip4()
- gre_if.generate_remote_hosts(4)
-
- self.logger.info(self.vapi.cli("sh adj"))
- self.logger.info(self.vapi.cli("sh ip fib"))
-
- #
- # ensure we don't match to the tunnel if the source address
- # is all zeros
- #
- tx = self.create_tunnel_stream_4o4(self.pg0,
- "0.0.0.0",
- itf.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- self.send_and_assert_no_replies(self.pg0, tx)
-
- #
- # for-each peer
- #
- for ii in range(1, 4):
- route_addr = "4.4.4.%d" % ii
- tx_e = self.create_stream_ip4(self.pg0, "5.5.5.5", route_addr)
-
- #
- # route traffic via the peer
- #
- route_via_tun = VppIpRoute(
- self, route_addr, 32,
- [VppRoutePath(gre_if._remote_hosts[ii].ip4,
- gre_if.sw_if_index)])
- route_via_tun.add_vpp_config()
-
- # all packets dropped at this point
- rx = self.send_and_assert_no_replies(self.pg0, tx_e)
-
- gre_if.admin_down()
- gre_if.admin_up()
- rx = self.send_and_assert_no_replies(self.pg0, tx_e)
-
- #
- # Add a TEIB entry resolves the peer
- #
- teib = VppTeib(self, gre_if,
- gre_if._remote_hosts[ii].ip4,
- itf._remote_hosts[ii].ip4)
- teib.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - packets are GRE encapped
- #
- rx = self.send_and_expect(self.pg0, tx_e, itf)
- self.verify_tunneled_4o4(self.pg0, rx, tx_e,
- itf.local_ip4,
- itf._remote_hosts[ii].ip4)
-
- tx_i = self.create_tunnel_stream_4o4(self.pg0,
- itf._remote_hosts[ii].ip4,
- itf.local_ip4,
- self.pg0.local_ip4,
- self.pg0.remote_ip4)
- rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
- self.verify_decapped_4o4(self.pg0, rx, tx_i)
-
- #
- # delete and re-add the TEIB
- #
- teib.remove_vpp_config()
- self.send_and_assert_no_replies(self.pg0, tx_e)
- self.send_and_assert_no_replies(self.pg0, tx_i)
-
- teib.add_vpp_config()
- rx = self.send_and_expect(self.pg0, tx_e, itf)
- self.verify_tunneled_4o4(self.pg0, rx, tx_e,
- itf.local_ip4,
- itf._remote_hosts[ii].ip4)
- rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
- self.verify_decapped_4o4(self.pg0, rx, tx_i)
-
- #
- # bounce the interface state and try packets again
- #
- gre_if.admin_down()
- gre_if.admin_up()
- rx = self.send_and_expect(self.pg0, tx_e, itf)
- self.verify_tunneled_4o4(self.pg0, rx, tx_e,
- itf.local_ip4,
- itf._remote_hosts[ii].ip4)
- rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
- self.verify_decapped_4o4(self.pg0, rx, tx_i)
-
- gre_if.admin_down()
- gre_if.unconfig_ip4()
-
- def test_mgre6(self):
- """ mGRE IPv6 tunnel Tests """
-
- self.pg0.config_ip6()
- self.pg0.resolve_ndp()
-
- e = VppEnum.vl_api_tunnel_encap_decap_flags_t
-
- for itf in self.pg_interfaces[3:]:
- #
- # one underlay nh for each overlay/tunnel peer
- #
- itf.config_ip6()
- itf.generate_remote_hosts(4)
- itf.configure_ipv6_neighbors()
-
- #
- # Create an L3 GRE tunnel.
- # - set it admin up
- # - assign an IP Addres
- # - Add a route via the tunnel
- #
- gre_if = VppGreInterface(
- self,
- itf.local_ip6,
- "::",
- mode=(VppEnum.vl_api_tunnel_mode_t.
- TUNNEL_API_MODE_MP),
- flags=e.TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
-
- gre_if.add_vpp_config()
- gre_if.admin_up()
- gre_if.config_ip6()
- gre_if.generate_remote_hosts(4)
-
- #
- # for-each peer
- #
- for ii in range(1, 4):
- route_addr = "4::%d" % ii
-
- #
- # Add a TEIB entry resolves the peer
- #
- teib = VppTeib(self, gre_if,
- gre_if._remote_hosts[ii].ip6,
- itf._remote_hosts[ii].ip6)
- teib.add_vpp_config()
-
- #
- # route traffic via the peer
- #
- route_via_tun = VppIpRoute(
- self, route_addr, 128,
- [VppRoutePath(gre_if._remote_hosts[ii].ip6,
- gre_if.sw_if_index)])
- route_via_tun.add_vpp_config()
-
- #
- # Send a packet stream that is routed into the tunnel
- # - packets are GRE encapped
- #
- tx_e = self.create_stream_ip6(self.pg0, "5::5", route_addr,
- dscp=2, ecn=1)
- rx = self.send_and_expect(self.pg0, tx_e, itf)
- self.verify_tunneled_6o6(self.pg0, rx, tx_e,
- itf.local_ip6,
- itf._remote_hosts[ii].ip6,
- dscp=2)
- tx_i = self.create_tunnel_stream_6o6(self.pg0,
- itf._remote_hosts[ii].ip6,
- itf.local_ip6,
- self.pg0.local_ip6,
- self.pg0.remote_ip6)
- rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
- self.verify_decapped_6o6(self.pg0, rx, tx_i)
-
- #
- # delete and re-add the TEIB
- #
- teib.remove_vpp_config()
- self.send_and_assert_no_replies(self.pg0, tx_e)
-
- teib.add_vpp_config()
- rx = self.send_and_expect(self.pg0, tx_e, itf)
- self.verify_tunneled_6o6(self.pg0, rx, tx_e,
- itf.local_ip6,
- itf._remote_hosts[ii].ip6,
- dscp=2)
- rx = self.send_and_expect(self.pg0, tx_i, self.pg0)
- self.verify_decapped_6o6(self.pg0, rx, tx_i)
-
- gre_if.admin_down()
- gre_if.unconfig_ip4()
- itf.unconfig_ip6()
- self.pg0.unconfig_ip6()
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/gso/test/test_gro.py b/src/vnet/gso/test/test_gro.py
deleted file mode 100644
index 33215d65fa7..00000000000
--- a/src/vnet/gso/test/test_gro.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python3
-"""GRO functional tests"""
-
-#
-# Add tests for:
-# - GRO
-# - Verify that sending 1500 Bytes frame without GRO enabled correctly
-# - Verify that sending 1500 Bytes frame with GRO enabled correctly
-#
-import unittest
-
-from scapy.packet import Raw
-from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
-from scapy.layers.inet6 import ipv6nh, IPerror6
-from scapy.layers.inet import TCP, ICMP
-from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
-
-from framework import VppTestCase, VppTestRunner
-from vpp_object import VppObject
-from vpp_interface import VppInterface
-
-
-""" Test_gro is a subclass of VPPTestCase classes.
- GRO tests.
-"""
-
-
-class TestGRO(VppTestCase):
- """ GRO Test Case """
-
- @classmethod
- def setUpClass(self):
- super(TestGRO, self).setUpClass()
- res = self.create_pg_interfaces(range(2))
- res_gro = self.create_pg_interfaces(range(2, 3), 1, 1460)
- self.create_pg_interfaces(range(3, 4), 1, 8940)
- self.pg_interfaces.append(res[0])
- self.pg_interfaces.append(res[1])
- self.pg_interfaces.append(res_gro[0])
- self.pg2.coalesce_enable()
- self.pg3.coalesce_enable()
-
- @classmethod
- def tearDownClass(self):
- super(TestGRO, self).tearDownClass()
-
- def setUp(self):
- super(TestGRO, self).setUp()
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip4()
- i.config_ip6()
- i.disable_ipv6_ra()
- i.resolve_arp()
- i.resolve_ndp()
-
- def tearDown(self):
- super(TestGRO, self).tearDown()
- if not self.vpp_dead:
- for i in self.pg_interfaces:
- i.unconfig_ip4()
- i.unconfig_ip6()
- i.admin_down()
-
- def test_gro(self):
- """ GRO test """
-
- n_packets = 124
- #
- # Send 1500 bytes frame with gro disabled
- #
- p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=4321) /
- Raw(b'\xa5' * 1460))
-
- rxs = self.send_and_expect(self.pg0, n_packets * p4, self.pg1)
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 4321)
-
- #
- # Send 1500 bytes frame with gro enabled on
- # output interfaces support GRO
- #
- p = []
- s = 0
- for n in range(0, n_packets):
- p.append((Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=4321, seq=s, ack=n, flags='A') /
- Raw(b'\xa5' * 1460)))
- s += 1460
-
- rxs = self.send_and_expect(self.pg0, p, self.pg2, n_rx=2)
-
- i = 0
- for rx in rxs:
- i += 1
- self.assertEqual(rx[Ether].src, self.pg2.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].len, 64280) # 1460 * 44 + 40 < 65536
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 4321)
- self.assertEqual(rx[TCP].ack, (44*i - 1))
-
- p4_temp = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=4321, flags='F'))
-
- rxs = self.send_and_expect(self.pg2, 100*[p4_temp], self.pg0, n_rx=100)
- rx_coalesce = self.pg2.get_capture(1, timeout=1)
-
- rx0 = rx_coalesce[0]
- self.assertEqual(rx0[Ether].src, self.pg2.local_mac)
- self.assertEqual(rx0[Ether].dst, self.pg2.remote_mac)
- self.assertEqual(rx0[IP].src, self.pg0.remote_ip4)
- self.assertEqual(rx0[IP].dst, self.pg2.remote_ip4)
- self.assertEqual(rx0[IP].len, 52600) # 1460 * 36 + 40
- self.assertEqual(rx0[TCP].sport, 1234)
- self.assertEqual(rx0[TCP].dport, 4321)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assertEqual(rx[IP].len, 40)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 4321)
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/gso/test/test_gso.py b/src/vnet/gso/test/test_gso.py
deleted file mode 100644
index 094600eb74c..00000000000
--- a/src/vnet/gso/test/test_gso.py
+++ /dev/null
@@ -1,722 +0,0 @@
-#!/usr/bin/env python3
-"""GSO functional tests"""
-
-#
-# Add tests for:
-# - GSO
-# - Verify that sending Jumbo frame without GSO enabled correctly
-# - Verify that sending Jumbo frame with GSO enabled correctly
-# - Verify that sending Jumbo frame with GSO enabled only on ingress interface
-#
-import unittest
-
-from scapy.packet import Raw
-from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
-from scapy.layers.inet6 import ipv6nh, IPerror6
-from scapy.layers.inet import TCP, ICMP
-from scapy.layers.vxlan import VXLAN
-from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
-
-from framework import VppTestCase, VppTestRunner
-from vpp_object import VppObject
-from vpp_interface import VppInterface
-from vpp_ip import DpoProto
-from vpp_ip_route import VppIpRoute, VppRoutePath, FibPathProto
-from vpp_ipip_tun_interface import VppIpIpTunInterface
-from vpp_vxlan_tunnel import VppVxlanTunnel
-from socket import AF_INET, AF_INET6, inet_pton
-from util import reassemble4
-
-
-""" Test_gso is a subclass of VPPTestCase classes.
- GSO tests.
-"""
-
-
-class TestGSO(VppTestCase):
- """ GSO Test Case """
-
- def __init__(self, *args):
- VppTestCase.__init__(self, *args)
-
- @classmethod
- def setUpClass(self):
- super(TestGSO, self).setUpClass()
- res = self.create_pg_interfaces(range(2))
- res_gso = self.create_pg_interfaces(range(2, 4), 1, 1460)
- self.create_pg_interfaces(range(4, 5), 1, 8940)
- self.pg_interfaces.append(res[0])
- self.pg_interfaces.append(res[1])
- self.pg_interfaces.append(res_gso[0])
- self.pg_interfaces.append(res_gso[1])
-
- @classmethod
- def tearDownClass(self):
- super(TestGSO, self).tearDownClass()
-
- def setUp(self):
- super(TestGSO, self).setUp()
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip4()
- i.config_ip6()
- i.disable_ipv6_ra()
- i.resolve_arp()
- i.resolve_ndp()
-
- self.single_tunnel_bd = 10
- self.vxlan = VppVxlanTunnel(self, src=self.pg0.local_ip4,
- dst=self.pg0.remote_ip4,
- vni=self.single_tunnel_bd)
-
- self.vxlan2 = VppVxlanTunnel(self, src=self.pg0.local_ip6,
- dst=self.pg0.remote_ip6,
- vni=self.single_tunnel_bd)
-
- self.ipip4 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip4,
- self.pg0.remote_ip4)
- self.ipip6 = VppIpIpTunInterface(self, self.pg0, self.pg0.local_ip6,
- self.pg0.remote_ip6)
-
- def tearDown(self):
- super(TestGSO, self).tearDown()
- if not self.vpp_dead:
- for i in self.pg_interfaces:
- i.unconfig_ip4()
- i.unconfig_ip6()
- i.admin_down()
-
- def test_gso(self):
- """ GSO test """
- #
- # Send jumbo frame with gso disabled and DF bit is set
- #
- p4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg0, [p4], self.pg0)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assertEqual(rx[ICMP].type, 3) # "dest-unreach"
- self.assertEqual(rx[ICMP].code, 4) # "fragmentation-needed"
-
- #
- # Send checksum offload frames
- #
- p40 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 1460))
-
- rxs = self.send_and_expect(self.pg2, 100*[p40], self.pg0)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- payload_len = rx[IP].len - 20 - 20
- self.assert_ip_checksum_valid(rx)
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(payload_len, len(rx[Raw]))
-
- p60 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 1440))
-
- rxs = self.send_and_expect(self.pg2, 100*[p60], self.pg0)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- payload_len = rx[IPv6].plen - 20
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(payload_len, len(rx[Raw]))
-
- #
- # Send jumbo frame with gso enabled and DF bit is set
- # input and output interfaces support GSO
- #
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg3.sw_if_index,
- enable_disable=1)
- p41 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 100*[p41], self.pg3, 100)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg3.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
- self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
- self.assertEqual(rx[IP].len, 65240) # 65200 + 20 (IP) + 20 (TCP)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 1234)
-
- #
- # ipv6
- #
- p61 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IPv6(src=self.pg2.remote_ip6, dst=self.pg3.remote_ip6) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 100*[p61], self.pg3, 100)
-
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg3.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg3.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg3.remote_ip6)
- self.assertEqual(rx[IPv6].plen, 65220) # 65200 + 20 (TCP)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 1234)
-
- #
- # Send jumbo frame with gso enabled only on input interface
- # and DF bit is set. GSO packet will be chunked into gso_size
- # data payload
- #
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=1)
- p42 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.remote_ip4, dst=self.pg0.remote_ip4,
- flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p42], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
- self.assert_ip_checksum_valid(rx)
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 1234)
- self.assertEqual(payload_len, len(rx[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # ipv6
- #
- p62 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IPv6(src=self.pg2.remote_ip6, dst=self.pg0.remote_ip6) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p62], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- payload_len = rx[IPv6].plen - 20
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(rx[TCP].sport, 1234)
- self.assertEqual(rx[TCP].dport, 1234)
- self.assertEqual(payload_len, len(rx[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # Send jumbo frame with gso enabled only on input interface
- # and DF bit is unset. GSO packet will be fragmented.
- #
- self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [576, 0, 0, 0])
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg1.sw_if_index,
- enable_disable=1)
-
- p43 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IP(src=self.pg2.remote_ip4, dst=self.pg1.remote_ip4) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p43], self.pg1, 5*119)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
- self.assertEqual(rx[IP].src, self.pg2.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- size += rx[IP].len - 20
- size -= 20*5 # TCP header
- self.assertEqual(size, 65200*5)
-
- #
- # IPv6
- # Send jumbo frame with gso enabled only on input interface.
- # ICMPv6 Packet Too Big will be sent back to sender.
- #
- self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1280, 0, 0, 0])
- p63 = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
- IPv6(src=self.pg2.remote_ip6, dst=self.pg1.remote_ip6) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p63], self.pg2, 5)
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg2.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg2.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg2.local_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg2.remote_ip6)
- self.assertEqual(rx[IPv6].plen, 1240) # MTU - IPv6 header
- self.assertEqual(ipv6nh[rx[IPv6].nh], "ICMPv6")
- self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 1280)
- self.assertEqual(rx[IPerror6].src, self.pg2.remote_ip6)
- self.assertEqual(rx[IPerror6].dst, self.pg1.remote_ip6)
- self.assertEqual(rx[IPerror6].plen - 20, 65200)
-
- #
- # Send jumbo frame with gso enabled only on input interface with 9K MTU
- # and DF bit is unset. GSO packet will be fragmented. MSS is 8960. GSO
- # size will be min(MSS, 2048 - 14 - 20) vlib_buffer_t size
- #
- self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
- self.vapi.sw_interface_set_mtu(self.pg4.sw_if_index, [9000, 0, 0, 0])
- p44 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
- IP(src=self.pg4.remote_ip4, dst=self.pg1.remote_ip4) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg4, 5*[p44], self.pg1, 165)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
- self.assertEqual(rx[IP].src, self.pg4.remote_ip4)
- self.assertEqual(rx[IP].dst, self.pg1.remote_ip4)
- payload_len = rx[IP].len - 20 - 20 # len - 20 (IP4) - 20 (TCP)
- self.assert_ip_checksum_valid(rx)
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(payload_len, len(rx[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # IPv6
- #
- p64 = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
- IPv6(src=self.pg4.remote_ip6, dst=self.pg1.remote_ip6) /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg4, 5*[p64], self.pg1, 170)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg4.remote_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg1.remote_ip6)
- payload_len = rx[IPv6].plen - 20
- self.assert_tcp_checksum_valid(rx)
- self.assertEqual(payload_len, len(rx[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=0)
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg1.sw_if_index,
- enable_disable=0)
-
- def test_gso_vxlan(self):
- """ GSO VXLAN test """
- self.logger.info(self.vapi.cli("sh int addr"))
- #
- # Send jumbo frame with gso enabled only on input interface and
- # create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg2
- # into BD.
- #
-
- #
- # enable ipv4/vxlan
- #
- self.vxlan.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.vxlan.sw_if_index, bd_id=self.single_tunnel_bd)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.single_tunnel_bd)
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=1)
-
- #
- # IPv4/IPv4 - VXLAN
- #
- p45 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p45], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
- self.assertEqual(rx[VXLAN].vni, 10)
- inner = rx[VXLAN].payload
- self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
- self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
- self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
- self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
- self.assertEqual(inner[IP].dst, "172.16.3.3")
- self.assert_ip_checksum_valid(inner)
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IP].len - 20 - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # IPv4/IPv6 - VXLAN
- #
- p65 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p65], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
- self.assertEqual(rx[VXLAN].vni, 10)
- inner = rx[VXLAN].payload
- self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
- self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
- self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
- self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(inner[IPv6].dst, "fd01:3::3")
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IPv6].plen - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # disable ipv4/vxlan
- #
- self.vxlan.remove_vpp_config()
-
- #
- # enable ipv6/vxlan
- #
- self.vxlan2.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.vxlan2.sw_if_index,
- bd_id=self.single_tunnel_bd)
-
- #
- # IPv6/IPv4 - VXLAN
- #
- p46 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p46], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
- self.assertEqual(rx[VXLAN].vni, 10)
- inner = rx[VXLAN].payload
- self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
- self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
- self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
- self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
- self.assertEqual(inner[IP].dst, "172.16.3.3")
- self.assert_ip_checksum_valid(inner)
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IP].len - 20 - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # IPv6/IPv6 - VXLAN
- #
- p66 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3") /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p66], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
- self.assertEqual(rx[VXLAN].vni, 10)
- inner = rx[VXLAN].payload
- self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
- self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
- self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
- self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(inner[IPv6].dst, "fd01:3::3")
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IPv6].plen - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # disable ipv4/vxlan
- #
- self.vxlan2.remove_vpp_config()
-
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=0)
-
- def test_gso_ipip(self):
- """ GSO IPIP test """
- self.logger.info(self.vapi.cli("sh int addr"))
- #
- # Send jumbo frame with gso enabled only on input interface and
- # create IPIP tunnel on VPP pg0.
- #
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=1)
-
- #
- # enable ipip4
- #
- self.ipip4.add_vpp_config()
-
- # Set interface up and enable IP on it
- self.ipip4.admin_up()
- self.ipip4.set_unnumbered(self.pg0.sw_if_index)
-
- # Add IPv4 routes via tunnel interface
- self.ip4_via_ip4_tunnel = VppIpRoute(
- self, "172.16.10.0", 24,
- [VppRoutePath("0.0.0.0",
- self.ipip4.sw_if_index,
- proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
- self.ip4_via_ip4_tunnel.add_vpp_config()
-
- #
- # IPv4/IPv4 - IPIP
- #
- p47 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- self.assertEqual(rx[IP].proto, 4) # ipencap
- inner = rx[IP].payload
- self.assertEqual(rx[IP].len - 20, len(inner))
- self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
- self.assertEqual(inner[IP].dst, "172.16.10.3")
- self.assert_ip_checksum_valid(inner)
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IP].len - 20 - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- self.ip6_via_ip4_tunnel = VppIpRoute(
- self, "fd01:10::", 64,
- [VppRoutePath("::",
- self.ipip4.sw_if_index,
- proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
- self.ip6_via_ip4_tunnel.add_vpp_config()
- #
- # IPv4/IPv6 - IPIP
- #
- p67 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p67], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- self.assertEqual(rx[IP].proto, 41) # ipv6
- inner = rx[IP].payload
- self.assertEqual(rx[IP].len - 20, len(inner))
- self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(inner[IPv6].dst, "fd01:10::3")
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IPv6].plen - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # Send jumbo frame with gso enabled only on input interface and
- # create IPIP tunnel on VPP pg0. Enable gso feature node on ipip
- # tunnel - IPSec use case
- #
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=0)
- self.vapi.feature_gso_enable_disable(
- sw_if_index=self.ipip4.sw_if_index,
- enable_disable=1)
-
- rxs = self.send_and_expect(self.pg2, 5*[p47], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IP].src, self.pg0.local_ip4)
- self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
- self.assert_ip_checksum_valid(rx)
- self.assertEqual(rx[IP].proto, 4) # ipencap
- inner = rx[IP].payload
- self.assertEqual(rx[IP].len - 20, len(inner))
- self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
- self.assertEqual(inner[IP].dst, "172.16.10.3")
- self.assert_ip_checksum_valid(inner)
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IP].len - 20 - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # disable ipip4
- #
- self.vapi.feature_gso_enable_disable(
- sw_if_index=self.ipip4.sw_if_index,
- enable_disable=0)
- self.ip4_via_ip4_tunnel.remove_vpp_config()
- self.ip6_via_ip4_tunnel.remove_vpp_config()
- self.ipip4.remove_vpp_config()
-
- #
- # enable ipip6
- #
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=1)
- self.ipip6.add_vpp_config()
-
- # Set interface up and enable IP on it
- self.ipip6.admin_up()
- self.ipip6.set_unnumbered(self.pg0.sw_if_index)
-
- # Add IPv4 routes via tunnel interface
- self.ip4_via_ip6_tunnel = VppIpRoute(
- self, "172.16.10.0", 24,
- [VppRoutePath("0.0.0.0",
- self.ipip6.sw_if_index,
- proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)])
- self.ip4_via_ip6_tunnel.add_vpp_config()
-
- #
- # IPv6/IPv4 - IPIP
- #
- p48 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags='DF') /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p48], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assertEqual(ipv6nh[rx[IPv6].nh], "IP")
- inner = rx[IPv6].payload
- self.assertEqual(rx[IPv6].plen, len(inner))
- self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
- self.assertEqual(inner[IP].dst, "172.16.10.3")
- self.assert_ip_checksum_valid(inner)
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IP].len - 20 - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- self.ip6_via_ip6_tunnel = VppIpRoute(
- self, "fd01:10::", 64,
- [VppRoutePath("::",
- self.ipip6.sw_if_index,
- proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
- self.ip6_via_ip6_tunnel.add_vpp_config()
-
- #
- # IPv6/IPv6 - IPIP
- #
- p68 = (Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79") /
- IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3") /
- TCP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 65200))
-
- rxs = self.send_and_expect(self.pg2, 5*[p68], self.pg0, 225)
- size = 0
- for rx in rxs:
- self.assertEqual(rx[Ether].src, self.pg0.local_mac)
- self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
- self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
- self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assertEqual(ipv6nh[rx[IPv6].nh], "IPv6")
- inner = rx[IPv6].payload
- self.assertEqual(rx[IPv6].plen, len(inner))
- self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
- self.assertEqual(inner[IPv6].dst, "fd01:10::3")
- self.assert_tcp_checksum_valid(inner)
- payload_len = inner[IPv6].plen - 20
- self.assertEqual(payload_len, len(inner[Raw]))
- size += payload_len
- self.assertEqual(size, 65200*5)
-
- #
- # disable ipip6
- #
- self.ip4_via_ip6_tunnel.remove_vpp_config()
- self.ip6_via_ip6_tunnel.remove_vpp_config()
- self.ipip6.remove_vpp_config()
-
- self.vapi.feature_gso_enable_disable(sw_if_index=self.pg0.sw_if_index,
- enable_disable=0)
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/policer/test/test_policer.py b/src/vnet/policer/test/test_policer.py
deleted file mode 100644
index 6b15a0234a3..00000000000
--- a/src/vnet/policer/test/test_policer.py
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2021 Graphiant, Inc.
-
-import unittest
-
-from framework import VppTestCase, VppTestRunner
-from vpp_policer import VppPolicer, PolicerAction
-
-# Default for the tests is 10s of "Green" packets at 8Mbps, ie. 10M bytes.
-# The policer helper CLI "sends" 500 byte packets, so default is 20000.
-
-TEST_RATE = 8000 # kbps
-TEST_BURST = 10000 # ms
-
-CIR_OK = 8500 # CIR in kbps, above test rate
-CIR_LOW = 7000 # CIR in kbps, below test rate
-EIR_OK = 9000 # EIR in kbps, above test rate
-EIR_LOW = 7500 # EIR in kbps, below test rate
-
-NUM_PKTS = 20000
-
-CBURST = 100000 # Committed burst in bytes
-EBURST = 200000 # Excess burst in bytes
-
-
-class TestPolicer(VppTestCase):
- """ Policer Test Case """
-
- def run_policer_test(self, type, cir, cb, eir, eb, rate=8000, burst=10000,
- colour=0):
- """
- Configure a Policer and push traffic through it.
- """
- types = {
- '1R2C': 0,
- '1R3C': 1,
- '2R3C': 3,
- }
-
- pol_type = types.get(type)
- policer = VppPolicer(self, "pol1", cir, eir, cb, eb, rate_type=0,
- type=pol_type, color_aware=colour)
- policer.add_vpp_config()
-
- error = self.vapi.cli(
- f"test policing index {policer.policer_index} rate {rate} "
- f"burst {burst} colour {colour}")
-
- stats = policer.get_stats()
- policer.remove_vpp_config()
-
- return stats
-
- def test_policer_1r2c(self):
- """ Single rate, 2 colour policer """
- stats = self.run_policer_test("1R2C", CIR_OK, CBURST, 0, 0)
- self.assertEqual(stats['conform_packets'], NUM_PKTS)
-
- stats = self.run_policer_test("1R2C", CIR_LOW, CBURST, 0, 0)
- self.assertLess(stats['conform_packets'], NUM_PKTS)
- self.assertEqual(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("1R2C", CIR_LOW, CBURST, 0, 0, colour=2)
- self.assertEqual(stats['violate_packets'], NUM_PKTS)
-
- def test_policer_1r3c(self):
- """ Single rate, 3 colour policer """
- stats = self.run_policer_test("1R3C", CIR_OK, CBURST, 0, 0)
- self.assertEqual(stats['conform_packets'], NUM_PKTS)
-
- stats = self.run_policer_test("1R3C", CIR_LOW, CBURST, 0, EBURST)
- self.assertLess(stats['conform_packets'], NUM_PKTS)
- self.assertGreater(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("1R3C", CIR_LOW, CBURST, 0, EBURST,
- colour=1)
- self.assertEqual(stats['conform_packets'], 0)
- self.assertGreater(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("1R3C", CIR_LOW, CBURST, 0, EBURST,
- colour=2)
- self.assertEqual(stats['violate_packets'], NUM_PKTS)
-
- def test_policer_2r3c(self):
- """ Dual rate, 3 colour policer """
- stats = self.run_policer_test("2R3C", CIR_OK, CBURST, EIR_OK, EBURST)
- self.assertEqual(stats['conform_packets'], NUM_PKTS)
-
- stats = self.run_policer_test("2R3C", CIR_LOW, CBURST, EIR_OK, EBURST)
- self.assertLess(stats['conform_packets'], NUM_PKTS)
- self.assertGreater(stats['exceed_packets'], 0)
- self.assertEqual(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("2R3C", CIR_LOW, CBURST, EIR_LOW, EBURST)
- self.assertLess(stats['conform_packets'], NUM_PKTS)
- self.assertGreater(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("2R3C", CIR_LOW, CBURST, EIR_OK, EBURST,
- colour=1)
- self.assertEqual(stats['exceed_packets'], NUM_PKTS)
-
- stats = self.run_policer_test("2R3C", CIR_LOW, CBURST, EIR_LOW, EBURST,
- colour=1)
- self.assertEqual(stats['conform_packets'], 0)
- self.assertGreater(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- stats = self.run_policer_test("2R3C", CIR_LOW, CBURST, EIR_OK, EBURST,
- colour=2)
- self.assertEqual(stats['violate_packets'], NUM_PKTS)
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/policer/test/test_policer_input.py b/src/vnet/policer/test/test_policer_input.py
deleted file mode 100644
index c95f6643ff2..00000000000
--- a/src/vnet/policer/test/test_policer_input.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2021 Graphiant, Inc.
-
-import unittest
-import scapy.compat
-from scapy.layers.inet import IP, UDP
-from scapy.layers.l2 import Ether
-from scapy.packet import Raw
-from framework import VppTestCase, VppTestRunner
-from vpp_papi import VppEnum
-from vpp_policer import VppPolicer, PolicerAction
-
-NUM_PKTS = 67
-
-
-class TestPolicerInput(VppTestCase):
- """ Policer on an input interface """
- vpp_worker_count = 2
-
- def setUp(self):
- super(TestPolicerInput, self).setUp()
-
- self.create_pg_interfaces(range(2))
- for i in self.pg_interfaces:
- i.admin_up()
- i.config_ip4()
- i.resolve_arp()
-
- self.pkt = (Ether(src=self.pg0.remote_mac,
- dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
- UDP(sport=1234, dport=1234) /
- Raw(b'\xa5' * 100))
-
- def tearDown(self):
- for i in self.pg_interfaces:
- i.unconfig_ip4()
- i.admin_down()
- super(TestPolicerInput, self).tearDown()
-
- def test_policer_input(self):
- """ Input Policing """
- pkts = self.pkt * NUM_PKTS
-
- action_tx = PolicerAction(
- VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT,
- 0)
- policer = VppPolicer(self, "pol1", 80, 0, 1000, 0,
- conform_action=action_tx,
- exceed_action=action_tx,
- violate_action=action_tx)
- policer.add_vpp_config()
-
- # Start policing on pg0
- policer.apply_vpp_config(self.pg0.sw_if_index, True)
-
- rx = self.send_and_expect(self.pg0, pkts, self.pg1, worker=0)
- stats = policer.get_stats()
-
- # Single rate, 2 colour policer - expect conform, violate but no exceed
- self.assertGreater(stats['conform_packets'], 0)
- self.assertEqual(stats['exceed_packets'], 0)
- self.assertGreater(stats['violate_packets'], 0)
-
- # Stop policing on pg0
- policer.apply_vpp_config(self.pg0.sw_if_index, False)
-
- rx = self.send_and_expect(self.pg0, pkts, self.pg1, worker=0)
-
- statsnew = policer.get_stats()
-
- # No new packets counted
- self.assertEqual(stats, statsnew)
-
- policer.remove_vpp_config()
-
- def test_policer_handoff(self):
- """ Worker thread handoff """
- pkts = self.pkt * NUM_PKTS
-
- action_tx = PolicerAction(
- VppEnum.vl_api_sse2_qos_action_type_t.SSE2_QOS_ACTION_API_TRANSMIT,
- 0)
- policer = VppPolicer(self, "pol2", 80, 0, 1000, 0,
- conform_action=action_tx,
- exceed_action=action_tx,
- violate_action=action_tx)
- policer.add_vpp_config()
-
- # Bind the policer to worker 1
- policer.bind_vpp_config(1, True)
-
- # Start policing on pg0
- policer.apply_vpp_config(self.pg0.sw_if_index, True)
-
- for worker in [0, 1]:
- self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker)
- self.logger.debug(self.vapi.cli("show trace max 100"))
-
- stats = policer.get_stats()
- stats0 = policer.get_stats(worker=0)
- stats1 = policer.get_stats(worker=1)
-
- # Worker 1, should have done all the policing
- self.assertEqual(stats, stats1)
-
- # Worker 0, should have handed everything off
- self.assertEqual(stats0['conform_packets'], 0)
- self.assertEqual(stats0['exceed_packets'], 0)
- self.assertEqual(stats0['violate_packets'], 0)
-
- # Unbind the policer from worker 1 and repeat
- policer.bind_vpp_config(1, False)
- for worker in [0, 1]:
- self.send_and_expect(self.pg0, pkts, self.pg1, worker=worker)
- self.logger.debug(self.vapi.cli("show trace max 100"))
-
- # The policer should auto-bind to worker 0 when packets arrive
- stats = policer.get_stats()
-
- # The 2 workers should now have policed the same amount
- stats = policer.get_stats()
- stats0 = policer.get_stats(worker=0)
- stats1 = policer.get_stats(worker=1)
-
- self.assertGreater(stats0['conform_packets'], 0)
- self.assertEqual(stats0['exceed_packets'], 0)
- self.assertGreater(stats0['violate_packets'], 0)
-
- self.assertGreater(stats1['conform_packets'], 0)
- self.assertEqual(stats1['exceed_packets'], 0)
- self.assertGreater(stats1['violate_packets'], 0)
-
- self.assertEqual(stats0['conform_packets'] + stats1['conform_packets'],
- stats['conform_packets'])
-
- self.assertEqual(stats0['violate_packets'] + stats1['violate_packets'],
- stats['violate_packets'])
-
- # Stop policing on pg0
- policer.apply_vpp_config(self.pg0.sw_if_index, False)
-
- policer.remove_vpp_config()
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/vxlan/test/test_vxlan.py b/src/vnet/vxlan/test/test_vxlan.py
deleted file mode 100644
index 028275ccedf..00000000000
--- a/src/vnet/vxlan/test/test_vxlan.py
+++ /dev/null
@@ -1,421 +0,0 @@
-#!/usr/bin/env python3
-
-import socket
-from util import ip4_range, reassemble4
-import unittest
-from framework import VppTestCase, VppTestRunner
-from template_bd import BridgeDomain
-
-from scapy.layers.l2 import Ether
-from scapy.packet import Raw, bind_layers
-from scapy.layers.inet import IP, UDP
-from scapy.layers.vxlan import VXLAN
-
-import util
-from vpp_ip_route import VppIpRoute, VppRoutePath
-from vpp_vxlan_tunnel import VppVxlanTunnel
-from vpp_ip import INVALID_INDEX
-
-
-class TestVxlan(BridgeDomain, VppTestCase):
- """ VXLAN Test Case """
-
- def __init__(self, *args):
- BridgeDomain.__init__(self)
- VppTestCase.__init__(self, *args)
-
- def encapsulate(self, pkt, vni):
- """
- Encapsulate the original payload frame by adding VXLAN header with its
- UDP, IP and Ethernet fields
- """
- return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- def ip_range(self, start, end):
- """ range of remote ip's """
- return ip4_range(self.pg0.remote_ip4, start, end)
-
- def encap_mcast(self, pkt, src_ip, src_mac, vni):
- """
- Encapsulate the original payload frame by adding VXLAN header with its
- UDP, IP and Ethernet fields
- """
- return (Ether(src=src_mac, dst=self.mcast_mac) /
- IP(src=src_ip, dst=self.mcast_ip4) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- def decapsulate(self, pkt):
- """
- Decapsulate the original payload frame by removing VXLAN header
- """
- # check if is set I flag
- self.assertEqual(pkt[VXLAN].flags, int('0x8', 16))
- return pkt[VXLAN].payload
-
- # Method for checking VXLAN encapsulation.
- #
- def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
- # TODO: add error messages
- # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
- # by VPP using ARP.
- self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
- else:
- self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
- # Verify VXLAN tunnel source IP is VPP_IP and destination IP is MY_IP.
- self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
- else:
- self.assertEqual(pkt[IP].dst, type(self).mcast_ip4)
- # Verify UDP destination port is VXLAN 4789, source UDP port could be
- # arbitrary.
- self.assertEqual(pkt[UDP].dport, self.dport)
- # Verify UDP checksum
- self.assert_udp_checksum_valid(pkt)
- # Verify VNI
- self.assertEqual(pkt[VXLAN].vni, vni)
-
- @classmethod
- def create_vxlan_flood_test_bd(cls, vni, n_ucast_tunnels, port):
- # Create 10 ucast vxlan tunnels under bd
- ip_range_start = 10
- ip_range_end = ip_range_start + n_ucast_tunnels
- next_hop_address = cls.pg0.remote_ip4
- for dest_ip4 in ip4_range(next_hop_address, ip_range_start,
- ip_range_end):
- # add host route so dest_ip4 will not be resolved
- rip = VppIpRoute(cls, dest_ip4, 32,
- [VppRoutePath(next_hop_address,
- INVALID_INDEX)],
- register=False)
- rip.add_vpp_config()
-
- r = VppVxlanTunnel(cls, src=cls.pg0.local_ip4,
- src_port=port, dst_port=port,
- dst=dest_ip4, vni=vni)
- r.add_vpp_config()
- cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index, bd_id=vni)
-
- @classmethod
- def add_del_shared_mcast_dst_load(cls, port, is_add):
- """
- add or del tunnels sharing the same mcast dst
- to test vxlan ref_count mechanism
- """
- n_shared_dst_tunnels = 20
- vni_start = 10000
- vni_end = vni_start + n_shared_dst_tunnels
- for vni in range(vni_start, vni_end):
- r = VppVxlanTunnel(cls, src=cls.pg0.local_ip4,
- src_port=port, dst_port=port,
- dst=cls.mcast_ip4, mcast_sw_if_index=1, vni=vni)
- if is_add:
- r.add_vpp_config()
- if r.sw_if_index == 0xffffffff:
- raise ValueError("bad sw_if_index: ~0")
- else:
- r.remove_vpp_config()
-
- @classmethod
- def add_shared_mcast_dst_load(cls, port):
- cls.add_del_shared_mcast_dst_load(port=port, is_add=1)
-
- @classmethod
- def del_shared_mcast_dst_load(cls, port):
- cls.add_del_shared_mcast_dst_load(port=port, is_add=0)
-
- @classmethod
- def add_del_mcast_tunnels_load(cls, port, is_add):
- """
- add or del tunnels to test vxlan stability
- """
- n_distinct_dst_tunnels = 200
- ip_range_start = 10
- ip_range_end = ip_range_start + n_distinct_dst_tunnels
- for dest_ip4 in ip4_range(cls.mcast_ip4, ip_range_start,
- ip_range_end):
- vni = bytearray(socket.inet_pton(socket.AF_INET, dest_ip4))[3]
- r = VppVxlanTunnel(cls, src=cls.pg0.local_ip4,
- src_port=port, dst_port=port,
- dst=dest_ip4, mcast_sw_if_index=1, vni=vni)
- if is_add:
- r.add_vpp_config()
- else:
- r.remove_vpp_config()
-
- @classmethod
- def add_mcast_tunnels_load(cls, port):
- cls.add_del_mcast_tunnels_load(port=port, is_add=1)
-
- @classmethod
- def del_mcast_tunnels_load(cls, port):
- cls.add_del_mcast_tunnels_load(port=port, is_add=0)
-
- # Class method to start the VXLAN test case.
- # Overrides setUpClass method in VppTestCase class.
- # Python try..except statement is used to ensure that the tear down of
- # the class will be executed even if exception is raised.
- # @param cls The class pointer.
- @classmethod
- def setUpClass(cls):
- super(TestVxlan, cls).setUpClass()
-
- try:
- cls.flags = 0x8
-
- # Create 2 pg interfaces.
- cls.create_pg_interfaces(range(4))
- for pg in cls.pg_interfaces:
- pg.admin_up()
-
- # Configure IPv4 addresses on VPP pg0.
- cls.pg0.config_ip4()
-
- # Resolve MAC address for VPP's IP address on pg0.
- cls.pg0.resolve_arp()
-
- # Our Multicast address
- cls.mcast_ip4 = '239.1.1.1'
- cls.mcast_mac = util.mcast_ip_to_mac(cls.mcast_ip4)
- except Exception:
- cls.tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(TestVxlan, cls).tearDownClass()
-
- def setUp(self):
- super(TestVxlan, self).setUp()
-
- def createVxLANInterfaces(self, port=4789):
- # Create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg1
- # into BD.
- self.dport = port
-
- self.single_tunnel_vni = 0x12345
- self.single_tunnel_bd = 1
- r = VppVxlanTunnel(self, src=self.pg0.local_ip4,
- dst=self.pg0.remote_ip4,
- src_port=self.dport, dst_port=self.dport,
- vni=self.single_tunnel_vni)
- r.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=self.single_tunnel_bd)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=self.single_tunnel_bd)
-
- # Setup vni 2 to test multicast flooding
- self.n_ucast_tunnels = 10
- self.mcast_flood_bd = 2
- self.create_vxlan_flood_test_bd(self.mcast_flood_bd,
- self.n_ucast_tunnels,
- self.dport)
- r = VppVxlanTunnel(self, src=self.pg0.local_ip4, dst=self.mcast_ip4,
- src_port=self.dport, dst_port=self.dport,
- mcast_sw_if_index=1, vni=self.mcast_flood_bd)
- r.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=self.mcast_flood_bd)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.mcast_flood_bd)
-
- # Add and delete mcast tunnels to check stability
- self.add_shared_mcast_dst_load(self.dport)
- self.add_mcast_tunnels_load(self.dport)
- self.del_shared_mcast_dst_load(self.dport)
- self.del_mcast_tunnels_load(self.dport)
-
- # Setup vni 3 to test unicast flooding
- self.ucast_flood_bd = 3
- self.create_vxlan_flood_test_bd(self.ucast_flood_bd,
- self.n_ucast_tunnels,
- self.dport)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg3.sw_if_index, bd_id=self.ucast_flood_bd)
-
- # Set scapy listen custom port for VxLAN
- bind_layers(UDP, VXLAN, dport=self.dport)
-
- def encap_big_packet(self):
- self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])
-
- frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
- IP(src='4.3.2.1', dst='1.2.3.4') /
- UDP(sport=20000, dport=10000) /
- Raw(b'\xa5' * 1450))
-
- self.pg1.add_stream([frame])
-
- self.pg0.enable_capture()
-
- self.pg_start()
-
- # Pick first received frame and check if it's correctly encapsulated.
- out = self.pg0.get_capture(2)
- ether = out[0]
- pkt = reassemble4(out)
- pkt = ether / pkt
- self.check_encapsulation(pkt, self.single_tunnel_vni)
-
- payload = self.decapsulate(pkt)
- # TODO: Scapy bug?
- # self.assert_eq_pkts(payload, frame)
-
- """
- Tests with default port (4789)
- """
- def test_decap(self):
- """ Decapsulation test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan, self).test_decap()
-
- def test_encap(self):
- """ Encapsulation test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan, self).test_encap()
-
- def test_encap_big_packet(self):
- """ Encapsulation test send big frame from pg1
- Verify receipt of encapsulated frames on pg0
- """
- self.createVxLANInterfaces()
- self.encap_big_packet()
-
- def test_ucast_flood(self):
- """ Unicast flood test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan, self).test_ucast_flood()
-
- def test_mcast_flood(self):
- """ Multicast flood test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan, self).test_mcast_flood()
-
- def test_mcast_rcv(self):
- """ Multicast receive test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan, self).test_mcast_rcv()
-
- """
- Tests with custom port
- """
- def test_decap_custom_port(self):
- """ Decapsulation test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan, self).test_decap()
-
- def test_encap_custom_port(self):
- """ Encapsulation test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan, self).test_encap()
-
- def test_ucast_flood_custom_port(self):
- """ Unicast flood test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan, self).test_ucast_flood()
-
- def test_mcast_flood_custom_port(self):
- """ Multicast flood test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan, self).test_mcast_flood()
-
- def test_mcast_rcv_custom_port(self):
- """ Multicast receive test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan, self).test_mcast_rcv()
-
- # Method to define VPP actions before tear down of the test case.
- # Overrides tearDown method in VppTestCase class.
- # @param self The object pointer.
-
- def tearDown(self):
- super(TestVxlan, self).tearDown()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 2 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
- self.logger.info(self.vapi.cli("show vxlan tunnel"))
-
-
-class TestVxlan2(VppTestCase):
- """ VXLAN Test Case """
- def setUp(self):
- super(TestVxlan2, self).setUp()
-
- # Create 2 pg interfaces.
- self.create_pg_interfaces(range(4))
- for pg in self.pg_interfaces:
- pg.admin_up()
-
- # Configure IPv4 addresses on VPP pg0.
- self.pg0.config_ip4()
- self.pg0.resolve_arp()
-
- def tearDown(self):
- super(TestVxlan2, self).tearDown()
-
- def test_xconnect(self):
- """ VXLAN source address not local """
-
- #
- # test the broken configuration of a VXLAN tunnel whose
- # source address is not local ot the box. packets sent
- # through the tunnel should be dropped
- #
- t = VppVxlanTunnel(self,
- src="10.0.0.5",
- dst=self.pg0.local_ip4,
- vni=1000)
- t.add_vpp_config()
- t.admin_up()
-
- self.vapi.sw_interface_set_l2_xconnect(t.sw_if_index,
- self.pg1.sw_if_index,
- enable=1)
- self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
- t.sw_if_index,
- enable=1)
-
- p = (Ether(src="00:11:22:33:44:55",
- dst="00:00:00:11:22:33") /
- IP(src="4.3.2.1", dst="1.2.3.4") /
- UDP(sport=20000, dport=10000) /
- Raw(b'\xa5' * 1450))
-
- rx = self.send_and_assert_no_replies(self.pg1, [p])
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/vxlan/test/test_vxlan6.py b/src/vnet/vxlan/test/test_vxlan6.py
deleted file mode 100644
index 123cce9b7ba..00000000000
--- a/src/vnet/vxlan/test/test_vxlan6.py
+++ /dev/null
@@ -1,316 +0,0 @@
-#!/usr/bin/env python3
-
-import socket
-import unittest
-from framework import VppTestCase, VppTestRunner
-from template_bd import BridgeDomain
-
-from scapy.layers.l2 import Ether
-from scapy.packet import Raw, bind_layers
-from scapy.layers.inet6 import IP, IPv6, UDP
-from scapy.layers.vxlan import VXLAN
-
-import util
-from vpp_ip_route import VppIpRoute, VppRoutePath
-from vpp_vxlan_tunnel import VppVxlanTunnel
-from vpp_ip import INVALID_INDEX
-
-
-class TestVxlan6(BridgeDomain, VppTestCase):
- """ VXLAN over IPv6 Test Case """
-
- def __init__(self, *args):
- BridgeDomain.__init__(self)
- VppTestCase.__init__(self, *args)
-
- def encapsulate(self, pkt, vni):
- """
- Encapsulate the original payload frame by adding VXLAN header with its
- UDP, IP and Ethernet fields
- """
- return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- @classmethod
- def ip_range(cls, s, e):
- """ range of remote ip's """
- tmp = cls.pg0.remote_ip6.rsplit(':', 1)[0]
- return ("%s:%x" % (tmp, i) for i in range(s, e))
-
- def encap_mcast(self, pkt, src_ip, src_mac, vni):
- """
- Encapsulate the original payload frame by adding VXLAN header with its
- UDP, IP and Ethernet fields
- """
- return (Ether(src=src_mac, dst=self.mcast_mac) /
- IPv6(src=src_ip, dst=self.mcast_ip6) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- def decapsulate(self, pkt):
- """
- Decapsulate the original payload frame by removing VXLAN header
- """
- # check if is set I flag
- self.assertEqual(pkt[VXLAN].flags, int('0x8', 16))
- return pkt[VXLAN].payload
-
- # Method for checking VXLAN encapsulation.
- #
- def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
- # TODO: add error messages
- # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
- # by VPP using ARP.
- self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
- else:
- self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
- # Verify VXLAN tunnel source IP is VPP_IP and destination IP is MY_IP.
- self.assertEqual(pkt[IPv6].src, self.pg0.local_ip6)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[IPv6].dst, self.pg0.remote_ip6)
- else:
- self.assertEqual(pkt[IPv6].dst, type(self).mcast_ip6)
- # Verify UDP destination port is VXLAN 4789, source UDP port could be
- # arbitrary.
- self.assertEqual(pkt[UDP].dport, self.dport)
- # Verify UDP checksum
- self.assert_udp_checksum_valid(pkt, ignore_zero_checksum=False)
- # Verify VNI
- self.assertEqual(pkt[VXLAN].vni, vni)
-
- @classmethod
- def create_vxlan_flood_test_bd(cls, vni, n_ucast_tunnels, port):
- # Create 10 ucast vxlan tunnels under bd
- start = 10
- end = start + n_ucast_tunnels
- for dest_ip6 in cls.ip_range(start, end):
- # add host route so dest ip will not be resolved
- rip = VppIpRoute(cls, dest_ip6, 128,
- [VppRoutePath(cls.pg0.remote_ip6, INVALID_INDEX)],
- register=False)
- rip.add_vpp_config()
- r = VppVxlanTunnel(cls, src=cls.pg0.local_ip6,
- src_port=port, dst_port=port,
- dst=dest_ip6, vni=vni)
- r.add_vpp_config()
- cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index, bd_id=vni)
-
- @classmethod
- def add_mcast_tunnels_load(cls):
- cls.add_del_mcast_tunnels_load(is_add=1)
-
- @classmethod
- def del_mcast_tunnels_load(cls):
- cls.add_del_mcast_tunnels_load(is_add=0)
-
- # Class method to start the VXLAN test case.
- # Overrides setUpClass method in VppTestCase class.
- # Python try..except statement is used to ensure that the tear down of
- # the class will be executed even if exception is raised.
- # @param cls The class pointer.
- @classmethod
- def setUpClass(cls):
- super(TestVxlan6, cls).setUpClass()
-
- try:
- cls.flags = 0x8
-
- # Create 2 pg interfaces.
- cls.create_pg_interfaces(range(4))
- for pg in cls.pg_interfaces:
- pg.admin_up()
-
- # Configure IPv6 addresses on VPP pg0.
- cls.pg0.config_ip6()
-
- # Resolve MAC address for VPP's IP address on pg0.
- cls.pg0.resolve_ndp()
-
- # Our Multicast address
- cls.mcast_ip6 = 'ff0e::1'
- cls.mcast_mac = util.mcast_ip_to_mac(cls.mcast_ip6)
- except Exception:
- super(TestVxlan6, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(TestVxlan6, cls).tearDownClass()
-
- def setUp(self):
- super(TestVxlan6, self).setUp()
-
- def createVxLANInterfaces(self, port=4789):
- # Create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg1
- # into BD.
- self.dport = port
-
- self.single_tunnel_vni = 0x12345
- self.single_tunnel_bd = 1
- r = VppVxlanTunnel(self, src=self.pg0.local_ip6,
- dst=self.pg0.remote_ip6,
- src_port=self.dport, dst_port=self.dport,
- vni=self.single_tunnel_vni)
- r.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=self.single_tunnel_bd)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg1.sw_if_index, bd_id=self.single_tunnel_bd)
-
- # Setup vni 2 to test multicast flooding
- self.n_ucast_tunnels = 10
- self.mcast_flood_bd = 2
- self.create_vxlan_flood_test_bd(self.mcast_flood_bd,
- self.n_ucast_tunnels,
- self.dport)
- r = VppVxlanTunnel(self, src=self.pg0.local_ip6, dst=self.mcast_ip6,
- src_port=self.dport, dst_port=self.dport,
- mcast_sw_if_index=1, vni=self.mcast_flood_bd)
- r.add_vpp_config()
- self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=self.mcast_flood_bd)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg2.sw_if_index, bd_id=self.mcast_flood_bd)
-
- # Setup vni 3 to test unicast flooding
- self.ucast_flood_bd = 3
- self.create_vxlan_flood_test_bd(self.ucast_flood_bd,
- self.n_ucast_tunnels,
- self.dport)
- self.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=self.pg3.sw_if_index, bd_id=self.ucast_flood_bd)
-
- # Set scapy listen custom port for VxLAN
- bind_layers(UDP, VXLAN, dport=self.dport)
-
- # Method to define VPP actions before tear down of the test case.
- # Overrides tearDown method in VppTestCase class.
- # @param self The object pointer.
- def tearDown(self):
- super(TestVxlan6, self).tearDown()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 2 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
- self.logger.info(self.vapi.cli("show vxlan tunnel"))
-
- def encap_fragmented_packet(self):
- frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
- IP(src='4.3.2.1', dst='1.2.3.4') /
- UDP(sport=20000, dport=10000) /
- Raw(b'\xa5' * 1000))
-
- frags = util.fragment_rfc791(frame, 400)
-
- self.pg1.add_stream(frags)
-
- self.pg0.enable_capture()
-
- self.pg_start()
-
- out = self.pg0.get_capture(3)
-
- payload = []
- for pkt in out:
- payload.append(self.decapsulate(pkt))
- self.check_encapsulation(pkt, self.single_tunnel_vni)
-
- reassembled = util.reassemble4(payload)
-
- self.assertEqual(Ether(raw(frame))[IP], reassembled[IP])
-
- """
- Tests with default port (4789)
- """
- def test_decap(self):
- """ Decapsulation test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan6, self).test_decap()
-
- def test_encap(self):
- """ Encapsulation test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan6, self).test_encap()
-
- def test_encap_fragmented_packet(self):
- """ Encapsulation test send fragments from pg1
- Verify receipt of encapsulated frames on pg0
- """
- self.createVxLANInterfaces()
- self.encap_fragmented_packet()
-
- def test_ucast_flood(self):
- """ Unicast flood test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan6, self).test_ucast_flood()
-
- def test_mcast_flood(self):
- """ Multicast flood test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan6, self).test_mcast_flood()
-
- def test_mcast_rcv(self):
- """ Multicast receive test
- from BridgeDoman
- """
- self.createVxLANInterfaces()
- super(TestVxlan6, self).test_mcast_rcv()
-
- """
- Tests with custom port
- """
- def test_decap_custom_port(self):
- """ Decapsulation test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan6, self).test_decap()
-
- def test_encap_custom_port(self):
- """ Encapsulation test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan6, self).test_encap()
-
- def test_ucast_flood_custom_port(self):
- """ Unicast flood test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan6, self).test_ucast_flood()
-
- def test_mcast_flood_custom_port(self):
- """ Multicast flood test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan6, self).test_mcast_flood()
-
- def test_mcast_rcv_custom_port(self):
- """ Multicast receive test custom port
- from BridgeDoman
- """
- self.createVxLANInterfaces(1111)
- super(TestVxlan6, self).test_mcast_rcv()
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/vxlan/test/test_vxlan_gbp.py b/src/vnet/vxlan/test/test_vxlan_gbp.py
deleted file mode 100644
index f332aced7d8..00000000000
--- a/src/vnet/vxlan/test/test_vxlan_gbp.py
+++ /dev/null
@@ -1,293 +0,0 @@
-#!/usr/bin/env python3
-
-import socket
-from util import ip4_range, reassemble4_ether
-import unittest
-from framework import VppTestCase, VppTestRunner
-from template_bd import BridgeDomain
-
-from scapy.layers.l2 import Ether
-from scapy.packet import Raw
-from scapy.layers.inet import IP, UDP
-from scapy.layers.vxlan import VXLAN
-
-from vpp_ip_route import VppIpRoute, VppRoutePath
-from vpp_ip import INVALID_INDEX
-
-
-class TestVxlanGbp(VppTestCase):
- """ VXLAN GBP Test Case """
-
- @property
- def frame_request(self):
- """ Ethernet frame modeling a generic request """
- return (Ether(src='00:00:00:00:00:01', dst='00:00:00:00:00:02') /
- IP(src='1.2.3.4', dst='4.3.2.1') /
- UDP(sport=10000, dport=20000) /
- Raw(b'\xa5' * 100))
-
- @property
- def frame_reply(self):
- """ Ethernet frame modeling a generic reply """
- return (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
- IP(src='4.3.2.1', dst='1.2.3.4') /
- UDP(sport=20000, dport=10000) /
- Raw(b'\xa5' * 100))
-
- def encapsulate(self, pkt, vni):
- """
- Encapsulate the original payload frame by adding VXLAN GBP header with
- its UDP, IP and Ethernet fields
- """
- return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags, gpflags=self.gpflags,
- gpid=self.sclass) / pkt)
-
- def ip_range(self, start, end):
- """ range of remote ip's """
- return ip4_range(self.pg0.remote_ip4, start, end)
-
- def decapsulate(self, pkt):
- """
- Decapsulate the original payload frame by removing VXLAN header
- """
- # check if is set G and I flag
- self.assertEqual(pkt[VXLAN].flags, int('0x88', 16))
- return pkt[VXLAN].payload
-
- # Method for checking VXLAN GBP encapsulation.
- #
- def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
- # TODO: add error messages
- # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
- # by VPP using ARP.
- self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
- else:
- self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
- # Verify VXLAN GBP tunnel source IP is VPP_IP and destination IP is
- # MY_IP.
- self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
- else:
- self.assertEqual(pkt[IP].dst, type(self).mcast_ip4)
- # Verify UDP destination port is VXLAN GBP 48879, source UDP port could
- # be arbitrary.
- self.assertEqual(pkt[UDP].dport, type(self).dport)
- # Verify UDP checksum
- self.assert_udp_checksum_valid(pkt)
- # Verify VNI
- # pkt.show()
- self.assertEqual(pkt[VXLAN].vni, vni)
- # Verify Source Class
- self.assertEqual(pkt[VXLAN].gpid, 0)
-
- @classmethod
- def create_vxlan_gbp_flood_test_bd(cls, vni, n_ucast_tunnels):
- # Create 2 ucast vxlan tunnels under bd
- ip_range_start = 10
- ip_range_end = ip_range_start + n_ucast_tunnels
- next_hop_address = cls.pg0.remote_ip4
- for dest_ip4 in ip4_range(cls.pg0.remote_ip4,
- ip_range_start,
- ip_range_end):
- # add host route so dest_ip4 will not be resolved
- rip = VppIpRoute(cls, dest_ip4, 32,
- [VppRoutePath(next_hop_address,
- INVALID_INDEX)],
- register=False)
- rip.add_vpp_config()
- r = cls.vapi.vxlan_gbp_tunnel_add_del(
- tunnel={
- 'src': cls.pg0.local_ip4,
- 'dst': dest_ip4,
- 'vni': vni,
- 'instance': INVALID_INDEX,
- 'mcast_sw_if_index': INVALID_INDEX,
- 'mode': 1,
- },
- is_add=1
- )
- cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=vni)
-
- # Class method to start the VXLAN GBP test case.
- # Overrides setUpClass method in VppTestCase class.
- # Python try..except statement is used to ensure that the tear down of
- # the class will be executed even if exception is raised.
- # @param cls The class pointer.
- @classmethod
- def setUpClass(cls):
- super(TestVxlanGbp, cls).setUpClass()
-
- try:
- cls.dport = 48879
- cls.flags = 0x88
- cls.gpflags = 0x0
- cls.sclass = 0
-
- # Create 2 pg interfaces.
- cls.create_pg_interfaces(range(4))
- for pg in cls.pg_interfaces:
- pg.admin_up()
-
- # Configure IPv4 addresses on VPP pg0.
- cls.pg0.config_ip4()
-
- # Resolve MAC address for VPP's IP address on pg0.
- cls.pg0.resolve_arp()
-
- # Create VXLAN GBP VTEP on VPP pg0, and put vxlan_gbp_tunnel0 and
- # pg1 into BD.
- cls.single_tunnel_bd = 1
- cls.single_tunnel_vni = 0xabcde
- r = cls.vapi.vxlan_gbp_tunnel_add_del(
- tunnel={
- 'src': cls.pg0.local_ip4,
- 'dst': cls.pg0.remote_ip4,
- 'vni': cls.single_tunnel_vni,
- 'instance': INVALID_INDEX,
- 'mcast_sw_if_index': INVALID_INDEX,
- 'mode': 1,
- },
- is_add=1
- )
- cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=cls.single_tunnel_bd)
- cls.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=cls.pg1.sw_if_index,
- bd_id=cls.single_tunnel_bd)
-
- # Setup vni 2 to test multicast flooding
- cls.n_ucast_tunnels = 2
- # Setup vni 3 to test unicast flooding
- cls.ucast_flood_bd = 3
- cls.create_vxlan_gbp_flood_test_bd(cls.ucast_flood_bd,
- cls.n_ucast_tunnels)
- cls.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=cls.pg3.sw_if_index,
- bd_id=cls.ucast_flood_bd)
- except Exception:
- super(TestVxlanGbp, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(TestVxlanGbp, cls).tearDownClass()
-
- def assert_eq_pkts(self, pkt1, pkt2):
- """ Verify the Ether, IP, UDP, payload are equal in both
- packets
- """
- self.assertEqual(pkt1[Ether].src, pkt2[Ether].src)
- self.assertEqual(pkt1[Ether].dst, pkt2[Ether].dst)
- self.assertEqual(pkt1[IP].src, pkt2[IP].src)
- self.assertEqual(pkt1[IP].dst, pkt2[IP].dst)
- self.assertEqual(pkt1[UDP].sport, pkt2[UDP].sport)
- self.assertEqual(pkt1[UDP].dport, pkt2[UDP].dport)
- self.assertEqual(pkt1[Raw], pkt2[Raw])
-
- def test_decap(self):
- """ Decapsulation test
- Send encapsulated frames from pg0
- Verify receipt of decapsulated frames on pg1
- """
- encapsulated_pkt = self.encapsulate(self.frame_request,
- self.single_tunnel_vni)
-
- self.pg0.add_stream([encapsulated_pkt, ])
-
- self.pg1.enable_capture()
-
- self.pg_start()
-
- # Pick first received frame and check if it's the non-encapsulated
- # frame
- out = self.pg1.get_capture(1)
- pkt = out[0]
- self.assert_eq_pkts(pkt, self.frame_request)
-
- def test_encap(self):
- """ Encapsulation test
- Send frames from pg1
- Verify receipt of encapsulated frames on pg0
- """
- self.pg1.add_stream([self.frame_reply])
-
- self.pg0.enable_capture()
-
- self.pg_start()
-
- # Pick first received frame and check if it's correctly encapsulated.
- out = self.pg0.get_capture(1)
- pkt = out[0]
- self.check_encapsulation(pkt, self.single_tunnel_vni)
-
- payload = self.decapsulate(pkt)
- self.assert_eq_pkts(payload, self.frame_reply)
-
- def test_ucast_flood(self):
- """ Unicast flood test
- Send frames from pg3
- Verify receipt of encapsulated frames on pg0
- """
- self.pg3.add_stream([self.frame_reply])
-
- self.pg0.enable_capture()
-
- self.pg_start()
-
- # Get packet from each tunnel and assert it's correctly encapsulated.
- out = self.pg0.get_capture(self.n_ucast_tunnels)
- for pkt in out:
- self.check_encapsulation(pkt, self.ucast_flood_bd, True)
- payload = self.decapsulate(pkt)
- self.assert_eq_pkts(payload, self.frame_reply)
-
- def test_encap_big_packet(self):
- """ Encapsulation test send big frame from pg1
- Verify receipt of encapsulated frames on pg0
- """
-
- self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])
-
- frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
- IP(src='4.3.2.1', dst='1.2.3.4') /
- UDP(sport=20000, dport=10000) /
- Raw(b'\xa5' * 1450))
-
- self.pg1.add_stream([frame])
-
- self.pg0.enable_capture()
-
- self.pg_start()
-
- # Pick first received frame and check if it's correctly encapsulated.
- out = self.pg0.get_capture(2)
- pkt = reassemble4_ether(out)
- self.check_encapsulation(pkt, self.single_tunnel_vni)
-
- payload = self.decapsulate(pkt)
- self.assert_eq_pkts(payload, frame)
-
-# Method to define VPP actions before tear down of the test case.
-# Overrides tearDown method in VppTestCase class.
-# @param self The object pointer.
- def tearDown(self):
- super(TestVxlanGbp, self).tearDown()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
- self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
- self.logger.info(self.vapi.cli("show error"))
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/vxlan/test/test_vxlan_gpe.py b/src/vnet/vxlan/test/test_vxlan_gpe.py
deleted file mode 100644
index c5d6bf07f7c..00000000000
--- a/src/vnet/vxlan/test/test_vxlan_gpe.py
+++ /dev/null
@@ -1,265 +0,0 @@
-#!/usr/bin/env python3
-
-import socket
-from util import ip4_range
-import unittest
-from framework import VppTestCase, VppTestRunner, running_extended_tests
-from template_bd import BridgeDomain
-
-from scapy.layers.l2 import Ether
-from scapy.packet import Raw
-from scapy.layers.inet import IP, UDP
-from scapy.layers.vxlan import VXLAN
-
-import util
-from vpp_ip_route import VppIpRoute, VppRoutePath
-
-from vpp_ip import INVALID_INDEX
-
-
-@unittest.skipUnless(running_extended_tests, "part of extended tests")
-class TestVxlanGpe(BridgeDomain, VppTestCase):
- """ VXLAN-GPE Test Case """
-
- def __init__(self, *args):
- BridgeDomain.__init__(self)
- VppTestCase.__init__(self, *args)
-
- def encapsulate(self, pkt, vni):
- """
- Encapsulate the original payload frame by adding VXLAN-GPE header
- with its UDP, IP and Ethernet fields
- """
- return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
- IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- def ip_range(self, start, end):
- """ range of remote ip's """
- return ip4_range(self.pg0.remote_ip4, start, end)
-
- def encap_mcast(self, pkt, src_ip, src_mac, vni):
- """
- Encapsulate the original payload frame by adding VXLAN-GPE header
- with its UDP, IP and Ethernet fields
- """
- return (Ether(src=src_mac, dst=self.mcast_mac) /
- IP(src=src_ip, dst=self.mcast_ip4) /
- UDP(sport=self.dport, dport=self.dport, chksum=0) /
- VXLAN(vni=vni, flags=self.flags) /
- pkt)
-
- def decapsulate(self, pkt):
- """
- Decapsulate the original payload frame by removing VXLAN-GPE header
- """
- # check if is set I and P flag
- self.assertEqual(pkt[VXLAN].flags, 0x0c)
- return pkt[VXLAN].payload
-
- # Method for checking VXLAN-GPE encapsulation.
- #
- def check_encapsulation(self, pkt, vni, local_only=False, mcast_pkt=False):
- # Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
- # by VPP using ARP.
- self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
- else:
- self.assertEqual(pkt[Ether].dst, type(self).mcast_mac)
- # Verify VXLAN-GPE tunnel src IP is VPP_IP and dst IP is MY_IP.
- self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
- if not local_only:
- if not mcast_pkt:
- self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
- else:
- self.assertEqual(pkt[IP].dst, type(self).mcast_ip4)
- # Verify UDP destination port is VXLAN-GPE 4790, source UDP port
- # could be arbitrary.
- self.assertEqual(pkt[UDP].dport, type(self).dport)
- # Verify UDP checksum
- self.assert_udp_checksum_valid(pkt)
- # Verify VNI
- self.assertEqual(pkt[VXLAN].vni, vni)
-
- @classmethod
- def create_vxlan_gpe_flood_test_bd(cls, vni, n_ucast_tunnels):
- # Create 10 ucast vxlan tunnels under bd
- ip_range_start = 10
- ip_range_end = ip_range_start + n_ucast_tunnels
- next_hop_address = cls.pg0.remote_ip4
- for dest_ip4 in ip4_range(next_hop_address, ip_range_start,
- ip_range_end):
- # add host route so dest_ip4n will not be resolved
- rip = VppIpRoute(cls, dest_ip4, 32,
- [VppRoutePath(next_hop_address,
- INVALID_INDEX)],
- register=False)
- rip.add_vpp_config()
-
- r = cls.vapi.vxlan_gpe_add_del_tunnel(
- src_addr=cls.pg0.local_ip4,
- dst_addr=dest_ip4,
- vni=vni)
- cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=vni)
-
- @classmethod
- def add_del_shared_mcast_dst_load(cls, is_add):
- """
- add or del tunnels sharing the same mcast dst
- to test vxlan_gpe ref_count mechanism
- """
- n_shared_dst_tunnels = 20
- vni_start = 1000
- vni_end = vni_start + n_shared_dst_tunnels
- for vni in range(vni_start, vni_end):
- r = cls.vapi.vxlan_gpe_add_del_tunnel(
- local=cls.pg0.local_ip4,
- remote=cls.mcast_ip4,
- mcast_sw_if_index=1,
- vni=vni,
- is_add=is_add)
- if r.sw_if_index == 0xffffffff:
- raise ValueError("bad sw_if_index: ~0")
-
- @classmethod
- def add_shared_mcast_dst_load(cls):
- cls.add_del_shared_mcast_dst_load(is_add=1)
-
- @classmethod
- def del_shared_mcast_dst_load(cls):
- cls.add_del_shared_mcast_dst_load(is_add=0)
-
- @classmethod
- def add_del_mcast_tunnels_load(cls, is_add):
- """
- add or del tunnels to test vxlan_gpe stability
- """
- n_distinct_dst_tunnels = 20
- ip_range_start = 10
- ip_range_end = ip_range_start + n_distinct_dst_tunnels
- for dest_ip4 in ip4_range(cls.mcast_ip4, ip_range_start,
- ip_range_end):
- vni = int(dest_ip4.split(".")[3])
- cls.vapi.vxlan_gpe_add_del_tunnel(
- src_addr=cls.pg0.local_ip4,
- dst_addr=dest_ip4,
- mcast_sw_if_index=1,
- vni=vni,
- is_add=is_add)
-
- @classmethod
- def add_mcast_tunnels_load(cls):
- cls.add_del_mcast_tunnels_load(is_add=1)
-
- @classmethod
- def del_mcast_tunnels_load(cls):
- cls.add_del_mcast_tunnels_load(is_add=0)
-
- # Class method to start the VXLAN-GPE test case.
- # Overrides setUpClass method in VppTestCase class.
- # Python try..except statement is used to ensure that the tear down of
- # the class will be executed even if exception is raised.
- # @param cls The class pointer.
- @classmethod
- def setUpClass(cls):
- super(TestVxlanGpe, cls).setUpClass()
-
- try:
- cls.dport = 4790
- cls.flags = 0x0c
-
- # Create 2 pg interfaces.
- cls.create_pg_interfaces(range(4))
- for pg in cls.pg_interfaces:
- pg.admin_up()
-
- # Configure IPv4 addresses on VPP pg0.
- cls.pg0.config_ip4()
-
- # Resolve MAC address for VPP's IP address on pg0.
- cls.pg0.resolve_arp()
-
- # Our Multicast address
- cls.mcast_ip4 = '239.1.1.1'
- cls.mcast_mac = util.mcast_ip_to_mac(cls.mcast_ip4)
-
- # Create VXLAN-GPE VTEP on VPP pg0, and put vxlan_gpe_tunnel0
- # and pg1 into BD.
- cls.single_tunnel_vni = 0xabcde
- cls.single_tunnel_bd = 11
- r = cls.vapi.vxlan_gpe_add_del_tunnel(
- src_addr=cls.pg0.local_ip4,
- dst_addr=cls.pg0.remote_ip4,
- vni=cls.single_tunnel_vni)
- cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=cls.single_tunnel_bd)
- cls.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=cls.pg1.sw_if_index, bd_id=cls.single_tunnel_bd)
-
- # Setup vni 2 to test multicast flooding
- cls.n_ucast_tunnels = 10
- cls.mcast_flood_bd = 12
- cls.create_vxlan_gpe_flood_test_bd(cls.mcast_flood_bd,
- cls.n_ucast_tunnels)
- r = cls.vapi.vxlan_gpe_add_del_tunnel(
- src_addr=cls.pg0.local_ip4,
- dst_addr=cls.mcast_ip4,
- mcast_sw_if_index=1,
- vni=cls.mcast_flood_bd)
- cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index,
- bd_id=cls.mcast_flood_bd)
- cls.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=cls.pg2.sw_if_index, bd_id=cls.mcast_flood_bd)
-
- # Add and delete mcast tunnels to check stability
- cls.add_shared_mcast_dst_load()
- cls.add_mcast_tunnels_load()
- cls.del_shared_mcast_dst_load()
- cls.del_mcast_tunnels_load()
-
- # Setup vni 3 to test unicast flooding
- cls.ucast_flood_bd = 13
- cls.create_vxlan_gpe_flood_test_bd(cls.ucast_flood_bd,
- cls.n_ucast_tunnels)
- cls.vapi.sw_interface_set_l2_bridge(
- rx_sw_if_index=cls.pg3.sw_if_index, bd_id=cls.ucast_flood_bd)
- except Exception:
- super(TestVxlanGpe, cls).tearDownClass()
- raise
-
- @classmethod
- def tearDownClass(cls):
- super(TestVxlanGpe, cls).tearDownClass()
-
- @unittest.skip("test disabled for vxlan-gpe")
- def test_mcast_flood(self):
- """ inherited from BridgeDomain """
- pass
-
- @unittest.skip("test disabled for vxlan-gpe")
- def test_mcast_rcv(self):
- """ inherited from BridgeDomain """
- pass
-
- # Method to define VPP actions before tear down of the test case.
- # Overrides tearDown method in VppTestCase class.
- # @param self The object pointer.
- def tearDown(self):
- super(TestVxlanGpe, self).tearDown()
-
- def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show bridge-domain 11 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 12 detail"))
- self.logger.info(self.vapi.cli("show bridge-domain 13 detail"))
- self.logger.info(self.vapi.cli("show int"))
- self.logger.info(self.vapi.cli("show vxlan-gpe"))
- self.logger.info(self.vapi.cli("show trace"))
-
-
-if __name__ == '__main__':
- unittest.main(testRunner=VppTestRunner)
diff --git a/src/vnet/vxlan/test/vpp_vxlan_gbp_tunnel.py b/src/vnet/vxlan/test/vpp_vxlan_gbp_tunnel.py
deleted file mode 100644
index 0898bd9f810..00000000000
--- a/src/vnet/vxlan/test/vpp_vxlan_gbp_tunnel.py
+++ /dev/null
@@ -1,75 +0,0 @@
-
-from vpp_interface import VppInterface
-from vpp_papi import VppEnum
-
-
-INDEX_INVALID = 0xffffffff
-
-
-def find_vxlan_gbp_tunnel(test, src, dst, vni):
- ts = test.vapi.vxlan_gbp_tunnel_dump(INDEX_INVALID)
- for t in ts:
- if src == str(t.tunnel.src) and \
- dst == str(t.tunnel.dst) and \
- t.tunnel.vni == vni:
- return t.tunnel.sw_if_index
- return INDEX_INVALID
-
-
-class VppVxlanGbpTunnel(VppInterface):
- """
- VPP VXLAN GBP interface
- """
-
- def __init__(self, test, src, dst, vni, mcast_itf=None, mode=None,
- is_ipv6=None, encap_table_id=None, instance=0xffffffff):
- """ Create VXLAN-GBP Tunnel interface """
- super(VppVxlanGbpTunnel, self).__init__(test)
- self.src = src
- self.dst = dst
- self.vni = vni
- self.mcast_itf = mcast_itf
- self.ipv6 = is_ipv6
- self.encap_table_id = encap_table_id
- self.instance = instance
- if not mode:
- self.mode = (VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
- VXLAN_GBP_API_TUNNEL_MODE_L2)
- else:
- self.mode = mode
-
- def encode(self):
- return {
- 'src': self.src,
- 'dst': self.dst,
- 'mode': self.mode,
- 'vni': self.vni,
- 'mcast_sw_if_index': self.mcast_itf.sw_if_index
- if self.mcast_itf else INDEX_INVALID,
- 'encap_table_id': self.encap_table_id,
- 'instance': self.instance,
- }
-
- def add_vpp_config(self):
- reply = self.test.vapi.vxlan_gbp_tunnel_add_del(
- is_add=1,
- tunnel=self.encode(),
- )
- self.set_sw_if_index(reply.sw_if_index)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self.test.vapi.vxlan_gbp_tunnel_add_del(
- is_add=0,
- tunnel=self.encode(),
- )
-
- def query_vpp_config(self):
- return (INDEX_INVALID != find_vxlan_gbp_tunnel(self._test,
- self.src,
- self.dst,
- self.vni))
-
- def object_id(self):
- return "vxlan-gbp-%d-%d-%s-%s" % (self.sw_if_index, self.vni,
- self.src, self.dst)
diff --git a/src/vnet/vxlan/test/vpp_vxlan_tunnel.py b/src/vnet/vxlan/test/vpp_vxlan_tunnel.py
deleted file mode 100644
index d7e087da6f8..00000000000
--- a/src/vnet/vxlan/test/vpp_vxlan_tunnel.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from vpp_interface import VppInterface
-from vpp_papi import VppEnum
-
-
-INDEX_INVALID = 0xffffffff
-DEFAULT_PORT = 4789
-UNDEFINED_PORT = 0
-
-
-def find_vxlan_tunnel(test, src, dst, s_port, d_port, vni):
- ts = test.vapi.vxlan_tunnel_v2_dump(INDEX_INVALID)
-
- src_port = DEFAULT_PORT
- if s_port != UNDEFINED_PORT:
- src_port = s_port
-
- dst_port = DEFAULT_PORT
- if d_port != UNDEFINED_PORT:
- dst_port = d_port
-
- for t in ts:
- if src == str(t.src_address) and \
- dst == str(t.dst_address) and \
- src_port == t.src_port and \
- dst_port == t.dst_port and \
- t.vni == vni:
- return t.sw_if_index
- return INDEX_INVALID
-
-
-class VppVxlanTunnel(VppInterface):
- """
- VPP VXLAN interface
- """
-
- def __init__(self, test, src, dst, vni,
- src_port=UNDEFINED_PORT, dst_port=UNDEFINED_PORT,
- mcast_itf=None,
- mcast_sw_if_index=INDEX_INVALID,
- decap_next_index=INDEX_INVALID,
- encap_vrf_id=None, instance=0xffffffff, is_l3=False):
- """ Create VXLAN Tunnel interface """
- super(VppVxlanTunnel, self).__init__(test)
- self.src = src
- self.dst = dst
- self.vni = vni
- self.src_port = src_port
- self.dst_port = dst_port
- self.mcast_itf = mcast_itf
- self.mcast_sw_if_index = mcast_sw_if_index
- self.encap_vrf_id = encap_vrf_id
- self.decap_next_index = decap_next_index
- self.instance = instance
- self.is_l3 = is_l3
-
- if (self.mcast_itf):
- self.mcast_sw_if_index = self.mcast_itf.sw_if_index
-
- def add_vpp_config(self):
- reply = self.test.vapi.vxlan_add_del_tunnel_v3(
- is_add=1, src_address=self.src, dst_address=self.dst, vni=self.vni,
- src_port=self.src_port, dst_port=self.dst_port,
- mcast_sw_if_index=self.mcast_sw_if_index,
- encap_vrf_id=self.encap_vrf_id, is_l3=self.is_l3,
- instance=self.instance, decap_next_index=self.decap_next_index)
- self.set_sw_if_index(reply.sw_if_index)
- self._test.registry.register(self, self._test.logger)
-
- def remove_vpp_config(self):
- self.test.vapi.vxlan_add_del_tunnel_v2(
- is_add=0, src_address=self.src, dst_address=self.dst, vni=self.vni,
- src_port=self.src_port, dst_port=self.dst_port,
- mcast_sw_if_index=self.mcast_sw_if_index,
- encap_vrf_id=self.encap_vrf_id, instance=self.instance,
- decap_next_index=self.decap_next_index)
-
- def query_vpp_config(self):
- return (INDEX_INVALID != find_vxlan_tunnel(self._test,
- self.src,
- self.dst,
- self.src_port,
- self.dst_port,
- self.vni))
-
- def object_id(self):
- return "vxlan-%d-%d-%s-%s" % (self.sw_if_index, self.vni,
- self.src, self.dst)