summaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gbp')
-rw-r--r--src/plugins/gbp/gbp.api4
-rw-r--r--src/plugins/gbp/test/test_gbp.py290
2 files changed, 184 insertions, 110 deletions
diff --git a/src/plugins/gbp/gbp.api b/src/plugins/gbp/gbp.api
index 2f46634af52..525e70536bd 100644
--- a/src/plugins/gbp/gbp.api
+++ b/src/plugins/gbp/gbp.api
@@ -262,8 +262,8 @@ enum gbp_subnet_type
typedef gbp_subnet
{
u32 rd_id;
- vl_api_interface_index_t sw_if_index;
- u16 sclass;
+ vl_api_interface_index_t sw_if_index [default= 0xffffffff];
+ u16 sclass [default=0xffffffff];
vl_api_gbp_subnet_type_t type;
vl_api_prefix_t prefix;
};
diff --git a/src/plugins/gbp/test/test_gbp.py b/src/plugins/gbp/test/test_gbp.py
index 342e5de6c45..21d0770cf66 100644
--- a/src/plugins/gbp/test/test_gbp.py
+++ b/src/plugins/gbp/test/test_gbp.py
@@ -1,27 +1,45 @@
#!/usr/bin/env python3
-
-from socket import AF_INET, AF_INET6, inet_pton, inet_ntop
+import typing
+from socket import AF_INET6, inet_pton, inet_ntop
import unittest
from ipaddress import ip_address, IPv4Network, IPv6Network
from scapy.packet import Raw
from scapy.layers.l2 import Ether, ARP, Dot1Q
from scapy.layers.inet import IP, UDP, ICMP
-from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
- ICMPv6ND_NA, ICMPv6EchoRequest
+from scapy.layers.inet6 import (
+ IPv6,
+ ICMPv6ND_NS,
+ ICMPv6NDOptSrcLLAddr,
+ ICMPv6ND_NA,
+ ICMPv6EchoRequest,
+)
from scapy.utils6 import in6_getnsma, in6_getnsmac
from scapy.layers.vxlan import VXLAN
-from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
+from scapy.data import ETH_P_IP, ETH_P_IPV6
from framework import tag_fixme_vpp_workers
from framework import VppTestCase, VppTestRunner
from vpp_object import VppObject
from vpp_interface import VppInterface
-from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \
- VppIpInterfaceAddress, VppIpInterfaceBind, find_route, FibPathProto, \
- FibPathType
-from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
- VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr
+from vpp_ip_route import (
+ VppIpRoute,
+ VppRoutePath,
+ VppIpTable,
+ VppIpInterfaceAddress,
+ VppIpInterfaceBind,
+ find_route,
+ FibPathProto,
+ FibPathType,
+)
+from vpp_l2 import (
+ VppBridgeDomain,
+ VppBridgeDomainPort,
+ VppBridgeDomainArpEntry,
+ VppL2FibEntry,
+ find_bridge_domain_port,
+ VppL2Vtr,
+)
from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
from vpp_ip import DpoProto, get_dpo_proto
from vpp_papi import VppEnum, MACAddress
@@ -29,10 +47,6 @@ from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \
VppVxlanGbpTunnel
from vpp_neighbor import VppNeighbor
from vpp_acl import AclRule, VppAcl
-try:
- text_type = unicode
-except NameError:
- text_type = str
NUM_PKTS = 67
@@ -73,7 +87,7 @@ def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None,
return False
-def find_gbp_vxlan(test, vni):
+def find_gbp_vxlan(test: VppTestCase, vni):
ts = test.vapi.gbp_vxlan_tunnel_dump()
for t in ts:
if t.tunnel.vni == vni:
@@ -121,6 +135,7 @@ class VppGbpEndpoint(VppObject):
mac=True):
self._test = test
self.itf = itf
+ self.handle = None
self.epg = epg
self.recirc = recirc
@@ -138,20 +153,30 @@ class VppGbpEndpoint(VppObject):
self.tun_src = tun_src
self.tun_dst = tun_dst
+ def encode(self):
+ ips = [self.ip4, self.ip6]
+ return {
+ "sw_if_index": self.itf.sw_if_index,
+ "ips": ips,
+ "n_ips": len(ips),
+ "mac": self.vmac.packed,
+ "sclass": self.epg.sclass,
+ "flags": self.flags,
+ "tun": {
+ "src": self.tun_src,
+ "dst": self.tun_dst,
+ },
+ }
+
def add_vpp_config(self):
res = self._test.vapi.gbp_endpoint_add(
- self.itf.sw_if_index,
- [self.ip4, self.ip6],
- self.vmac.packed,
- self.epg.sclass,
- self.flags,
- self.tun_src,
- self.tun_dst)
+ endpoint=self.encode(),
+ )
self.handle = res.handle
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
- self._test.vapi.gbp_endpoint_del(self.handle)
+ self._test.vapi.gbp_endpoint_del(handle=self.handle)
def object_id(self):
return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
@@ -176,20 +201,25 @@ class VppGbpRecirc(VppObject):
self.epg = epg
self.is_ext = is_ext
+ def encode(self):
+ return {
+ "is_ext": self.is_ext,
+ "sw_if_index": self.recirc.sw_if_index,
+ "sclass": self.epg.sclass,
+ }
+
def add_vpp_config(self):
self._test.vapi.gbp_recirc_add_del(
1,
- self.recirc.sw_if_index,
- self.epg.sclass,
- self.is_ext)
+ recirc=self.encode(),
+ )
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
self._test.vapi.gbp_recirc_add_del(
0,
- self.recirc.sw_if_index,
- self.epg.sclass,
- self.is_ext)
+ recirc=self.encode(),
+ )
def object_id(self):
return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
@@ -214,14 +244,26 @@ class VppGbpExtItf(VppObject):
self.rd = rd
self.flags = 1 if anon else 0
+ def encode(self):
+ return {
+ "sw_if_index": self.itf.sw_if_index,
+ "bd_id": self.bd.bd_id,
+ "rd_id": self.rd.rd_id,
+ "flags": self.flags,
+ }
+
def add_vpp_config(self):
self._test.vapi.gbp_ext_itf_add_del(
- 1, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
+ 1,
+ ext_itf=self.encode(),
+ )
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
self._test.vapi.gbp_ext_itf_add_del(
- 0, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
+ 0,
+ ext_itf=self.encode(),
+ )
def object_id(self):
return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index,
@@ -241,7 +283,9 @@ class VppGbpSubnet(VppObject):
"""
def __init__(self, test, rd, address, address_len,
- type, sw_if_index=None, sclass=None):
+ type, sw_if_index=0xffffffff, sclass=0xffff):
+ # TODO: replace hardcoded defaults when vpp_papi supports
+ # defaults in typedefs
self._test = test
self.rd_id = rd.rd_id
a = ip_address(address)
@@ -255,22 +299,27 @@ class VppGbpSubnet(VppObject):
self.sw_if_index = sw_if_index
self.sclass = sclass
+ def encode(self):
+ return {
+ "type": self.type,
+ "sw_if_index": self.sw_if_index,
+ "sclass": self.sclass,
+ "prefix": self.prefix,
+ "rd_id": self.rd_id,
+ }
+
def add_vpp_config(self):
self._test.vapi.gbp_subnet_add_del(
- 1,
- self.rd_id,
- self.prefix,
- self.type,
- sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
- sclass=self.sclass if self.sclass else 0xffff)
+ is_add=1,
+ subnet=self.encode(),
+ )
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
self._test.vapi.gbp_subnet_add_del(
- 0,
- self.rd_id,
- self.prefix,
- self.type)
+ is_add=0,
+ subnet=self.encode()
+ )
def object_id(self):
return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
@@ -307,30 +356,35 @@ class VppGbpEndpointGroup(VppObject):
self.bvi_ip4 = bvi_ip4
self.bvi_ip6 = bvi_ip6
self.vnid = vnid
- self.bd = bd
+ self.bd = bd # VppGbpBridgeDomain
self.rd = rd
self.sclass = sclass
if 0 == self.sclass:
self.sclass = 0xffff
self.retention = retention
+ def encode(self) -> dict:
+ return {
+ "uplink_sw_if_index": self.uplink.sw_if_index
+ if self.uplink else INDEX_INVALID,
+ "bd_id": self.bd.bd.bd_id,
+ "rd_id": self.rd.rd_id,
+ "vnid": self.vnid,
+ "sclass": self.sclass,
+ "retention": self.retention.encode(),
+ }
+
def add_vpp_config(self):
- self._test.vapi.gbp_endpoint_group_add(
- self.vnid,
- self.sclass,
- self.bd.bd.bd_id,
- self.rd.rd_id,
- self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
- self.retention.encode())
+ self._test.vapi.gbp_endpoint_group_add(epg=self.encode())
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
- self._test.vapi.gbp_endpoint_group_del(self.sclass)
+ self._test.vapi.gbp_endpoint_group_del(sclass=self.sclass)
- def object_id(self):
+ def object_id(self) -> str:
return "gbp-endpoint-group:[%d]" % (self.vnid)
- def query_vpp_config(self):
+ def query_vpp_config(self) -> bool:
epgs = self._test.vapi.gbp_endpoint_group_dump()
for epg in epgs:
if epg.epg.vnid == self.vnid:
@@ -343,7 +397,8 @@ class VppGbpBridgeDomain(VppObject):
GBP Bridge Domain
"""
- def __init__(self, test, bd, rd, bvi, uu_fwd=None,
+ def __init__(self, test, bd, rd, bvi,
+ uu_fwd: typing.Optional[VppVxlanGbpTunnel] = None,
bm_flood=None, learn=True,
uu_drop=False, bm_drop=False,
ucast_arp=False):
@@ -366,23 +421,31 @@ class VppGbpBridgeDomain(VppObject):
if ucast_arp:
self.flags |= e.GBP_BD_API_FLAG_UCAST_ARP
+ def encode(self) -> dict:
+ return {
+ "flags": self.flags,
+ "bvi_sw_if_index": self.bvi.sw_if_index,
+ "uu_fwd_sw_if_index": self.uu_fwd.sw_if_index
+ if self.uu_fwd else INDEX_INVALID,
+ "bm_flood_sw_if_index": self.bm_flood.sw_if_index
+ if self.bm_flood else INDEX_INVALID,
+ "bd_id": self.bd.bd_id,
+ "rd_id": self.rd.rd_id,
+ }
+
def add_vpp_config(self):
self._test.vapi.gbp_bridge_domain_add(
- self.bd.bd_id,
- self.rd.rd_id,
- self.flags,
- self.bvi.sw_if_index,
- self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
- self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
+ bd=self.encode(),
+ )
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
- self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
+ self._test.vapi.gbp_bridge_domain_del(bd_id=self.bd.bd_id)
- def object_id(self):
+ def object_id(self) -> str:
return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
- def query_vpp_config(self):
+ def query_vpp_config(self) -> bool:
bds = self._test.vapi.gbp_bridge_domain_dump()
for bd in bds:
if bd.bd.bd_id == self.bd.bd_id:
@@ -404,18 +467,27 @@ class VppGbpRouteDomain(VppObject):
self.ip4_uu = ip4_uu
self.ip6_uu = ip6_uu
+ def encode(self) -> dict:
+ return {
+ "rd_id": self.rd_id,
+ "scope": self.scope,
+ "ip4_table_id": self.t4.table_id,
+ "ip6_table_id": self.t6.table_id,
+ "ip4_uu_sw_if_index": self.ip4_uu.sw_if_index
+ if self.ip4_uu else INDEX_INVALID,
+ "ip6_uu_sw_if_index": self.ip6_uu.sw_if_index
+ if self.ip6_uu else INDEX_INVALID,
+
+ }
+
def add_vpp_config(self):
self._test.vapi.gbp_route_domain_add(
- self.rd_id,
- self.scope,
- self.t4.table_id,
- self.t6.table_id,
- self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
- self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
+ rd=self.encode(),
+ )
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
- self._test.vapi.gbp_route_domain_del(self.rd_id)
+ self._test.vapi.gbp_route_domain_del(rd_id=self.rd_id)
def object_id(self):
return "gbp-route-domain:[%d]" % (self.rd_id)
@@ -428,27 +500,29 @@ class VppGbpRouteDomain(VppObject):
return False
-class VppGbpContractNextHop():
+class VppGbpContractNextHop:
def __init__(self, mac, bd, ip, rd):
self.mac = mac
self.ip = ip
self.bd = bd
self.rd = rd
- def encode(self):
- return {'ip': self.ip,
- 'mac': self.mac.packed,
- 'bd_id': self.bd.bd.bd_id,
- 'rd_id': self.rd.rd_id}
+ def encode(self) -> dict:
+ return {
+ "ip": self.ip,
+ "mac": self.mac.packed,
+ "bd_id": self.bd.bd.bd_id,
+ "rd_id": self.rd.rd_id,
+ }
-class VppGbpContractRule():
+class VppGbpContractRule:
def __init__(self, action, hash_mode, nhs=None):
self.action = action
self.hash_mode = hash_mode
self.nhs = [] if nhs is None else nhs
- def encode(self):
+ def encode(self) -> dict:
nhs = []
for nh in self.nhs:
nhs.append(nh.encode())
@@ -471,12 +545,8 @@ class VppGbpContract(VppObject):
"""
def __init__(self, test, scope, sclass, dclass, acl_index,
- rules, allowed_ethertypes):
+ rules: list, allowed_ethertypes: list):
self._test = test
- if not isinstance(rules, list):
- raise ValueError("'rules' must be a list.")
- if not isinstance(allowed_ethertypes, list):
- raise ValueError("'allowed_ethertypes' must be a list.")
self.scope = scope
self.acl_index = acl_index
self.sclass = sclass
@@ -486,36 +556,35 @@ class VppGbpContract(VppObject):
while (len(self.allowed_ethertypes) < 16):
self.allowed_ethertypes.append(0)
- def add_vpp_config(self):
+ def encode(self) -> dict:
rules = []
for r in self.rules:
rules.append(r.encode())
+ return {
+ 'acl_index': self.acl_index,
+ 'scope': self.scope,
+ 'sclass': self.sclass,
+ 'dclass': self.dclass,
+ 'n_rules': len(rules),
+ 'rules': rules,
+ 'n_ether_types': len(self.allowed_ethertypes),
+ 'allowed_ethertypes': self.allowed_ethertypes,
+ }
+
+ def add_vpp_config(self):
r = self._test.vapi.gbp_contract_add_del(
is_add=1,
- contract={
- 'acl_index': self.acl_index,
- 'scope': self.scope,
- 'sclass': self.sclass,
- 'dclass': self.dclass,
- 'n_rules': len(rules),
- 'rules': rules,
- 'n_ether_types': len(self.allowed_ethertypes),
- 'allowed_ethertypes': self.allowed_ethertypes})
+ contract=self.encode()
+ )
+
self.stats_index = r.stats_index
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
self._test.vapi.gbp_contract_add_del(
is_add=0,
- contract={
- 'acl_index': self.acl_index,
- 'scope': self.scope,
- 'sclass': self.sclass,
- 'dclass': self.dclass,
- 'n_rules': 0,
- 'rules': [],
- 'n_ether_types': len(self.allowed_ethertypes),
- 'allowed_ethertypes': self.allowed_ethertypes})
+ contract=self.encode(),
+ )
def object_id(self):
return "gbp-contract:[%d:%d:%d:%d]" % (self.scope,
@@ -554,17 +623,23 @@ class VppGbpVxlanTunnel(VppInterface):
self.mode = mode
self.src = src
+ def encode(self) -> dict:
+ return {
+ "vni": self.vni,
+ "mode": self.mode,
+ "bd_rd_id": self.bd_rd_id,
+ "src": self.src,
+ }
+
def add_vpp_config(self):
r = self._test.vapi.gbp_vxlan_tunnel_add(
- self.vni,
- self.bd_rd_id,
- self.mode,
- self.src)
+ tunnel=self.encode(),
+ )
self.set_sw_if_index(r.sw_if_index)
self._test.registry.register(self, self._test.logger)
def remove_vpp_config(self):
- self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
+ self._test.vapi.gbp_vxlan_tunnel_del(vni=self.vni)
def object_id(self):
return "gbp-vxlan:%d" % (self.sw_if_index)
@@ -728,7 +803,6 @@ class TestGBP(VppTestCase):
self.pg_send(src, tx)
dst.get_capture(0, timeout=1)
dst.assert_nothing_captured(remark="")
- timeout = 0.1
def send_and_expect_arp(self, src, tx, dst):
rx = self.send_and_expect(src, tx, dst)