diff options
author | Klement Sekera <klement.sekera@gmail.com> | 2022-04-26 19:02:15 +0200 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2022-05-10 18:52:08 +0000 |
commit | d9b0c6fbf7aa5bd9af84264105b39c82028a4a29 (patch) | |
tree | 4f786cfd8ebc2443cb11e11b74c8657204068898 /extras | |
parent | f90348bcb4afd0af2611cefc43b17ef3042b511c (diff) |
tests: replace pycodestyle with black
Drop pycodestyle for code style checking in favor of black. Black is
much faster, stable PEP8 compliant code style checker offering also
automatic formatting. It aims to be very stable and produce smallest
diffs. It's used by many small and big projects.
Running checkstyle with black takes a few seconds with a terse output.
Thus, test-checkstyle-diff is no longer necessary.
Expand scope of checkstyle to all python files in the repo, replacing
test-checkstyle with checkstyle-python.
Also, fixstyle-python is now available for automatic style formatting.
Note: python virtualenv has been consolidated in test/Makefile,
test/requirements*.txt which will eventually be moved to a central
location. This is required to simply the automated generation of
docker executor images in the CI.
Type: improvement
Change-Id: I022a326603485f58585e879ac0f697fceefbc9c8
Signed-off-by: Klement Sekera <klement.sekera@gmail.com>
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Diffstat (limited to 'extras')
-rwxr-xr-x | extras/deprecated/perfmon/intel_json_to_c.py | 64 | ||||
-rw-r--r-- | extras/deprecated/plugins/gbp/test_gbp.py | 5510 | ||||
-rw-r--r-- | extras/deprecated/vnet/vxlan-gbp/test_vxlan_gbp.py | 143 | ||||
-rw-r--r-- | extras/deprecated/vnet/vxlan-gbp/vpp_vxlan_gbp_tunnel.py | 64 | ||||
-rw-r--r-- | extras/deprecated/vom/test/test_vom.py | 23 | ||||
-rwxr-xr-x | extras/scripts/crcchecker.py | 207 | ||||
-rwxr-xr-x | extras/scripts/list_api_changes.py | 23 | ||||
-rwxr-xr-x | extras/vpp_config/scripts/dpdk-devbind.py | 213 | ||||
-rw-r--r-- | extras/vpp_config/setup.py | 60 | ||||
-rwxr-xr-x | extras/vpp_config/vpp_config.py | 354 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/AutoConfig.py | 1205 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/CpuUtils.py | 88 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/QemuUtils.py | 484 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/VPPUtil.py | 435 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/VppGrubUtil.py | 146 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/VppHugePageUtil.py | 76 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/VppPCIUtil.py | 165 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/constants.py | 18 |
18 files changed, 5398 insertions, 3880 deletions
diff --git a/extras/deprecated/perfmon/intel_json_to_c.py b/extras/deprecated/perfmon/intel_json_to_c.py index 6a625ac2c33..4389c86fc38 100755 --- a/extras/deprecated/perfmon/intel_json_to_c.py +++ b/extras/deprecated/perfmon/intel_json_to_c.py @@ -4,48 +4,58 @@ import json, argparse p = argparse.ArgumentParser() -p.add_argument('-i', '--input', action="store", - help="input JSON file name", required = True) - -p.add_argument('-o', '--output', action="store", - help="output C file name", required = True) - -p.add_argument('-m', '--model', action="append", - help="CPU model in format: model[,stepping0]", - required = True) +p.add_argument( + "-i", "--input", action="store", help="input JSON file name", required=True +) + +p.add_argument( + "-o", "--output", action="store", help="output C file name", required=True +) + +p.add_argument( + "-m", + "--model", + action="append", + help="CPU model in format: model[,stepping0]", + required=True, +) r = p.parse_args() -with open(r.input, 'r') as fp: +with open(r.input, "r") as fp: objects = json.load(fp) -c = open(r.output, 'w') +c = open(r.output, "w") -c.write (""" +c.write( + """ #include <perfmon/perfmon_intel.h> static perfmon_intel_pmc_cpu_model_t cpu_model_table[] = { -""") +""" +) for v in r.model: if "," in v: - (m, s) = v.split(",") + (m, s) = v.split(",") m = int(m, 0) s = int(s, 0) - c.write (" {}0x{:02X}, 0x{:02X}, 1{},\n".format("{", m, s, "}")) + c.write(" {}0x{:02X}, 0x{:02X}, 1{},\n".format("{", m, s, "}")) else: m = int(v, 0) - c.write (" {}0x{:02X}, 0x00, 0{},\n".format("{", m, "}")) -c.write (""" + c.write(" {}0x{:02X}, 0x00, 0{},\n".format("{", m, "}")) +c.write( + """ }; static perfmon_intel_pmc_event_t event_table[] = { -""") +""" +) for obj in objects: MSRIndex = obj["MSRIndex"] if MSRIndex != "0": - continue + continue EventCode = obj["EventCode"] UMask = obj["UMask"] @@ -53,20 +63,22 @@ for obj in objects: if "," in EventCode: continue - c.write (" {\n") - c.write (" .event_code = {}{}{},\n".format("{", EventCode, "}")) - c.write (" .umask = {},\n".format(UMask)) - c.write (" .event_name = \"{}\",\n".format(EventName)) - c.write (" },\n") + c.write(" {\n") + c.write(" .event_code = {}{}{},\n".format("{", EventCode, "}")) + c.write(" .umask = {},\n".format(UMask)) + c.write(' .event_name = "{}",\n'.format(EventName)) + c.write(" },\n") -c.write (""" { +c.write( + """ { .event_name = 0, }, }; PERFMON_REGISTER_INTEL_PMC (cpu_model_table, event_table); -""") +""" +) c.close() diff --git a/extras/deprecated/plugins/gbp/test_gbp.py b/extras/deprecated/plugins/gbp/test_gbp.py index c30a729519d..8c53b393f92 100644 --- a/extras/deprecated/plugins/gbp/test_gbp.py +++ b/extras/deprecated/plugins/gbp/test_gbp.py @@ -43,16 +43,16 @@ from vpp_l2 import ( from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint from vpp_ip import DpoProto, get_dpo_proto from vpp_papi import VppEnum, MACAddress -from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \ - VppVxlanGbpTunnel +from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, VppVxlanGbpTunnel from vpp_neighbor import VppNeighbor from vpp_acl import AclRule, VppAcl NUM_PKTS = 67 -def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, - tep=None, sclass=None, flags=None): +def find_gbp_endpoint( + test, sw_if_index=None, ip=None, mac=None, tep=None, sclass=None, flags=None +): if ip: vip = ip if mac: @@ -64,8 +64,7 @@ def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, if tep: src = tep[0] dst = tep[1] - if src != str(ep.endpoint.tun.src) or \ - dst != str(ep.endpoint.tun.dst): + if src != str(ep.endpoint.tun.src) or dst != str(ep.endpoint.tun.dst): continue if sw_if_index: if ep.endpoint.sw_if_index != sw_if_index: @@ -128,11 +127,21 @@ class VppGbpEndpoint(VppObject): def fips(self): return [self.fip4, self.fip6] - def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6, - flags=0, - tun_src="0.0.0.0", - tun_dst="0.0.0.0", - mac=True): + def __init__( + self, + test, + itf, + epg, + recirc, + ip4, + fip4, + ip6, + fip6, + flags=0, + tun_src="0.0.0.0", + tun_dst="0.0.0.0", + mac=True, + ): self._test = test self.itf = itf self.handle = None @@ -179,15 +188,15 @@ class VppGbpEndpoint(VppObject): self._test.vapi.gbp_endpoint_del(handle=self.handle) def object_id(self): - return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle, - self.itf.sw_if_index, - self.ip4, - self.epg.sclass) + return "gbp-endpoint:[%d==%d:%s:%d]" % ( + self.handle, + self.itf.sw_if_index, + self.ip4, + self.epg.sclass, + ) def query_vpp_config(self): - return find_gbp_endpoint(self._test, - self.itf.sw_if_index, - self.ip4) + return find_gbp_endpoint(self._test, self.itf.sw_if_index, self.ip4) class VppGbpRecirc(VppObject): @@ -266,8 +275,10 @@ class VppGbpExtItf(VppObject): ) def object_id(self): - return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index, - " [anon]" if self.flags else "") + return "gbp-ext-itf:[%d]%s" % ( + self.itf.sw_if_index, + " [anon]" if self.flags else "", + ) def query_vpp_config(self): rs = self._test.vapi.gbp_ext_itf_dump() @@ -282,19 +293,25 @@ class VppGbpSubnet(VppObject): GBP Subnet """ - def __init__(self, test, rd, address, address_len, - type, sw_if_index=0xffffffff, sclass=0xffff): + def __init__( + self, + test, + rd, + address, + address_len, + 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) if 4 == a.version: - self.prefix = IPv4Network("%s/%d" % (address, address_len), - strict=False) + self.prefix = IPv4Network("%s/%d" % (address, address_len), strict=False) else: - self.prefix = IPv6Network("%s/%d" % (address, address_len), - strict=False) + self.prefix = IPv6Network("%s/%d" % (address, address_len), strict=False) self.type = type self.sw_if_index = sw_if_index self.sclass = sclass @@ -316,10 +333,7 @@ class VppGbpSubnet(VppObject): self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): - self._test.vapi.gbp_subnet_add_del( - is_add=0, - subnet=self.encode() - ) + self._test.vapi.gbp_subnet_add_del(is_add=0, subnet=self.encode()) def object_id(self): return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix) @@ -327,19 +341,21 @@ class VppGbpSubnet(VppObject): def query_vpp_config(self): ss = self._test.vapi.gbp_subnet_dump() for s in ss: - if s.subnet.rd_id == self.rd_id and \ - s.subnet.type == self.type and \ - s.subnet.prefix == self.prefix: + if ( + s.subnet.rd_id == self.rd_id + and s.subnet.type == self.type + and s.subnet.prefix == self.prefix + ): return True return False class VppGbpEndpointRetention(object): - def __init__(self, remote_ep_timeout=0xffffffff): + def __init__(self, remote_ep_timeout=0xFFFFFFFF): self.remote_ep_timeout = remote_ep_timeout def encode(self): - return {'remote_ep_timeout': self.remote_ep_timeout} + return {"remote_ep_timeout": self.remote_ep_timeout} class VppGbpEndpointGroup(VppObject): @@ -347,9 +363,19 @@ class VppGbpEndpointGroup(VppObject): GBP Endpoint Group """ - def __init__(self, test, vnid, sclass, rd, bd, uplink, - bvi, bvi_ip4, bvi_ip6=None, - retention=VppGbpEndpointRetention()): + def __init__( + self, + test, + vnid, + sclass, + rd, + bd, + uplink, + bvi, + bvi_ip4, + bvi_ip6=None, + retention=VppGbpEndpointRetention(), + ): self._test = test self.uplink = uplink self.bvi = bvi @@ -360,13 +386,14 @@ class VppGbpEndpointGroup(VppObject): self.rd = rd self.sclass = sclass if 0 == self.sclass: - self.sclass = 0xffff + 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, + if self.uplink + else INDEX_INVALID, "bd_id": self.bd.bd.bd_id, "rd_id": self.rd.rd_id, "vnid": self.vnid, @@ -397,11 +424,19 @@ class VppGbpBridgeDomain(VppObject): GBP Bridge Domain """ - 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): + 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, + ): self._test = test self.bvi = bvi self.uu_fwd = uu_fwd @@ -426,9 +461,11 @@ class VppGbpBridgeDomain(VppObject): "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, + 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, + if self.bm_flood + else INDEX_INVALID, "bd_id": self.bd.bd_id, "rd_id": self.rd.rd_id, } @@ -474,10 +511,11 @@ class VppGbpRouteDomain(VppObject): "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, + 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, - + if self.ip6_uu + else INDEX_INVALID, } def add_vpp_config(self): @@ -528,15 +566,16 @@ class VppGbpContractRule: nhs.append(nh.encode()) while len(nhs) < 8: nhs.append({}) - return {'action': self.action, - 'nh_set': { - 'hash_mode': self.hash_mode, - 'n_nhs': len(self.nhs), - 'nhs': nhs}} + return { + "action": self.action, + "nh_set": {"hash_mode": self.hash_mode, "n_nhs": len(self.nhs), "nhs": nhs}, + } def __repr__(self): - return '<VppGbpContractRule action=%s, hash_mode=%s>' % ( - self.action, self.hash_mode) + return "<VppGbpContractRule action=%s, hash_mode=%s>" % ( + self.action, + self.hash_mode, + ) class VppGbpContract(VppObject): @@ -544,8 +583,16 @@ class VppGbpContract(VppObject): GBP Contract """ - def __init__(self, test, scope, sclass, dclass, acl_index, - rules: list, allowed_ethertypes: list): + def __init__( + self, + test, + scope, + sclass, + dclass, + acl_index, + rules: list, + allowed_ethertypes: list, + ): self._test = test self.scope = scope self.acl_index = acl_index @@ -553,7 +600,7 @@ class VppGbpContract(VppObject): self.dclass = dclass self.rules = rules self.allowed_ethertypes = allowed_ethertypes - while (len(self.allowed_ethertypes) < 16): + while len(self.allowed_ethertypes) < 16: self.allowed_ethertypes.append(0) def encode(self) -> dict: @@ -561,21 +608,18 @@ class VppGbpContract(VppObject): 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, + "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=self.encode() - ) + r = self._test.vapi.gbp_contract_add_del(is_add=1, contract=self.encode()) self.stats_index = r.stats_index self._test.registry.register(self, self._test.logger) @@ -587,17 +631,21 @@ class VppGbpContract(VppObject): ) def object_id(self): - return "gbp-contract:[%d:%d:%d:%d]" % (self.scope, - self.sclass, - self.dclass, - self.acl_index) + return "gbp-contract:[%d:%d:%d:%d]" % ( + self.scope, + self.sclass, + self.dclass, + self.acl_index, + ) def query_vpp_config(self): cs = self._test.vapi.gbp_contract_dump() for c in cs: - if c.contract.scope == self.scope \ - and c.contract.sclass == self.sclass \ - and c.contract.dclass == self.dclass: + if ( + c.contract.scope == self.scope + and c.contract.sclass == self.sclass + and c.contract.dclass == self.dclass + ): return True return False @@ -650,7 +698,7 @@ class VppGbpVxlanTunnel(VppInterface): @tag_fixme_vpp_workers class TestGBP(VppTestCase): - """ GBP Test Case """ + """GBP Test Case""" @property def nat_config_flags(self): @@ -817,7 +865,7 @@ class TestGBP(VppTestCase): return rx def test_gbp(self): - """ Group Based Policy """ + """Group Based Policy""" ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t @@ -862,26 +910,70 @@ class TestGBP(VppTestCase): # 3 EPGs, 2 of which share a BD. # 2 NAT EPGs, one for floating-IP subnets, the other for internet # - epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1, - self.pg4, self.loop0, - "10.0.0.128", "2001:10::128"), - VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1, - self.pg5, self.loop0, - "10.0.1.128", "2001:10:1::128"), - VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2, - self.pg6, self.loop1, - "10.0.2.128", "2001:10:2::128"), - VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20, - self.pg7, self.loop2, - "11.0.0.128", "3001::128"), - VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20, - self.pg8, self.loop2, - "11.0.0.129", "3001::129")] - recircs = [VppGbpRecirc(self, epgs[0], self.loop3), - VppGbpRecirc(self, epgs[1], self.loop4), - VppGbpRecirc(self, epgs[2], self.loop5), - VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True), - VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)] + epgs = [ + VppGbpEndpointGroup( + self, + 220, + 1220, + rd0, + gbd1, + self.pg4, + self.loop0, + "10.0.0.128", + "2001:10::128", + ), + VppGbpEndpointGroup( + self, + 221, + 1221, + rd0, + gbd1, + self.pg5, + self.loop0, + "10.0.1.128", + "2001:10:1::128", + ), + VppGbpEndpointGroup( + self, + 222, + 1222, + rd0, + gbd2, + self.pg6, + self.loop1, + "10.0.2.128", + "2001:10:2::128", + ), + VppGbpEndpointGroup( + self, + 333, + 1333, + rd20, + gbd20, + self.pg7, + self.loop2, + "11.0.0.128", + "3001::128", + ), + VppGbpEndpointGroup( + self, + 444, + 1444, + rd20, + gbd20, + self.pg8, + self.loop2, + "11.0.0.129", + "3001::129", + ), + ] + recircs = [ + VppGbpRecirc(self, epgs[0], self.loop3), + VppGbpRecirc(self, epgs[1], self.loop4), + VppGbpRecirc(self, epgs[2], self.loop5), + VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True), + VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True), + ] epg_nat = epgs[3] recirc_nat = recircs[3] @@ -889,22 +981,48 @@ class TestGBP(VppTestCase): # # 4 end-points, 2 in the same subnet, 3 in the same BD # - eps = [VppGbpEndpoint(self, self.pg0, - epgs[0], recircs[0], - "10.0.0.1", "11.0.0.1", - "2001:10::1", "3001::1"), - VppGbpEndpoint(self, self.pg1, - epgs[0], recircs[0], - "10.0.0.2", "11.0.0.2", - "2001:10::2", "3001::2"), - VppGbpEndpoint(self, self.pg2, - epgs[1], recircs[1], - "10.0.1.1", "11.0.0.3", - "2001:10:1::1", "3001::3"), - VppGbpEndpoint(self, self.pg3, - epgs[2], recircs[2], - "10.0.2.1", "11.0.0.4", - "2001:10:2::1", "3001::4")] + eps = [ + VppGbpEndpoint( + self, + self.pg0, + epgs[0], + recircs[0], + "10.0.0.1", + "11.0.0.1", + "2001:10::1", + "3001::1", + ), + VppGbpEndpoint( + self, + self.pg1, + epgs[0], + recircs[0], + "10.0.0.2", + "11.0.0.2", + "2001:10::2", + "3001::2", + ), + VppGbpEndpoint( + self, + self.pg2, + epgs[1], + recircs[1], + "10.0.1.1", + "11.0.0.3", + "2001:10:1::1", + "3001::3", + ), + VppGbpEndpoint( + self, + self.pg3, + epgs[2], + recircs[2], + "10.0.2.1", + "11.0.0.4", + "2001:10:2::1", + "3001::4", + ), + ] self.vapi.nat44_ed_plugin_enable_disable(enable=1) self.vapi.nat66_plugin_enable_disable(enable=1) @@ -915,39 +1033,37 @@ class TestGBP(VppTestCase): for epg in epgs: # IP config on the BVI interfaces if epg != epgs[1] and epg != epgs[4]: - b4 = VppIpInterfaceBind(self, epg.bvi, - epg.rd.t4).add_vpp_config() - b6 = VppIpInterfaceBind(self, epg.bvi, - epg.rd.t6).add_vpp_config() + b4 = VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config() + b6 = VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config() epg.bvi.set_mac(self.router_mac) # The BVIs are NAT inside interfaces flags = self.nat_config_flags.NAT_IS_INSIDE self.vapi.nat44_interface_add_del_feature( - sw_if_index=epg.bvi.sw_if_index, - flags=flags, is_add=1) + sw_if_index=epg.bvi.sw_if_index, flags=flags, is_add=1 + ) self.vapi.nat66_add_del_interface( - sw_if_index=epg.bvi.sw_if_index, - flags=flags, is_add=1) + sw_if_index=epg.bvi.sw_if_index, flags=flags, is_add=1 + ) - if_ip4 = VppIpInterfaceAddress(self, epg.bvi, - epg.bvi_ip4, 32, - bind=b4).add_vpp_config() - if_ip6 = VppIpInterfaceAddress(self, epg.bvi, - epg.bvi_ip6, 128, - bind=b6).add_vpp_config() + if_ip4 = VppIpInterfaceAddress( + self, epg.bvi, epg.bvi_ip4, 32, bind=b4 + ).add_vpp_config() + if_ip6 = VppIpInterfaceAddress( + self, epg.bvi, epg.bvi_ip6, 128, bind=b6 + ).add_vpp_config() # EPG uplink interfaces in the RD VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config() VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config() # add the BD ARP termination entry for BVI IP - epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd, - str(self.router_mac), - epg.bvi_ip4) - epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd, - str(self.router_mac), - epg.bvi_ip6) + epg.bd_arp_ip4 = VppBridgeDomainArpEntry( + self, epg.bd.bd, str(self.router_mac), epg.bvi_ip4 + ) + epg.bd_arp_ip6 = VppBridgeDomainArpEntry( + self, epg.bd.bd, str(self.router_mac), epg.bvi_ip6 + ) epg.bd_arp_ip4.add_vpp_config() epg.bd_arp_ip6.add_vpp_config() @@ -956,22 +1072,24 @@ class TestGBP(VppTestCase): for recirc in recircs: # EPG's ingress recirculation interface maps to its RD - VppIpInterfaceBind(self, recirc.recirc, - recirc.epg.rd.t4).add_vpp_config() - VppIpInterfaceBind(self, recirc.recirc, - recirc.epg.rd.t6).add_vpp_config() + VppIpInterfaceBind(self, recirc.recirc, recirc.epg.rd.t4).add_vpp_config() + VppIpInterfaceBind(self, recirc.recirc, recirc.epg.rd.t6).add_vpp_config() self.vapi.nat44_interface_add_del_feature( - sw_if_index=recirc.recirc.sw_if_index, is_add=1) + sw_if_index=recirc.recirc.sw_if_index, is_add=1 + ) self.vapi.nat66_add_del_interface( - sw_if_index=recirc.recirc.sw_if_index, is_add=1) + sw_if_index=recirc.recirc.sw_if_index, is_add=1 + ) recirc.add_vpp_config() for recirc in recircs: - self.assertTrue(find_bridge_domain_port(self, - recirc.epg.bd.bd.bd_id, - recirc.recirc.sw_if_index)) + self.assertTrue( + find_bridge_domain_port( + self, recirc.epg.bd.bd.bd_id, recirc.recirc.sw_if_index + ) + ) for ep in eps: self.pg_enable_capture(self.pg_interfaces) @@ -991,12 +1109,12 @@ class TestGBP(VppTestCase): external_ip_address=fip, external_sw_if_index=0xFFFFFFFF, vrf_id=0, - flags=flags) + flags=flags, + ) else: self.vapi.nat66_add_del_static_mapping( - local_ip_address=ip, - external_ip_address=fip, - vrf_id=0, is_add=1) + local_ip_address=ip, external_ip_address=fip, vrf_id=0, is_add=1 + ) # VPP EP create ... ep.add_vpp_config() @@ -1019,36 +1137,41 @@ class TestGBP(VppTestCase): # add the BD ARP termination entry for floating IP for fip in ep.fips: - ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, - fip) + ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip) ba.add_vpp_config() # floating IPs route via EPG recirc r = VppIpRoute( - self, fip, ip_address(fip).max_prefixlen, - [VppRoutePath(fip, - ep.recirc.recirc.sw_if_index, - type=FibPathType.FIB_PATH_TYPE_DVR, - proto=get_dpo_proto(fip))], - table_id=20) + self, + fip, + ip_address(fip).max_prefixlen, + [ + VppRoutePath( + fip, + ep.recirc.recirc.sw_if_index, + type=FibPathType.FIB_PATH_TYPE_DVR, + proto=get_dpo_proto(fip), + ) + ], + table_id=20, + ) r.add_vpp_config() # L2 FIB entries in the NAT EPG BD to bridge the packets from # the outside direct to the internal EPG - lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac, - ep.recirc.recirc, bvi_mac=0) + lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac, ep.recirc.recirc, bvi_mac=0) lf.add_vpp_config() # # ARP packets for unknown IP are sent to the EPG uplink # - pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff", - src=self.pg0.remote_mac) / - ARP(op="who-has", - hwdst="ff:ff:ff:ff:ff:ff", - hwsrc=self.pg0.remote_mac, - pdst="10.0.0.88", - psrc="10.0.0.99")) + pkt_arp = Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP( + op="who-has", + hwdst="ff:ff:ff:ff:ff:ff", + hwsrc=self.pg0.remote_mac, + pdst="10.0.0.88", + psrc="10.0.0.99", + ) self.vapi.cli("clear trace") self.pg0.add_stream(pkt_arp) @@ -1061,33 +1184,35 @@ class TestGBP(VppTestCase): # # ARP/ND packets get a response # - pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff", - src=self.pg0.remote_mac) / - ARP(op="who-has", - hwdst="ff:ff:ff:ff:ff:ff", - hwsrc=self.pg0.remote_mac, - pdst=epgs[0].bvi_ip4, - psrc=eps[0].ip4)) + pkt_arp = Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) / ARP( + op="who-has", + hwdst="ff:ff:ff:ff:ff:ff", + hwsrc=self.pg0.remote_mac, + pdst=epgs[0].bvi_ip4, + psrc=eps[0].ip4, + ) self.send_and_expect(self.pg0, [pkt_arp], self.pg0) nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6)) d = inet_ntop(AF_INET6, nsma) - pkt_nd = (Ether(dst=in6_getnsmac(nsma), - src=self.pg0.remote_mac) / - IPv6(dst=d, src=eps[0].ip6) / - ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) / - ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac)) + pkt_nd = ( + Ether(dst=in6_getnsmac(nsma), src=self.pg0.remote_mac) + / IPv6(dst=d, src=eps[0].ip6) + / ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) + / ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac) + ) self.send_and_expect(self.pg0, [pkt_nd], self.pg0) # # broadcast packets are flooded # - pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff", - src=self.pg0.remote_mac) / - IP(src=eps[0].ip4, dst="232.1.1.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_bcast = ( + Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) + / IP(src=eps[0].ip4, dst="232.1.1.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.vapi.cli("clear trace") self.pg0.add_stream(pkt_bcast) @@ -1103,52 +1228,74 @@ class TestGBP(VppTestCase): # # packets to non-local L3 destinations dropped # - pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst="10.0.0.99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst="10.0.1.99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - - self.send_and_assert_no_replies(self.pg0, - pkt_intra_epg_220_ip4 * NUM_PKTS) - - pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6, - dst="2001:10::99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - self.send_and_assert_no_replies(self.pg0, - pkt_inter_epg_222_ip6 * NUM_PKTS) + pkt_intra_epg_220_ip4 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst="10.0.0.99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkt_inter_epg_222_ip4 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst="10.0.1.99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + + self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * NUM_PKTS) + + pkt_inter_epg_222_ip6 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IPv6(src=eps[0].ip6, dst="2001:10::99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * NUM_PKTS) # # Add the subnet routes # s41 = VppGbpSubnet( - self, rd0, "10.0.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "10.0.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s42 = VppGbpSubnet( - self, rd0, "10.0.1.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "10.0.1.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s43 = VppGbpSubnet( - self, rd0, "10.0.2.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "10.0.2.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s61 = VppGbpSubnet( - self, rd0, "2001:10::1", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "2001:10::1", + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s62 = VppGbpSubnet( - self, rd0, "2001:10:1::1", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "2001:10:1::1", + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s63 = VppGbpSubnet( - self, rd0, "2001:10:2::1", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL) + self, + rd0, + "2001:10:2::1", + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL, + ) s41.add_vpp_config() s42.add_vpp_config() s43.add_vpp_config() @@ -1156,15 +1303,15 @@ class TestGBP(VppTestCase): s62.add_vpp_config() s63.add_vpp_config() - self.send_and_expect_bridged(eps[0].itf, - pkt_intra_epg_220_ip4 * NUM_PKTS, - eps[0].epg.uplink) - self.send_and_expect_bridged(eps[0].itf, - pkt_inter_epg_222_ip4 * NUM_PKTS, - eps[0].epg.uplink) - self.send_and_expect_bridged6(eps[0].itf, - pkt_inter_epg_222_ip6 * NUM_PKTS, - eps[0].epg.uplink) + self.send_and_expect_bridged( + eps[0].itf, pkt_intra_epg_220_ip4 * NUM_PKTS, eps[0].epg.uplink + ) + self.send_and_expect_bridged( + eps[0].itf, pkt_inter_epg_222_ip4 * NUM_PKTS, eps[0].epg.uplink + ) + self.send_and_expect_bridged6( + eps[0].itf, pkt_inter_epg_222_ip6 * NUM_PKTS, eps[0].epg.uplink + ) self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2")) self.logger.info(self.vapi.cli("sh gbp endpoint-group")) @@ -1180,182 +1327,210 @@ class TestGBP(VppTestCase): # # Packet destined to unknown unicast is sent on the epg uplink ... # - pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac, - dst="00:00:00:33:44:55") / - IP(src=eps[0].ip4, - dst="10.0.0.99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_220_to_uplink = ( + Ether(src=self.pg0.remote_mac, dst="00:00:00:33:44:55") + / IP(src=eps[0].ip4, dst="10.0.0.99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged(eps[0].itf, - pkt_intra_epg_220_to_uplink * NUM_PKTS, - eps[0].epg.uplink) + self.send_and_expect_bridged( + eps[0].itf, pkt_intra_epg_220_to_uplink * NUM_PKTS, eps[0].epg.uplink + ) # ... and nowhere else self.pg1.get_capture(0, timeout=0.1) self.pg1.assert_nothing_captured(remark="Flood onto other VMS") - pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac, - dst="00:00:00:33:44:66") / - IP(src=eps[0].ip4, - dst="10.0.0.99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_221_to_uplink = ( + Ether(src=self.pg2.remote_mac, dst="00:00:00:33:44:66") + / IP(src=eps[0].ip4, dst="10.0.0.99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged(eps[2].itf, - pkt_intra_epg_221_to_uplink * NUM_PKTS, - eps[2].epg.uplink) + self.send_and_expect_bridged( + eps[2].itf, pkt_intra_epg_221_to_uplink * NUM_PKTS, eps[2].epg.uplink + ) # # Packets from the uplink are forwarded in the absence of a contract # - pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55", - dst=self.pg0.remote_mac) / - IP(src=eps[0].ip4, - dst="10.0.0.99") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_220_from_uplink = ( + Ether(src="00:00:00:33:44:55", dst=self.pg0.remote_mac) + / IP(src=eps[0].ip4, dst="10.0.0.99") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged(self.pg4, - pkt_intra_epg_220_from_uplink * NUM_PKTS, - self.pg0) + self.send_and_expect_bridged( + self.pg4, pkt_intra_epg_220_from_uplink * NUM_PKTS, self.pg0 + ) # # in the absence of policy, endpoints in the same EPG # can communicate # - pkt_intra_epg = (Ether(src=self.pg0.remote_mac, - dst=self.pg1.remote_mac) / - IP(src=eps[0].ip4, - dst=eps[1].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg = ( + Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) + / IP(src=eps[0].ip4, dst=eps[1].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged(self.pg0, - pkt_intra_epg * NUM_PKTS, - self.pg1) + self.send_and_expect_bridged(self.pg0, pkt_intra_epg * NUM_PKTS, self.pg1) # # in the absence of policy, endpoints in the different EPG # cannot communicate # - pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, - dst=self.pg2.remote_mac) / - IP(src=eps[0].ip4, - dst=eps[2].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, - dst=self.pg0.remote_mac) / - IP(src=eps[2].ip4, - dst=eps[0].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst=eps[3].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_221 * NUM_PKTS) - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_222 * NUM_PKTS) + pkt_inter_epg_220_to_221 = ( + Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) + / IP(src=eps[0].ip4, dst=eps[2].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkt_inter_epg_221_to_220 = ( + Ether(src=self.pg2.remote_mac, dst=self.pg0.remote_mac) + / IP(src=eps[2].ip4, dst=eps[0].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + pkt_inter_epg_220_to_222 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst=eps[3].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_221 * NUM_PKTS) + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_222 * NUM_PKTS) # # A uni-directional contract from EPG 220 -> 221 # rule = AclRule(is_permit=1, proto=17) - rule2 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule2 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule, rule2]) acl.add_vpp_config() c1 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 400, + epgs[0].sclass, + epgs[1].sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() - self.send_and_expect_bridged(eps[0].itf, - pkt_inter_epg_220_to_221 * NUM_PKTS, - eps[2].itf) - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_222 * NUM_PKTS) + self.send_and_expect_bridged( + eps[0].itf, pkt_inter_epg_220_to_221 * NUM_PKTS, eps[2].itf + ) + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_222 * NUM_PKTS) # # contract for the return direction # c2 = VppGbpContract( - self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 400, + epgs[1].sclass, + epgs[0].sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() - self.send_and_expect_bridged(eps[0].itf, - pkt_inter_epg_220_to_221 * NUM_PKTS, - eps[2].itf) - self.send_and_expect_bridged(eps[2].itf, - pkt_inter_epg_221_to_220 * NUM_PKTS, - eps[0].itf) + self.send_and_expect_bridged( + eps[0].itf, pkt_inter_epg_220_to_221 * NUM_PKTS, eps[2].itf + ) + self.send_and_expect_bridged( + eps[2].itf, pkt_inter_epg_221_to_220 * NUM_PKTS, eps[0].itf + ) ds = c2.get_drop_stats() - self.assertEqual(ds['packets'], 0) + self.assertEqual(ds["packets"], 0) ps = c2.get_permit_stats() - self.assertEqual(ps['packets'], NUM_PKTS) + self.assertEqual(ps["packets"], NUM_PKTS) # # the contract does not allow non-IP # - pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, - dst=self.pg2.remote_mac) / - ARP()) - self.send_and_assert_no_replies(eps[0].itf, - pkt_non_ip_inter_epg_220_to_221 * 17) + pkt_non_ip_inter_epg_220_to_221 = ( + Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) / ARP() + ) + self.send_and_assert_no_replies( + eps[0].itf, pkt_non_ip_inter_epg_220_to_221 * 17 + ) # # check that inter group is still disabled for the groups # not in the contract. # - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_222 * NUM_PKTS) + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_222 * NUM_PKTS) # # A uni-directional contract from EPG 220 -> 222 'L3 routed' # c3 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 400, + epgs[0].sclass, + epgs[2].sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() self.logger.info(self.vapi.cli("sh gbp contract")) - self.send_and_expect_routed(eps[0].itf, - pkt_inter_epg_220_to_222 * NUM_PKTS, - eps[3].itf, - str(self.router_mac)) + self.send_and_expect_routed( + eps[0].itf, + pkt_inter_epg_220_to_222 * NUM_PKTS, + eps[3].itf, + str(self.router_mac), + ) # # remove both contracts, traffic stops in both directions # @@ -1364,13 +1539,9 @@ class TestGBP(VppTestCase): c3.remove_vpp_config() acl.remove_vpp_config() - self.send_and_assert_no_replies(eps[2].itf, - pkt_inter_epg_221_to_220 * NUM_PKTS) - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_221 * NUM_PKTS) - self.send_and_expect_bridged(eps[0].itf, - pkt_intra_epg * NUM_PKTS, - eps[1].itf) + self.send_and_assert_no_replies(eps[2].itf, pkt_inter_epg_221_to_220 * NUM_PKTS) + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_221 * NUM_PKTS) + self.send_and_expect_bridged(eps[0].itf, pkt_intra_epg * NUM_PKTS, eps[1].itf) # # EPs to the outside world @@ -1378,36 +1549,60 @@ class TestGBP(VppTestCase): # in the EP's RD an external subnet via the NAT EPG's recirc se1 = VppGbpSubnet( - self, rd0, "0.0.0.0", 0, + self, + rd0, + "0.0.0.0", + 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) se2 = VppGbpSubnet( - self, rd0, "11.0.0.0", 8, + self, + rd0, + "11.0.0.0", + 8, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) se16 = VppGbpSubnet( - self, rd0, "::", 0, + self, + rd0, + "::", + 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=recirc_nat.recirc.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) # in the NAT RD an external subnet via the NAT EPG's uplink se3 = VppGbpSubnet( - self, rd20, "0.0.0.0", 0, + self, + rd20, + "0.0.0.0", + 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) se36 = VppGbpSubnet( - self, rd20, "::", 0, + self, + rd20, + "::", + 0, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) se4 = VppGbpSubnet( - self, rd20, "11.0.0.0", 8, + self, + rd20, + "11.0.0.0", + 8, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL, sw_if_index=epg_nat.uplink.sw_if_index, - sclass=epg_nat.sclass) + sclass=epg_nat.sclass, + ) se1.add_vpp_config() se2.add_vpp_config() se16.add_vpp_config() @@ -1418,132 +1613,153 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0")) self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1")) self.logger.info(self.vapi.cli("sh ip6 fib ::/0")) - self.logger.info(self.vapi.cli("sh ip6 fib %s" % - eps[0].fip6)) + self.logger.info(self.vapi.cli("sh ip6 fib %s" % eps[0].fip6)) # # From an EP to an outside address: IN2OUT # - pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst="1.1.1.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_inter_epg_220_to_global = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst="1.1.1.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) # no policy yet - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_global * NUM_PKTS) + self.send_and_assert_no_replies( + eps[0].itf, pkt_inter_epg_220_to_global * NUM_PKTS + ) rule = AclRule(is_permit=1, proto=17, ports=1234) - rule2 = AclRule(is_permit=1, proto=17, ports=1234, - src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0))) + rule2 = AclRule( + is_permit=1, + proto=17, + ports=1234, + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + ) acl2 = VppAcl(self, rules=[rule, rule2]) acl2.add_vpp_config() c4 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[3].sclass, acl2.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 400, + epgs[0].sclass, + epgs[3].sclass, + acl2.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c4.add_vpp_config() - self.send_and_expect_natted(eps[0].itf, - pkt_inter_epg_220_to_global * NUM_PKTS, - self.pg7, - eps[0].fip4) + self.send_and_expect_natted( + eps[0].itf, pkt_inter_epg_220_to_global * NUM_PKTS, self.pg7, eps[0].fip4 + ) - pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6, - dst="6001::1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_inter_epg_220_to_global = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IPv6(src=eps[0].ip6, dst="6001::1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_natted6(self.pg0, - pkt_inter_epg_220_to_global * NUM_PKTS, - self.pg7, - eps[0].fip6) + self.send_and_expect_natted6( + self.pg0, pkt_inter_epg_220_to_global * NUM_PKTS, self.pg7, eps[0].fip6 + ) # # From a global address to an EP: OUT2IN # - pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), - dst=self.pg0.remote_mac) / - IP(dst=eps[0].fip4, - src="1.1.1.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_inter_epg_220_from_global = ( + Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) + / IP(dst=eps[0].fip4, src="1.1.1.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies( - self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS) + self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS + ) c5 = VppGbpContract( - self, 400, epgs[3].sclass, epgs[0].sclass, acl2.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 400, + epgs[3].sclass, + epgs[0].sclass, + acl2.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c5.add_vpp_config() - self.send_and_expect_unnatted(self.pg7, - pkt_inter_epg_220_from_global * NUM_PKTS, - eps[0].itf, - eps[0].ip4) + self.send_and_expect_unnatted( + self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS, eps[0].itf, eps[0].ip4 + ) - pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac), - dst=self.pg0.remote_mac) / - IPv6(dst=eps[0].fip6, - src="6001::1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_inter_epg_220_from_global = ( + Ether(src=str(self.router_mac), dst=self.pg0.remote_mac) + / IPv6(dst=eps[0].fip6, src="6001::1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_expect_unnatted6( - self.pg7, - pkt_inter_epg_220_from_global * NUM_PKTS, - eps[0].itf, - eps[0].ip6) + self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS, eps[0].itf, eps[0].ip6 + ) # # From a local VM to another local VM using resp. public addresses: # IN2OUT2IN # - pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst=eps[1].fip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - - self.send_and_expect_double_natted(eps[0].itf, - pkt_intra_epg_220_global * NUM_PKTS, - eps[1].itf, - eps[0].fip4, - eps[1].ip4) - - pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6, - dst=eps[1].fip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_220_global = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst=eps[1].fip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + + self.send_and_expect_double_natted( + eps[0].itf, + pkt_intra_epg_220_global * NUM_PKTS, + eps[1].itf, + eps[0].fip4, + eps[1].ip4, + ) + + pkt_intra_epg_220_global = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IPv6(src=eps[0].ip6, dst=eps[1].fip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_expect_double_natted6( eps[0].itf, pkt_intra_epg_220_global * NUM_PKTS, eps[1].itf, eps[0].fip6, - eps[1].ip6) + eps[1].ip6, + ) # # cleanup @@ -1551,36 +1767,37 @@ class TestGBP(VppTestCase): self.vapi.nat44_ed_plugin_enable_disable(enable=0) self.vapi.nat66_plugin_enable_disable(enable=0) - def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None, - tep=None, n_tries=100, s_time=1): + def wait_for_ep_timeout( + self, sw_if_index=None, ip=None, mac=None, tep=None, n_tries=100, s_time=1 + ): # only learnt EP can timeout ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t flags = ep_flags.GBP_API_ENDPOINT_FLAG_LEARNT - while (n_tries): - if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, - flags=flags): + while n_tries: + if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, flags=flags): return True n_tries = n_tries - 1 self.sleep(s_time) - self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, - flags=flags)) + self.assertFalse( + find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, flags=flags) + ) return False def test_gbp_learn_l2(self): - """ GBP L2 Endpoint Learning """ + """GBP L2 Endpoint Learning""" drop_no_contract = self.statistics.get_err_counter( - '/err/gbp-policy-port/drop-no-contract') + "/err/gbp-policy-port/drop-no-contract" + ) allow_intra_class = self.statistics.get_err_counter( - '/err/gbp-policy-port/allow-intra-sclass') + "/err/gbp-policy-port/allow-intra-sclass" + ) ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t - learnt = [{'mac': '00:00:11:11:11:01', - 'ip': '10.0.0.1', - 'ip6': '2001:10::2'}, - {'mac': '00:00:11:11:11:02', - 'ip': '10.0.0.2', - 'ip6': '2001:10::3'}] + learnt = [ + {"mac": "00:00:11:11:11:01", "ip": "10.0.0.1", "ip6": "2001:10::2"}, + {"mac": "00:00:11:11:11:02", "ip": "10.0.0.2", "ip6": "2001:10::3"}, + ] # # IP tables @@ -1610,9 +1827,9 @@ class TestGBP(VppTestCase): # # Add a mcast destination VXLAN-GBP tunnel for B&M traffic # - tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4, - "239.1.1.1", 88, - mcast_itf=self.pg4) + tun_bm = VppVxlanGbpTunnel( + self, self.pg4.local_ip4, "239.1.1.1", 88, mcast_itf=self.pg4 + ) tun_bm.add_vpp_config() # @@ -1620,8 +1837,7 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, - self.pg3, tun_bm) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3, tun_bm) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) @@ -1634,17 +1850,31 @@ class TestGBP(VppTestCase): # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1, - None, self.loop0, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(4)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 112, + rd1, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(4), + ) epg_220.add_vpp_config() - epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1, - None, self.loop1, - "10.0.1.128", - "2001:11::128", - VppGbpEndpointRetention(4)) + epg_330 = VppGbpEndpointGroup( + self, + 330, + 113, + rd1, + gbd1, + None, + self.loop1, + "10.0.1.128", + "2001:11::128", + VppGbpEndpointRetention(4), + ) epg_330.add_vpp_config() # @@ -1652,51 +1882,61 @@ class TestGBP(VppTestCase): # learning enabled # vx_tun_l2_1 = VppGbpVxlanTunnel( - self, 99, bd1.bd_id, + self, + 99, + bd1.bd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l2_1.add_vpp_config() # # A static endpoint that the learnt endpoints are trying to # talk to # - ep = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.127", "11.0.0.127", - "2001:10::1", "3001::1") + ep = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.127", + "11.0.0.127", + "2001:10::1", + "3001::1", + ) ep.add_vpp_config() self.assertTrue(find_route(self, ep.ip4, 32, table_id=1)) # a packet with an sclass from an unknown EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[0].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=88, flags=0x88) / - Ether(src=learnt[0]["mac"], dst=ep.mac) / - IP(src=learnt[0]["ip"], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[0].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=88, flags=0x88) + / Ether(src=learnt[0]["mac"], dst=ep.mac) + / IP(src=learnt[0]["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(self.pg2, p) self.logger.info(self.vapi.cli("sh error")) self.assert_error_counter_equal( - '/err/gbp-policy-port/drop-no-contract', - drop_no_contract + 1) + "/err/gbp-policy-port/drop-no-contract", drop_no_contract + 1 + ) # # we should not have learnt a new tunnel endpoint, since # the EPG was not learnt. # - self.assertEqual(INDEX_INVALID, - find_vxlan_gbp_tunnel(self, - self.pg2.local_ip4, - self.pg2.remote_hosts[0].ip4, - 99)) + self.assertEqual( + INDEX_INVALID, + find_vxlan_gbp_tunnel( + self, self.pg2.local_ip4, self.pg2.remote_hosts[0].ip4, 99 + ), + ) # ep is not learnt, because the EPG is unknown self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1) @@ -1707,41 +1947,39 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=112, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=112, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - 99) + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, 99 + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) # # the EP is learnt via the learnt TEP # both from its MAC and its IP # - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - ip=l['ip'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, ip=l["ip"]) + ) self.assert_error_counter_equal( - '/err/gbp-policy-port/allow-intra-sclass', - allow_intra_class + 2) + "/err/gbp-policy-port/allow-intra-sclass", allow_intra_class + 2 + ) self.logger.info(self.vapi.cli("show gbp endpoint")) self.logger.info(self.vapi.cli("show gbp vxlan")) @@ -1752,8 +1990,7 @@ class TestGBP(VppTestCase): # age out # for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) # # Learn new EPs from GARP packets received on the BD's mcast tunnel @@ -1762,44 +1999,45 @@ class TestGBP(VppTestCase): # add some junk in the reserved field of the vxlan-header # next to the VNI. we should accept since reserved bits are # ignored on rx. - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst="239.1.1.1") / - UDP(sport=1234, dport=48879) / - VXLAN(vni=88, reserved2=0x80, gpid=112, flags=0x88) / - Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") / - ARP(op="who-has", - psrc=l['ip'], pdst=l['ip'], - hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff")) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst="239.1.1.1") + / UDP(sport=1234, dport=48879) + / VXLAN(vni=88, reserved2=0x80, gpid=112, flags=0x88) + / Ether(src=l["mac"], dst="ff:ff:ff:ff:ff:ff") + / ARP( + op="who-has", + psrc=l["ip"], + pdst=l["ip"], + hwsrc=l["mac"], + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) rx = self.send_and_expect(self.pg4, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - 99) + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, 99 + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) # # the EP is learnt via the learnt TEP # both from its MAC and its IP # - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - ip=l['ip'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, ip=l["ip"]) + ) # # wait for the learnt endpoints to age out # for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) # # Learn new EPs from L2 packets @@ -1807,32 +2045,30 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=112, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=112, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - 99) + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, 99 + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) # # the EP is learnt via the learnt TEP # both from its MAC and its IP # - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) self.logger.info(self.vapi.cli("show gbp endpoint")) self.logger.info(self.vapi.cli("show gbp vxlan")) @@ -1842,31 +2078,30 @@ class TestGBP(VppTestCase): # wait for the learnt endpoints to age out # for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) # # repeat. the do not learn bit is set so the EPs are not learnt # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.assertFalse( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) # # repeat @@ -1875,32 +2110,34 @@ class TestGBP(VppTestCase): # a packet with an sclass from a known EPG # set a reserved bit in addition to the G and I # reserved bits should not be checked on rx. - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=112, flags=0xc8) / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=112, flags=0xC8) + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) # # Static EP replies to dynamics # self.logger.info(self.vapi.cli("sh l2fib bd_id 1")) for l in learnt: - p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=l['ip'], src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / IP(dst=l["ip"], src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 17, self.pg2) @@ -1917,8 +2154,7 @@ class TestGBP(VppTestCase): self.assertFalse(rx[VXLAN].gpflags.D) for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) # # repeat in the other EPG @@ -1927,31 +2163,33 @@ class TestGBP(VppTestCase): # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=113, flags=0x88, gpflags="A") + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) # # static EP cannot reach the learnt EPs since there is no contract # only test 1 EP as the others could timeout # - p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=learnt[0]['ip'], src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / IP(dst=learnt[0]["ip"], src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(self.pg0, [p]) @@ -1960,50 +2198,65 @@ class TestGBP(VppTestCase): # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=113, flags=0x88, gpflags="A") + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) # # Add the contract so they can talk # rule = AclRule(is_permit=1, proto=17) - rule2 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule2 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule, rule2]) acl.add_vpp_config() c1 = VppGbpContract( - self, 401, epg_220.sclass, epg_330.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 401, + epg_220.sclass, + epg_330.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() for l in learnt: - p = (Ether(src=ep.mac, dst=l['mac']) / - IP(dst=l['ip'], src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / IP(dst=l["ip"], src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_expect(self.pg0, [p], self.pg2) @@ -2012,18 +2265,22 @@ class TestGBP(VppTestCase): # self.logger.info(self.vapi.cli("sh gbp bridge")) self.logger.info(self.vapi.cli("sh bridge-domain 1 detail")) - p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") / - IP(dst="10.0.0.133", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p_uu = ( + Ether(src=ep.mac, dst="00:11:11:11:11:11") + / IP(dst="10.0.0.133", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd) self.logger.info(self.vapi.cli("sh bridge 1 detail")) - p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / - IP(dst="10.0.0.133", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p_bm = ( + Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") + / IP(dst="10.0.0.133", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf) for rx in rxs: @@ -2039,52 +2296,66 @@ class TestGBP(VppTestCase): self.assertFalse(rx[VXLAN].gpflags.D) rule = AclRule(is_permit=1, proto=17) - rule2 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule2 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule, rule2]) acl.add_vpp_config() c2 = VppGbpContract( - self, 401, epg_330.sclass, epg_220.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 401, + epg_330.sclass, + epg_220.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) # # Check v6 Endpoints learning # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=113, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - IPv6(src=l['ip6'], dst=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=113, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / IPv6(src=l["ip6"], dst=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint( - self, - vx_tun_l2_1.sw_if_index, - ip=l['ip6'], - tep=[self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4])) + self.assertTrue( + find_gbp_endpoint( + self, + vx_tun_l2_1.sw_if_index, + ip=l["ip6"], + tep=[self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4], + ) + ) self.logger.info(self.vapi.cli("sh int")) self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel")) @@ -2097,36 +2368,40 @@ class TestGBP(VppTestCase): # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[2].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=113, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - IPv6(src=l['ip6'], dst=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[2].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=113, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / IPv6(src=l["ip6"], dst=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * 1, self.pg0) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint( - self, - vx_tun_l2_1.sw_if_index, - sclass=113, - mac=l['mac'], - tep=[self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4])) + self.assertTrue( + find_gbp_endpoint( + self, + vx_tun_l2_1.sw_if_index, + sclass=113, + mac=l["mac"], + tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4], + ) + ) # # v6 remote EP reachability # for l in learnt: - p = (Ether(src=ep.mac, dst=l['mac']) / - IPv6(dst=l['ip6'], src=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / IPv6(dst=l["ip6"], src=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -2141,46 +2416,51 @@ class TestGBP(VppTestCase): self.assertTrue(rx[VXLAN].flags.Instance) self.assertTrue(rx[VXLAN].gpflags.A) self.assertFalse(rx[VXLAN].gpflags.D) - self.assertEqual(rx[IPv6].dst, l['ip6']) + self.assertEqual(rx[IPv6].dst, l["ip6"]) # # EP changes sclass # for l in learnt: # a packet with an sclass from a known EPG - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[2].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=112, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - IPv6(src=l['ip6'], dst=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[2].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=112, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / IPv6(src=l["ip6"], dst=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, p * 1, self.pg0) rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint( - self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'], - sclass=112, - tep=[self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4])) + self.assertTrue( + find_gbp_endpoint( + self, + vx_tun_l2_1.sw_if_index, + mac=l["mac"], + sclass=112, + tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4], + ) + ) # # check reachability and contract intra-epg # allow_intra_class = self.statistics.get_err_counter( - '/err/gbp-policy-mac/allow-intra-sclass') + "/err/gbp-policy-mac/allow-intra-sclass" + ) for l in learnt: - p = (Ether(src=ep.mac, dst=l['mac']) / - IPv6(dst=l['ip6'], src=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / IPv6(dst=l["ip6"], src=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -2194,26 +2474,25 @@ class TestGBP(VppTestCase): self.assertTrue(rx[VXLAN].flags.Instance) self.assertTrue(rx[VXLAN].gpflags.A) self.assertFalse(rx[VXLAN].gpflags.D) - self.assertEqual(rx[IPv6].dst, l['ip6']) + self.assertEqual(rx[IPv6].dst, l["ip6"]) allow_intra_class += NUM_PKTS self.assert_error_counter_equal( - '/err/gbp-policy-mac/allow-intra-sclass', - allow_intra_class) + "/err/gbp-policy-mac/allow-intra-sclass", allow_intra_class + ) # # clean up # for l in learnt: - self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, - mac=l['mac']) + self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index, mac=l["mac"]) self.pg2.unconfig_ip4() self.pg3.unconfig_ip4() self.pg4.unconfig_ip4() def test_gbp_contract(self): - """ GBP Contracts """ + """GBP Contracts""" # # Route Domains @@ -2245,34 +2524,86 @@ class TestGBP(VppTestCase): # # 3 EPGs, 2 of which share a BD. # - epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1, - None, self.loop0, - "10.0.0.128", "2001:10::128"), - VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1, - None, self.loop0, - "10.0.1.128", "2001:10:1::128"), - VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2, - None, self.loop1, - "10.0.2.128", "2001:10:2::128")] + epgs = [ + VppGbpEndpointGroup( + self, + 220, + 1220, + rd0, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + ), + VppGbpEndpointGroup( + self, + 221, + 1221, + rd0, + gbd1, + None, + self.loop0, + "10.0.1.128", + "2001:10:1::128", + ), + VppGbpEndpointGroup( + self, + 222, + 1222, + rd0, + gbd2, + None, + self.loop1, + "10.0.2.128", + "2001:10:2::128", + ), + ] # # 4 end-points, 2 in the same subnet, 3 in the same BD # - eps = [VppGbpEndpoint(self, self.pg0, - epgs[0], None, - "10.0.0.1", "11.0.0.1", - "2001:10::1", "3001::1"), - VppGbpEndpoint(self, self.pg1, - epgs[0], None, - "10.0.0.2", "11.0.0.2", - "2001:10::2", "3001::2"), - VppGbpEndpoint(self, self.pg2, - epgs[1], None, - "10.0.1.1", "11.0.0.3", - "2001:10:1::1", "3001::3"), - VppGbpEndpoint(self, self.pg3, - epgs[2], None, - "10.0.2.1", "11.0.0.4", - "2001:10:2::1", "3001::4")] + eps = [ + VppGbpEndpoint( + self, + self.pg0, + epgs[0], + None, + "10.0.0.1", + "11.0.0.1", + "2001:10::1", + "3001::1", + ), + VppGbpEndpoint( + self, + self.pg1, + epgs[0], + None, + "10.0.0.2", + "11.0.0.2", + "2001:10::2", + "3001::2", + ), + VppGbpEndpoint( + self, + self.pg2, + epgs[1], + None, + "10.0.1.1", + "11.0.0.3", + "2001:10:1::1", + "3001::3", + ), + VppGbpEndpoint( + self, + self.pg3, + epgs[2], + None, + "10.0.2.1", + "11.0.0.4", + "2001:10:2::1", + "3001::4", + ), + ] # # Config related to each of the EPGs @@ -2280,23 +2611,21 @@ class TestGBP(VppTestCase): for epg in epgs: # IP config on the BVI interfaces if epg != epgs[1]: - b4 = VppIpInterfaceBind(self, epg.bvi, - epg.rd.t4).add_vpp_config() - b6 = VppIpInterfaceBind(self, epg.bvi, - epg.rd.t6).add_vpp_config() + b4 = VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config() + b6 = VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config() epg.bvi.set_mac(self.router_mac) - if_ip4 = VppIpInterfaceAddress(self, epg.bvi, - epg.bvi_ip4, 32, - bind=b4).add_vpp_config() - if_ip6 = VppIpInterfaceAddress(self, epg.bvi, - epg.bvi_ip6, 128, - bind=b6).add_vpp_config() + if_ip4 = VppIpInterfaceAddress( + self, epg.bvi, epg.bvi_ip4, 32, bind=b4 + ).add_vpp_config() + if_ip6 = VppIpInterfaceAddress( + self, epg.bvi, epg.bvi_ip6, 128, bind=b6 + ).add_vpp_config() # add the BD ARP termination entry for BVI IP - epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd, - str(self.router_mac), - epg.bvi_ip4) + epg.bd_arp_ip4 = VppBridgeDomainArpEntry( + self, epg.bd.bd, str(self.router_mac), epg.bvi_ip4 + ) epg.bd_arp_ip4.add_vpp_config() # EPG in VPP @@ -2315,37 +2644,33 @@ class TestGBP(VppTestCase): # # Intra epg allowed without contract # - pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac, - dst=self.pg1.remote_mac) / - IP(src=eps[0].ip4, - dst=eps[1].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_220_to_220 = ( + Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) + / IP(src=eps[0].ip4, dst=eps[1].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged(self.pg0, - pkt_intra_epg_220_to_220 * 65, - self.pg1) + self.send_and_expect_bridged(self.pg0, pkt_intra_epg_220_to_220 * 65, self.pg1) - pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac, - dst=self.pg1.remote_mac) / - IPv6(src=eps[0].ip6, - dst=eps[1].ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_intra_epg_220_to_220 = ( + Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) + / IPv6(src=eps[0].ip6, dst=eps[1].ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) - self.send_and_expect_bridged6(self.pg0, - pkt_intra_epg_220_to_220 * 65, - self.pg1) + self.send_and_expect_bridged6(self.pg0, pkt_intra_epg_220_to_220 * 65, self.pg1) # # Inter epg denied without contract # - pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac, - dst=self.pg2.remote_mac) / - IP(src=eps[0].ip4, - dst=eps[2].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + pkt_inter_epg_220_to_221 = ( + Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) + / IP(src=eps[0].ip4, dst=eps[2].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221) @@ -2353,58 +2678,71 @@ class TestGBP(VppTestCase): # A uni-directional contract from EPG 220 -> 221 # rule = AclRule(is_permit=1, proto=17) - rule2 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule2 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) rule3 = AclRule(is_permit=1, proto=1) acl = VppAcl(self, rules=[rule, rule2, rule3]) acl.add_vpp_config() c1 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 400, + epgs[0].sclass, + epgs[1].sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() - self.send_and_expect_bridged(eps[0].itf, - pkt_inter_epg_220_to_221 * 65, - eps[2].itf) + self.send_and_expect_bridged( + eps[0].itf, pkt_inter_epg_220_to_221 * 65, eps[2].itf + ) - pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst=eps[3].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - self.send_and_assert_no_replies(eps[0].itf, - pkt_inter_epg_220_to_222 * 65) + pkt_inter_epg_220_to_222 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst=eps[3].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_assert_no_replies(eps[0].itf, pkt_inter_epg_220_to_222 * 65) # # ping router IP in different BD # - pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[0].ip4, - dst=epgs[1].bvi_ip4) / - ICMP(type='echo-request')) + pkt_router_ping_220_to_221 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[0].ip4, dst=epgs[1].bvi_ip4) + / ICMP(type="echo-request") + ) self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0) - pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac, - dst=str(self.router_mac)) / - IPv6(src=eps[0].ip6, - dst=epgs[1].bvi_ip6) / - ICMPv6EchoRequest()) + pkt_router_ping_220_to_221 = ( + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IPv6(src=eps[0].ip6, dst=epgs[1].bvi_ip6) + / ICMPv6EchoRequest() + ) self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0) @@ -2412,70 +2750,84 @@ class TestGBP(VppTestCase): # contract for the return direction # c2 = VppGbpContract( - self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 400, + epgs[1].sclass, + epgs[0].sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() - self.send_and_expect_bridged(eps[0].itf, - pkt_inter_epg_220_to_221 * 65, - eps[2].itf) - pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, - dst=self.pg0.remote_mac) / - IP(src=eps[2].ip4, - dst=eps[0].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - self.send_and_expect_bridged(eps[2].itf, - pkt_inter_epg_221_to_220 * 65, - eps[0].itf) - pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, - dst=str(self.router_mac)) / - IP(src=eps[2].ip4, - dst=eps[0].ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - self.send_and_expect_routed(eps[2].itf, - pkt_inter_epg_221_to_220 * 65, - eps[0].itf, - str(self.router_mac)) - pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac, - dst=str(self.router_mac)) / - IPv6(src=eps[2].ip6, - dst=eps[0].ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - self.send_and_expect_routed6(eps[2].itf, - pkt_inter_epg_221_to_220 * 65, - eps[0].itf, - str(self.router_mac)) + self.send_and_expect_bridged( + eps[0].itf, pkt_inter_epg_220_to_221 * 65, eps[2].itf + ) + pkt_inter_epg_221_to_220 = ( + Ether(src=self.pg2.remote_mac, dst=self.pg0.remote_mac) + / IP(src=eps[2].ip4, dst=eps[0].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect_bridged( + eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf + ) + pkt_inter_epg_221_to_220 = ( + Ether(src=self.pg2.remote_mac, dst=str(self.router_mac)) + / IP(src=eps[2].ip4, dst=eps[0].ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect_routed( + eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf, str(self.router_mac) + ) + pkt_inter_epg_221_to_220 = ( + Ether(src=self.pg2.remote_mac, dst=str(self.router_mac)) + / IPv6(src=eps[2].ip6, dst=eps[0].ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + self.send_and_expect_routed6( + eps[2].itf, pkt_inter_epg_221_to_220 * 65, eps[0].itf, str(self.router_mac) + ) # # contract between 220 and 222 uni-direction # c3 = VppGbpContract( - self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 400, + epgs[0].sclass, + epgs[2].sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() - self.send_and_expect(eps[0].itf, - pkt_inter_epg_220_to_222 * 65, - eps[3].itf) + self.send_and_expect(eps[0].itf, pkt_inter_epg_220_to_222 * 65, eps[3].itf) c3.remove_vpp_config() c1.remove_vpp_config() @@ -2483,7 +2835,7 @@ class TestGBP(VppTestCase): acl.remove_vpp_config() def test_gbp_bd_drop_flags(self): - """ GBP BD drop flags """ + """GBP BD drop flags""" # # IP tables @@ -2502,32 +2854,46 @@ class TestGBP(VppTestCase): bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, - None, None, - uu_drop=True, bm_drop=True) + gbd1 = VppGbpBridgeDomain( + self, bd1, rd1, self.loop0, None, None, uu_drop=True, bm_drop=True + ) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.logger.info(self.vapi.cli("sh gbp bridge")) # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32).add_vpp_config() + ip_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32 + ).add_vpp_config() # # The Endpoint-group # - epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1, - None, self.loop0, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(3)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 112, + rd1, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(3), + ) epg_220.add_vpp_config() - ep = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.127", "11.0.0.127", - "2001:10::1", "3001::1") + ep = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.127", + "11.0.0.127", + "2001:10::1", + "3001::1", + ) ep.add_vpp_config() # @@ -2536,16 +2902,20 @@ class TestGBP(VppTestCase): # self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.logger.info(self.vapi.cli("sh gbp bridge")) - p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") / - IP(dst="10.0.0.133", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p_uu = ( + Ether(src=ep.mac, dst="00:11:11:11:11:11") + / IP(dst="10.0.0.133", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(ep.itf, [p_uu]) - p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / - IP(dst="10.0.0.133", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p_bm = ( + Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") + / IP(dst="10.0.0.133", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(ep.itf, [p_bm]) self.pg3.unconfig_ip4() @@ -2553,7 +2923,7 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh int")) def test_gbp_bd_arp_flags(self): - """ GBP BD arp flags """ + """GBP BD arp flags""" # # IP tables @@ -2575,9 +2945,9 @@ class TestGBP(VppTestCase): # # Add a mcast destination VXLAN-GBP tunnel for B&M traffic # - tun_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4, - "239.1.1.1", 88, - mcast_itf=self.pg4) + tun_uu = VppVxlanGbpTunnel( + self, self.pg4.local_ip4, "239.1.1.1", 88, mcast_itf=self.pg4 + ) tun_uu.add_vpp_config() # @@ -2586,29 +2956,43 @@ class TestGBP(VppTestCase): bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, - tun_uu, None, - ucast_arp=True) + gbd1 = VppGbpBridgeDomain( + self, bd1, rd1, self.loop0, tun_uu, None, ucast_arp=True + ) gbd1.add_vpp_config() # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32).add_vpp_config() + ip_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32 + ).add_vpp_config() # # The Endpoint-group # - epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1, - None, self.loop0, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(2)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 112, + rd1, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(2), + ) epg_220.add_vpp_config() - ep = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.127", "11.0.0.127", - "2001:10::1", "3001::1") + ep = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.127", + "11.0.0.127", + "2001:10::1", + "3001::1", + ) ep.add_vpp_config() # @@ -2616,25 +3000,25 @@ class TestGBP(VppTestCase): # self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.logger.info(self.vapi.cli("sh gbp bridge")) - p_arp = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / - ARP(op="who-has", - psrc=ep.ip4, pdst="10.0.0.99", - hwsrc=ep.mac, - hwdst="ff:ff:ff:ff:ff:ff")) + p_arp = Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") / ARP( + op="who-has", + psrc=ep.ip4, + pdst="10.0.0.99", + hwsrc=ep.mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) self.send_and_expect(ep.itf, [p_arp], self.pg4) self.pg4.unconfig_ip4() def test_gbp_learn_vlan_l2(self): - """ GBP L2 Endpoint w/ VLANs""" + """GBP L2 Endpoint w/ VLANs""" ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t - learnt = [{'mac': '00:00:11:11:11:01', - 'ip': '10.0.0.1', - 'ip6': '2001:10::2'}, - {'mac': '00:00:11:11:11:02', - 'ip': '10.0.0.2', - 'ip6': '2001:10::3'}] + learnt = [ + {"mac": "00:00:11:11:11:01", "ip": "10.0.0.1", "ip6": "2001:10::2"}, + {"mac": "00:00:11:11:11:02", "ip": "10.0.0.2", "ip6": "2001:10::3"}, + ] # # IP tables @@ -2663,11 +3047,12 @@ class TestGBP(VppTestCase): vlan_11 = VppDot1QSubint(self, self.pg0, 11) vlan_11.admin_up() self.vapi.l2_interface_vlan_tag_rewrite( - sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, - push_dot1q=11) + sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1, push_dot1q=11 + ) - bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4, - self.pg3.remote_ip4, 116) + bd_uu_fwd = VppVxlanGbpTunnel( + self, self.pg3.local_ip4, self.pg3.remote_ip4, 116 + ) bd_uu_fwd.add_vpp_config() # @@ -2677,25 +3062,32 @@ class TestGBP(VppTestCase): # bd1 = VppBridgeDomain(self, 1) bd1.add_vpp_config() - gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd, - learn=False) + gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd, learn=False) gbd1.add_vpp_config() self.logger.info(self.vapi.cli("sh bridge 1 detail")) self.logger.info(self.vapi.cli("sh gbp bridge")) # ... and has a /32 applied - ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32).add_vpp_config() + ip_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32 + ).add_vpp_config() # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1, - None, self.loop0, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(4)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 441, + rd1, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(4), + ) epg_220.add_vpp_config() # @@ -2703,19 +3095,28 @@ class TestGBP(VppTestCase): # learning enabled # vx_tun_l2_1 = VppGbpVxlanTunnel( - self, 99, bd1.bd_id, + self, + 99, + bd1.bd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l2_1.add_vpp_config() # # A static endpoint that the learnt endpoints are trying to # talk to # - ep = VppGbpEndpoint(self, vlan_11, - epg_220, None, - "10.0.0.127", "11.0.0.127", - "2001:10::1", "3001::1") + ep = VppGbpEndpoint( + self, + vlan_11, + epg_220, + None, + "10.0.0.127", + "11.0.0.127", + "2001:10::1", + "3001::1", + ) ep.add_vpp_config() self.assertTrue(find_route(self, ep.ip4, 32, table_id=1)) @@ -2726,16 +3127,16 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=99, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst=ep.mac) / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=99, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst=ep.mac) + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg2, [p], self.pg0) @@ -2749,15 +3150,15 @@ class TestGBP(VppTestCase): # the EP is not learnt since the BD setting prevents it # also no TEP too # - self.assertFalse(find_gbp_endpoint(self, - vx_tun_l2_1.sw_if_index, - mac=l['mac'])) - self.assertEqual(INDEX_INVALID, - find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - 99)) + self.assertFalse( + find_gbp_endpoint(self, vx_tun_l2_1.sw_if_index, mac=l["mac"]) + ) + self.assertEqual( + INDEX_INVALID, + find_vxlan_gbp_tunnel( + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, 99 + ), + ) self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1) @@ -2766,11 +3167,13 @@ class TestGBP(VppTestCase): # we didn't learn the remotes so they are sent to the UU-fwd # for l in learnt: - p = (Ether(src=ep.mac, dst=l['mac']) / - Dot1Q(vlan=11) / - IP(dst=l['ip'], src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=l["mac"]) + / Dot1Q(vlan=11) + / IP(dst=l["ip"], src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 17, self.pg3) @@ -2790,7 +3193,7 @@ class TestGBP(VppTestCase): self.pg3.unconfig_ip4() def test_gbp_learn_l3(self): - """ GBP L3 Endpoint Learning """ + """GBP L3 Endpoint Learning""" self.vapi.cli("set logging class gbp level debug") @@ -2798,12 +3201,10 @@ class TestGBP(VppTestCase): routed_dst_mac = "00:0c:0c:0c:0c:0c" routed_src_mac = "00:22:bd:f8:19:ff" - learnt = [{'mac': '00:00:11:11:11:02', - 'ip': '10.0.1.2', - 'ip6': '2001:10::2'}, - {'mac': '00:00:11:11:11:03', - 'ip': '10.0.1.3', - 'ip6': '2001:10::3'}] + learnt = [ + {"mac": "00:00:11:11:11:02", "ip": "10.0.1.2", "ip6": "2001:10::2"}, + {"mac": "00:00:11:11:11:03", "ip": "10.0.1.3", "ip6": "2001:10::3"}, + ] # # IP tables @@ -2813,10 +3214,12 @@ class TestGBP(VppTestCase): t6 = VppIpTable(self, 1, True) t6.add_vpp_config() - tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4, - self.pg4.remote_ip4, 114) - tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4, - self.pg4.remote_ip4, 116) + tun_ip4_uu = VppVxlanGbpTunnel( + self, self.pg4.local_ip4, self.pg4.remote_ip4, 114 + ) + tun_ip6_uu = VppVxlanGbpTunnel( + self, self.pg4.local_ip4, self.pg4.remote_ip4, 116 + ) tun_ip4_uu.add_vpp_config() tun_ip6_uu.add_vpp_config() @@ -2859,40 +3262,56 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("sh gbp route")) # ... and has a /32 and /128 applied - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32, - bind=b4).add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "2001:10::128", 128, - bind=b6).add_vpp_config() + ip4_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32, bind=b4 + ).add_vpp_config() + ip6_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "2001:10::128", 128, bind=b6 + ).add_vpp_config() # # The Endpoint-group in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1, - None, self.loop0, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(4)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 441, + rd1, + gbd1, + None, + self.loop0, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(4), + ) epg_220.add_vpp_config() # # The VXLAN GBP tunnel is in L3 mode with learning enabled # vx_tun_l3 = VppGbpVxlanTunnel( - self, 101, rd1.rd_id, + self, + 101, + rd1.rd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l3.add_vpp_config() # # A static endpoint that the learnt endpoints are trying to # talk to # - ep = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.127", "11.0.0.127", - "2001:10::1", "3001::1") + ep = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.127", + "11.0.0.127", + "2001:10::1", + "3001::1", + ) ep.add_vpp_config() # @@ -2901,40 +3320,38 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=101, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst="00:00:00:11:11:11") + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - vx_tun_l3.vni) + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, vx_tun_l3.vni + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip=l['ip'])) + self.assertTrue(find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip=l["ip"])) # # Static IPv4 EP replies to learnt # for l in learnt: - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=l['ip'], src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst=l["ip"], src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg2) @@ -2955,12 +3372,10 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, routed_dst_mac) self.assertEqual(inner[IP].src, ep.ip4) - self.assertEqual(inner[IP].dst, l['ip']) + self.assertEqual(inner[IP].dst, l["ip"]) for l in learnt: - self.assertFalse(find_gbp_endpoint(self, - tep1_sw_if_index, - ip=l['ip'])) + self.assertFalse(find_gbp_endpoint(self, tep1_sw_if_index, ip=l["ip"])) # # learn some remote IPv6 EPs @@ -2968,25 +3383,23 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IPv6(src=l['ip6'], dst=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=101, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst="00:00:00:11:11:11") + / IPv6(src=l["ip6"], dst=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - vx_tun_l3.vni) + self, self.pg2.local_ip4, self.pg2.remote_hosts[1].ip4, vx_tun_l3.vni + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) self.logger.info(self.vapi.cli("show gbp bridge")) @@ -2995,19 +3408,21 @@ class TestGBP(VppTestCase): self.logger.info(self.vapi.cli("show int addr")) # endpoint learnt via the TEP - self.assertTrue(find_gbp_endpoint(self, ip=l['ip6'])) + self.assertTrue(find_gbp_endpoint(self, ip=l["ip6"])) self.logger.info(self.vapi.cli("show gbp endpoint")) - self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip'])) + self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l["ip"])) # # Static EP replies to learnt # for l in learnt: - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IPv6(dst=l['ip6'], src=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IPv6(dst=l["ip6"], src=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -3028,19 +3443,21 @@ class TestGBP(VppTestCase): self.assertEqual(inner[Ether].src, routed_src_mac) self.assertEqual(inner[Ether].dst, routed_dst_mac) self.assertEqual(inner[IPv6].src, ep.ip6) - self.assertEqual(inner[IPv6].dst, l['ip6']) + self.assertEqual(inner[IPv6].dst, l["ip6"]) self.logger.info(self.vapi.cli("sh gbp endpoint")) for l in learnt: - self.wait_for_ep_timeout(ip=l['ip']) + self.wait_for_ep_timeout(ip=l["ip"]) # # Static sends to unknown EP with no route # - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.0.99", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst="10.0.0.99", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_assert_no_replies(self.pg0, [p]) @@ -3048,34 +3465,44 @@ class TestGBP(VppTestCase): # Add a route to static EP's v4 and v6 subnet # se_10_24 = VppGbpSubnet( - self, rd1, "10.0.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT) + self, + rd1, + "10.0.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT, + ) se_10_24.add_vpp_config() # # static pings router # - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=epg_220.bvi_ip4, src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst=epg_220.bvi_ip4, src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0) - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IPv6(dst=epg_220.bvi_ip6, src=ep.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IPv6(dst=epg_220.bvi_ip6, src=ep.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0) # # packets to address in the subnet are sent on the uu-fwd # - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.0.99", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst="10.0.0.99", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, [p], self.pg4) for rx in rxs: @@ -3097,43 +3524,45 @@ class TestGBP(VppTestCase): for ii, l in enumerate(learnt): # a packet with an sclass from a known EPG # arriving on an unknown TEP - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[2].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=l['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[2].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=101, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst="00:00:00:11:11:11") + / IP(src=l["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # the new TEP tep1_sw_if_index = find_vxlan_gbp_tunnel( - self, - self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4, - vx_tun_l3.vni) + self, self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4, vx_tun_l3.vni + ) self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip=l['ip'])) + self.assertTrue(find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip=l["ip"])) # # Add a remote endpoint from the API # - rep_88 = VppGbpEndpoint(self, vx_tun_l3, - epg_220, None, - "10.0.0.88", "11.0.0.88", - "2001:10::88", "3001::88", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4, - mac=None) + rep_88 = VppGbpEndpoint( + self, + vx_tun_l3, + epg_220, + None, + "10.0.0.88", + "11.0.0.88", + "2001:10::88", + "3001::88", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg2.local_ip4, + self.pg2.remote_hosts[2].ip4, + mac=None, + ) rep_88.add_vpp_config() # @@ -3141,14 +3570,20 @@ class TestGBP(VppTestCase): # this is a lower priority, hence the packet is sent to the DP leanrt # TEP # - rep_2 = VppGbpEndpoint(self, vx_tun_l3, - epg_220, None, - learnt[0]['ip'], "11.0.0.101", - learnt[0]['ip6'], "3001::101", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - mac=None) + rep_2 = VppGbpEndpoint( + self, + vx_tun_l3, + epg_220, + None, + learnt[0]["ip"], + "11.0.0.101", + learnt[0]["ip6"], + "3001::101", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg2.local_ip4, + self.pg2.remote_hosts[1].ip4, + mac=None, + ) rep_2.add_vpp_config() # @@ -3156,18 +3591,24 @@ class TestGBP(VppTestCase): # packets should be send on the v4/v6 uu=fwd interface resp. # se_10_1_24 = VppGbpSubnet( - self, rd1, "10.0.1.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT) + self, + rd1, + "10.0.1.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT, + ) se_10_1_24.add_vpp_config() self.logger.info(self.vapi.cli("show gbp endpoint")) - ips = ["10.0.0.88", learnt[0]['ip']] + ips = ["10.0.0.88", learnt[0]["ip"]] for ip in ips: - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst=ip, src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst=ip, src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -3199,18 +3640,22 @@ class TestGBP(VppTestCase): self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4)) - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4, dst=rep_2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(src=ep.ip4, dst=rep_2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, [p], self.pg2) self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4)) - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(src=ep.ip4, dst=rep_88.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(src=ep.ip4, dst=rep_88.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, [p], self.pg4) # @@ -3225,38 +3670,49 @@ class TestGBP(VppTestCase): # Same as above, learn a remote EP via CP and DP # this time remove the DP one first. expect the CP data to remain # - rep_3 = VppGbpEndpoint(self, vx_tun_l3, - epg_220, None, - "10.0.1.4", "11.0.0.103", - "2001::10:3", "3001::103", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg2.local_ip4, - self.pg2.remote_hosts[1].ip4, - mac=None) + rep_3 = VppGbpEndpoint( + self, + vx_tun_l3, + epg_220, + None, + "10.0.1.4", + "11.0.0.103", + "2001::10:3", + "3001::103", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg2.local_ip4, + self.pg2.remote_hosts[1].ip4, + mac=None, + ) rep_3.add_vpp_config() - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[2].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src="10.0.1.4", dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[2].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=101, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst="00:00:00:11:11:11") + / IP(src="10.0.1.4", dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip=rep_3.ip4, - tep=[self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4])) + self.assertTrue( + find_gbp_endpoint( + self, + vx_tun_l3._sw_if_index, + ip=rep_3.ip4, + tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4], + ) + ) - p = (Ether(src=ep.mac, dst=self.loop0.local_mac) / - IP(dst="10.0.1.4", src=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=ep.mac, dst=self.loop0.local_mac) + / IP(dst="10.0.1.4", src=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) # host 2 is the DP learned TEP @@ -3264,9 +3720,9 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].src, self.pg2.local_ip4) self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4) - self.wait_for_ep_timeout(ip=rep_3.ip4, - tep=[self.pg2.local_ip4, - self.pg2.remote_hosts[2].ip4]) + self.wait_for_ep_timeout( + ip=rep_3.ip4, tep=[self.pg2.local_ip4, self.pg2.remote_hosts[2].ip4] + ) rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2) @@ -3278,23 +3734,21 @@ class TestGBP(VppTestCase): # # shutdown with learnt endpoint present # - p = (Ether(src=self.pg2.remote_mac, - dst=self.pg2.local_mac) / - IP(src=self.pg2.remote_hosts[1].ip4, - dst=self.pg2.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=101, gpid=441, flags=0x88) / - Ether(src=l['mac'], dst="00:00:00:11:11:11") / - IP(src=learnt[1]['ip'], dst=ep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) + / IP(src=self.pg2.remote_hosts[1].ip4, dst=self.pg2.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=101, gpid=441, flags=0x88) + / Ether(src=l["mac"], dst="00:00:00:11:11:11") + / IP(src=learnt[1]["ip"], dst=ep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rx = self.send_and_expect(self.pg2, [p], self.pg0) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip=l['ip'])) + self.assertTrue(find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip=l["ip"])) # # TODO @@ -3305,7 +3759,7 @@ class TestGBP(VppTestCase): self.pg4.unconfig_ip4() def test_gbp_redirect(self): - """ GBP Endpoint Redirect """ + """GBP Endpoint Redirect""" self.vapi.cli("set logging class gbp level debug") @@ -3313,12 +3767,10 @@ class TestGBP(VppTestCase): routed_dst_mac = "00:0c:0c:0c:0c:0c" routed_src_mac = "00:22:bd:f8:19:ff" - learnt = [{'mac': '00:00:11:11:11:02', - 'ip': '10.0.1.2', - 'ip6': '2001:10::2'}, - {'mac': '00:00:11:11:11:03', - 'ip': '10.0.1.3', - 'ip6': '2001:10::3'}] + learnt = [ + {"mac": "00:00:11:11:11:02", "ip": "10.0.1.2", "ip6": "2001:10::2"}, + {"mac": "00:00:11:11:11:03", "ip": "10.0.1.3", "ip6": "2001:10::3"}, + ] # # IP tables @@ -3359,139 +3811,226 @@ class TestGBP(VppTestCase): gbd2.add_vpp_config() # ... and has a /32 and /128 applied - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32, - bind=b_ip4).add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "2001:10::128", 128, - bind=b_ip6).add_vpp_config() - ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, - "10.0.1.128", 32).add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, - "2001:11::128", 128).add_vpp_config() + ip4_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32, bind=b_ip4 + ).add_vpp_config() + ip6_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "2001:10::128", 128, bind=b_ip6 + ).add_vpp_config() + ip4_addr = VppIpInterfaceAddress( + self, gbd2.bvi, "10.0.1.128", 32 + ).add_vpp_config() + ip6_addr = VppIpInterfaceAddress( + self, gbd2.bvi, "2001:11::128", 128 + ).add_vpp_config() # # The Endpoint-groups in which we are learning endpoints # - epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1, - None, gbd1.bvi, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(60)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 440, + rd1, + gbd1, + None, + gbd1.bvi, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(60), + ) epg_220.add_vpp_config() - epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2, - None, gbd2.bvi, - "10.0.1.128", - "2001:11::128", - VppGbpEndpointRetention(60)) + epg_221 = VppGbpEndpointGroup( + self, + 221, + 441, + rd1, + gbd2, + None, + gbd2.bvi, + "10.0.1.128", + "2001:11::128", + VppGbpEndpointRetention(60), + ) epg_221.add_vpp_config() - epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1, - None, gbd1.bvi, - "10.0.2.128", - "2001:12::128", - VppGbpEndpointRetention(60)) + epg_222 = VppGbpEndpointGroup( + self, + 222, + 442, + rd1, + gbd1, + None, + gbd1.bvi, + "10.0.2.128", + "2001:12::128", + VppGbpEndpointRetention(60), + ) epg_222.add_vpp_config() # # a GBP bridge domains for the SEPs # - bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, - self.pg7.remote_ip4, 116) + bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, self.pg7.remote_ip4, 116) bd_uu1.add_vpp_config() - bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, - self.pg7.remote_ip4, 117) + bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, self.pg7.remote_ip4, 117) bd_uu2.add_vpp_config() bd3 = VppBridgeDomain(self, 3) bd3.add_vpp_config() - gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, - bd_uu1, learn=False) + gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, bd_uu1, learn=False) gbd3.add_vpp_config() bd4 = VppBridgeDomain(self, 4) bd4.add_vpp_config() - gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3, - bd_uu2, learn=False) + gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3, bd_uu2, learn=False) gbd4.add_vpp_config() # # EPGs in which the service endpoints exist # - epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3, - None, gbd1.bvi, - "12.0.0.128", - "4001:10::128", - VppGbpEndpointRetention(60)) + epg_320 = VppGbpEndpointGroup( + self, + 320, + 550, + rd1, + gbd3, + None, + gbd1.bvi, + "12.0.0.128", + "4001:10::128", + VppGbpEndpointRetention(60), + ) epg_320.add_vpp_config() - epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4, - None, gbd2.bvi, - "12.0.1.128", - "4001:11::128", - VppGbpEndpointRetention(60)) + epg_321 = VppGbpEndpointGroup( + self, + 321, + 551, + rd1, + gbd4, + None, + gbd2.bvi, + "12.0.1.128", + "4001:11::128", + VppGbpEndpointRetention(60), + ) epg_321.add_vpp_config() # # three local endpoints # - ep1 = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.1", "11.0.0.1", - "2001:10::1", "3001:10::1") + ep1 = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.1", + "11.0.0.1", + "2001:10::1", + "3001:10::1", + ) ep1.add_vpp_config() - ep2 = VppGbpEndpoint(self, self.pg1, - epg_221, None, - "10.0.1.1", "11.0.1.1", - "2001:11::1", "3001:11::1") + ep2 = VppGbpEndpoint( + self, + self.pg1, + epg_221, + None, + "10.0.1.1", + "11.0.1.1", + "2001:11::1", + "3001:11::1", + ) ep2.add_vpp_config() - ep3 = VppGbpEndpoint(self, self.pg2, - epg_222, None, - "10.0.2.2", "11.0.2.2", - "2001:12::1", "3001:12::1") + ep3 = VppGbpEndpoint( + self, + self.pg2, + epg_222, + None, + "10.0.2.2", + "11.0.2.2", + "2001:12::1", + "3001:12::1", + ) ep3.add_vpp_config() # # service endpoints # - sep1 = VppGbpEndpoint(self, self.pg3, - epg_320, None, - "12.0.0.1", "13.0.0.1", - "4001:10::1", "5001:10::1") + sep1 = VppGbpEndpoint( + self, + self.pg3, + epg_320, + None, + "12.0.0.1", + "13.0.0.1", + "4001:10::1", + "5001:10::1", + ) sep1.add_vpp_config() - sep2 = VppGbpEndpoint(self, self.pg4, - epg_320, None, - "12.0.0.2", "13.0.0.2", - "4001:10::2", "5001:10::2") + sep2 = VppGbpEndpoint( + self, + self.pg4, + epg_320, + None, + "12.0.0.2", + "13.0.0.2", + "4001:10::2", + "5001:10::2", + ) sep2.add_vpp_config() - sep3 = VppGbpEndpoint(self, self.pg5, - epg_321, None, - "12.0.1.1", "13.0.1.1", - "4001:11::1", "5001:11::1") + sep3 = VppGbpEndpoint( + self, + self.pg5, + epg_321, + None, + "12.0.1.1", + "13.0.1.1", + "4001:11::1", + "5001:11::1", + ) sep3.add_vpp_config() # this EP is not installed immediately - sep4 = VppGbpEndpoint(self, self.pg6, - epg_321, None, - "12.0.1.2", "13.0.1.2", - "4001:11::2", "5001:11::2") + sep4 = VppGbpEndpoint( + self, + self.pg6, + epg_321, + None, + "12.0.1.2", + "13.0.1.2", + "4001:11::2", + "5001:11::2", + ) # # an L2 switch packet between local EPs in different EPGs # different dest ports on each so the are LB hashed differently # - p4 = [(Ether(src=ep1.mac, dst=ep3.mac) / - IP(src=ep1.ip4, dst=ep3.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep3.mac, dst=ep1.mac) / - IP(src=ep3.ip4, dst=ep1.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=ep3.mac) / - IPv6(src=ep1.ip6, dst=ep3.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep3.mac, dst=ep1.mac) / - IPv6(src=ep3.ip6, dst=ep1.ip6) / - UDP(sport=1234, dport=1230) / - Raw(b'\xa5' * 100))] + p4 = [ + ( + Ether(src=ep1.mac, dst=ep3.mac) + / IP(src=ep1.ip4, dst=ep3.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep3.mac, dst=ep1.mac) + / IP(src=ep3.ip4, dst=ep1.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] + p6 = [ + ( + Ether(src=ep1.mac, dst=ep3.mac) + / IPv6(src=ep1.ip6, dst=ep3.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep3.mac, dst=ep1.mac) + / IPv6(src=ep3.ip6, dst=ep1.ip6) + / UDP(sport=1234, dport=1230) + / Raw(b"\xa5" * 100) + ), + ] # should be dropped since no contract yet self.send_and_assert_no_replies(self.pg0, [p4[0]]) @@ -3502,8 +4041,12 @@ class TestGBP(VppTestCase): # one of the next-hops is via an EP that is not known # rule4 = AclRule(is_permit=1, proto=17) - rule6 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule6 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule4, rule6]) acl.add_vpp_config() @@ -3511,41 +4054,75 @@ class TestGBP(VppTestCase): # test the src-ip hash mode # c1 = VppGbpContract( - self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_220.sclass, + epg_222.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() c2 = VppGbpContract( - self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_222.sclass, + epg_220.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() # @@ -3643,41 +4220,75 @@ class TestGBP(VppTestCase): # test the symmetric hash mode # c1 = VppGbpContract( - self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_220.sclass, + epg_222.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() c2 = VppGbpContract( - self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_222.sclass, + epg_220.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() # @@ -3709,40 +4320,69 @@ class TestGBP(VppTestCase): # an L3 switch packet between local EPs in different EPGs # different dest ports on each so the are LB hashed differently # - p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IP(src=ep1.ip4, dst=ep2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IP(src=ep2.ip4, dst=ep1.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IPv6(src=ep1.ip6, dst=ep2.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IPv6(src=ep2.ip6, dst=ep1.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] + p4 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IP(src=ep1.ip4, dst=ep2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep2.mac, dst=str(self.router_mac)) + / IP(src=ep2.ip4, dst=ep1.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] + p6 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IPv6(src=ep1.ip6, dst=ep2.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep2.mac, dst=str(self.router_mac)) + / IPv6(src=ep2.ip6, dst=ep1.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] c3 = VppGbpContract( - self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_220.sclass, + epg_221.sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) @@ -3758,40 +4398,60 @@ class TestGBP(VppTestCase): # packets coming from unknown remote EPs will be leant & redirected # vx_tun_l3 = VppGbpVxlanTunnel( - self, 444, rd1.rd_id, + self, + 444, + rd1.rd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l3.add_vpp_config() c4 = VppGbpContract( - self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_221.sclass, + epg_220.sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c4.add_vpp_config() - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=441, flags=0x88) / - Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) / - IP(src="10.0.0.88", dst=ep1.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=441, flags=0x88) + / Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) + / IP(src="10.0.0.88", dst=ep1.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) # unknown remote EP to local EP redirected rxs = self.send_and_expect(self.pg7, [p], sep1.itf) @@ -3803,20 +4463,18 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IP].dst, ep1.ip4) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip="10.0.0.88")) - - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=441, flags=0x88) / - Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) / - IPv6(src="2001:10::88", dst=ep1.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + self.assertTrue(find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip="10.0.0.88")) + + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=441, flags=0x88) + / Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) + / IPv6(src="2001:10::88", dst=ep1.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) # unknown remote EP to local EP redirected (ipv6) rxs = self.send_and_expect(self.pg7, [p], sep3.itf) @@ -3828,21 +4486,29 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IPv6].dst, ep1.ip6) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip="2001:10::88")) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip="2001:10::88") + ) # # L3 switch from local to remote EP # - p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IP(src=ep1.ip4, dst="10.0.0.88") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IPv6(src=ep1.ip6, dst="2001:10::88") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] + p4 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IP(src=ep1.ip4, dst="10.0.0.88") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + ] + p6 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IPv6(src=ep1.ip6, dst="2001:10::88") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + ] rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) @@ -3864,22 +4530,39 @@ class TestGBP(VppTestCase): # test the dst-ip hash mode # c5 = VppGbpContract( - self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd), - VppGbpContractNextHop(sep2.vmac, sep2.epg.bd, - sep2.ip4, sep2.epg.rd)]), + self, + 402, + epg_220.sclass, + epg_221.sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd, - sep3.ip6, sep3.epg.rd), - VppGbpContractNextHop(sep4.vmac, sep4.epg.bd, - sep4.ip6, sep4.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ), + VppGbpContractNextHop( + sep2.vmac, sep2.epg.bd, sep2.ip4, sep2.epg.rd + ), + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [ + VppGbpContractNextHop( + sep3.vmac, sep3.epg.bd, sep3.ip6, sep3.epg.rd + ), + VppGbpContractNextHop( + sep4.vmac, sep4.epg.bd, sep4.ip6, sep4.epg.rd + ), + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c5.add_vpp_config() rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf) @@ -3904,20 +4587,29 @@ class TestGBP(VppTestCase): # gbp vxlan tunnel for the remote SEP vx_tun_l3_sep = VppGbpVxlanTunnel( - self, 555, rd1.rd_id, + self, + 555, + rd1.rd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l3_sep.add_vpp_config() # remote SEP - sep5 = VppGbpEndpoint(self, vx_tun_l3_sep, - epg_320, None, - "12.0.0.10", "13.0.0.10", - "4001:10::10", "5001:10::10", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg7.local_ip4, - self.pg7.remote_ip4, - mac=None) + sep5 = VppGbpEndpoint( + self, + vx_tun_l3_sep, + epg_320, + None, + "12.0.0.10", + "13.0.0.10", + "4001:10::10", + "5001:10::10", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg7.local_ip4, + self.pg7.remote_ip4, + mac=None, + ) sep5.add_vpp_config() # @@ -3934,101 +4626,187 @@ class TestGBP(VppTestCase): gebd = VppGbpBridgeDomain(self, ebd, rd1, self.loop4, None, None) gebd.add_vpp_config() # the external epg - eepg = VppGbpEndpointGroup(self, 888, 765, rd1, gebd, - None, gebd.bvi, - "10.1.0.128", - "2001:10:1::128", - VppGbpEndpointRetention(60)) - eepg.add_vpp_config() - # add subnets to BVI - VppIpInterfaceAddress( + eepg = VppGbpEndpointGroup( self, + 888, + 765, + rd1, + gebd, + None, gebd.bvi, "10.1.0.128", - 24, bind=b_lo4_ip4).add_vpp_config() + "2001:10:1::128", + VppGbpEndpointRetention(60), + ) + eepg.add_vpp_config() + # add subnets to BVI + VppIpInterfaceAddress( + self, gebd.bvi, "10.1.0.128", 24, bind=b_lo4_ip4 + ).add_vpp_config() VppIpInterfaceAddress( + self, gebd.bvi, "2001:10:1::128", 64, bind=b_lo4_ip6 + ).add_vpp_config() + # ... which are L3-out subnets + VppGbpSubnet( self, - gebd.bvi, + rd1, + "10.1.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=765, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, "2001:10:1::128", - 64, bind=b_lo4_ip6).add_vpp_config() - # ... which are L3-out subnets - VppGbpSubnet(self, rd1, "10.1.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=765).add_vpp_config() - VppGbpSubnet(self, rd1, "2001:10:1::128", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=765).add_vpp_config() + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=765, + ).add_vpp_config() # external endpoints VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config() - eep1 = VppGbpEndpoint(self, self.vlan_100, eepg, None, "10.1.0.1", - "11.1.0.1", "2001:10:1::1", "3001:10:1::1", - ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep1 = VppGbpEndpoint( + self, + self.vlan_100, + eepg, + None, + "10.1.0.1", + "11.1.0.1", + "2001:10:1::1", + "3001:10:1::1", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL, + ) eep1.add_vpp_config() VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config() - eep2 = VppGbpEndpoint(self, self.vlan_101, eepg, None, "10.1.0.2", - "11.1.0.2", "2001:10:1::2", "3001:10:1::2", - ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep2 = VppGbpEndpoint( + self, + self.vlan_101, + eepg, + None, + "10.1.0.2", + "11.1.0.2", + "2001:10:1::2", + "3001:10:1::2", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL, + ) eep2.add_vpp_config() # external subnets reachable though eep1 and eep2 respectively - VppIpRoute(self, "10.220.0.0", 24, - [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)], - table_id=t4.table_id).add_vpp_config() - VppGbpSubnet(self, rd1, "10.220.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220).add_vpp_config() - VppIpRoute(self, "10:220::", 64, - [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)], - table_id=t6.table_id).add_vpp_config() - VppGbpSubnet(self, rd1, "10:220::", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220).add_vpp_config() - VppIpRoute(self, "10.221.0.0", 24, - [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], - table_id=t4.table_id).add_vpp_config() - VppGbpSubnet(self, rd1, "10.221.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4221).add_vpp_config() - VppIpRoute(self, "10:221::", 64, - [VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index)], - table_id=t6.table_id).add_vpp_config() - VppGbpSubnet(self, rd1, "10:221::", 64, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4221).add_vpp_config() + VppIpRoute( + self, + "10.220.0.0", + 24, + [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)], + table_id=t4.table_id, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10.220.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4220, + ).add_vpp_config() + VppIpRoute( + self, + "10:220::", + 64, + [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)], + table_id=t6.table_id, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10:220::", + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4220, + ).add_vpp_config() + VppIpRoute( + self, + "10.221.0.0", + 24, + [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], + table_id=t4.table_id, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10.221.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4221, + ).add_vpp_config() + VppIpRoute( + self, + "10:221::", + 64, + [VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index)], + table_id=t6.table_id, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10:221::", + 64, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, + sclass=4221, + ).add_vpp_config() # # l3out redirect to remote (known, then unknown) SEP # # packets from 1 external subnet to the other - p = [(Ether(src=eep1.mac, dst=self.router_mac) / - Dot1Q(vlan=100) / - IP(src="10.220.0.17", dst="10.221.0.65") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=eep1.mac, dst=self.router_mac) / - Dot1Q(vlan=100) / - IPv6(src="10:220::17", dst="10:221::65") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] + p = [ + ( + Ether(src=eep1.mac, dst=self.router_mac) + / Dot1Q(vlan=100) + / IP(src="10.220.0.17", dst="10.221.0.65") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=eep1.mac, dst=self.router_mac) + / Dot1Q(vlan=100) + / IPv6(src="10:220::17", dst="10:221::65") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] # packets should be dropped in absence of contract self.send_and_assert_no_replies(self.pg0, p) # contract redirecting to sep5 VppGbpContract( - self, 402, 4220, 4221, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, - sep5.ip4, sep5.epg.rd)]), + self, + 402, + 4220, + 4221, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, - sep5.ip6, sep5.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() + [ + VppGbpContractNextHop( + sep5.vmac, sep5.epg.bd, sep5.ip4, sep5.epg.rd + ) + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [ + VppGbpContractNextHop( + sep5.vmac, sep5.epg.bd, sep5.ip6, sep5.epg.rd + ) + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ).add_vpp_config() rxs = self.send_and_expect(self.pg0, p, self.pg7) @@ -4081,18 +4859,33 @@ class TestGBP(VppTestCase): # change the contract between l3out to redirect to local SEPs # instead of remote SEP VppGbpContract( - self, 402, 4220, 4221, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd)]), + self, + 402, + 4220, + 4221, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ) + ], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip6, sep1.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip6, sep1.epg.rd + ) + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ).add_vpp_config() rxs = self.send_and_expect(self.pg0, p, sep1.itf) for rx, tx in zip(rxs, p): @@ -4112,34 +4905,57 @@ class TestGBP(VppTestCase): # contract to redirect to learnt SEP VppGbpContract( - self, 402, epg_221.sclass, epg_222.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, - sep5.ip4, sep5.epg.rd)]), + self, + 402, + epg_221.sclass, + epg_222.sclass, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, - [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd, - sep5.ip6, sep5.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]).add_vpp_config() + [ + VppGbpContractNextHop( + sep5.vmac, sep5.epg.bd, sep5.ip4, sep5.epg.rd + ) + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP, + [ + VppGbpContractNextHop( + sep5.vmac, sep5.epg.bd, sep5.ip6, sep5.epg.rd + ) + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ).add_vpp_config() # packets from unknown EP 221 to known EP in EPG 222 # should be redirected to known remote SEP - base = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=441, flags=0x88) / - Ether(src="00:22:22:22:22:44", dst=str(self.router_mac))) - p = [(base / - IP(src="10.0.1.100", dst=ep3.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (base / - IPv6(src="2001:10::100", dst=ep3.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] + base = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=441, flags=0x88) + / Ether(src="00:22:22:22:22:44", dst=str(self.router_mac)) + ) + p = [ + ( + base + / IP(src="10.0.1.100", dst=ep3.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + base + / IPv6(src="2001:10::100", dst=ep3.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] # unknown remote EP to local EP redirected to known remote SEP rxs = self.send_and_expect(self.pg7, p, self.pg7) @@ -4163,12 +4979,12 @@ class TestGBP(VppTestCase): self.assertEqual(rxip.dst, txip.dst) # endpoint learnt via the parent GBP-vxlan interface - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip="10.0.1.100")) - self.assertTrue(find_gbp_endpoint(self, - vx_tun_l3._sw_if_index, - ip="2001:10::100")) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip="10.0.1.100") + ) + self.assertTrue( + find_gbp_endpoint(self, vx_tun_l3._sw_if_index, ip="2001:10::100") + ) # remote SEP: it is now an unknown remote SEP and should go # to spine proxy @@ -4202,7 +5018,7 @@ class TestGBP(VppTestCase): self.pg7.unconfig_ip4() def test_gbp_redirect_extended(self): - """ GBP Endpoint Redirect Extended """ + """GBP Endpoint Redirect Extended""" self.vapi.cli("set logging class gbp level debug") @@ -4210,12 +5026,10 @@ class TestGBP(VppTestCase): routed_dst_mac = "00:0c:0c:0c:0c:0c" routed_src_mac = "00:22:bd:f8:19:ff" - learnt = [{'mac': '00:00:11:11:11:02', - 'ip': '10.0.1.2', - 'ip6': '2001:10::2'}, - {'mac': '00:00:11:11:11:03', - 'ip': '10.0.1.3', - 'ip6': '2001:10::3'}] + learnt = [ + {"mac": "00:00:11:11:11:02", "ip": "10.0.1.2", "ip6": "2001:10::2"}, + {"mac": "00:00:11:11:11:03", "ip": "10.0.1.3", "ip6": "2001:10::3"}, + ] # # IP tables @@ -4232,8 +5046,10 @@ class TestGBP(VppTestCase): self.pg7.local_ip4, self.pg7.remote_ip4, 114, - mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. - VXLAN_GBP_API_TUNNEL_MODE_L3)) + mode=( + VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.VXLAN_GBP_API_TUNNEL_MODE_L3 + ), + ) rd_uu4.add_vpp_config() VppIpInterfaceBind(self, rd_uu4, t4).add_vpp_config() @@ -4242,8 +5058,10 @@ class TestGBP(VppTestCase): self.pg7.local_ip4, self.pg7.remote_ip4, 115, - mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. - VXLAN_GBP_API_TUNNEL_MODE_L3)) + mode=( + VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.VXLAN_GBP_API_TUNNEL_MODE_L3 + ), + ) rd_uu6.add_vpp_config() VppIpInterfaceBind(self, rd_uu6, t4).add_vpp_config() @@ -4284,54 +5102,66 @@ class TestGBP(VppTestCase): gbd2.add_vpp_config() # ... and has a /32 and /128 applied - ip4_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 32, - bind=b_lo0_ip4).add_vpp_config() - ip6_addr1 = VppIpInterfaceAddress(self, gbd1.bvi, - "2001:10::128", 128, - bind=b_lo0_ip6).add_vpp_config() - ip4_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, - "10.0.1.128", 32, - bind=b_lo1_ip4).add_vpp_config() - ip6_addr2 = VppIpInterfaceAddress(self, gbd2.bvi, - "2001:11::128", 128, - bind=b_lo1_ip6).add_vpp_config() + ip4_addr1 = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 32, bind=b_lo0_ip4 + ).add_vpp_config() + ip6_addr1 = VppIpInterfaceAddress( + self, gbd1.bvi, "2001:10::128", 128, bind=b_lo0_ip6 + ).add_vpp_config() + ip4_addr2 = VppIpInterfaceAddress( + self, gbd2.bvi, "10.0.1.128", 32, bind=b_lo1_ip4 + ).add_vpp_config() + ip6_addr2 = VppIpInterfaceAddress( + self, gbd2.bvi, "2001:11::128", 128, bind=b_lo1_ip6 + ).add_vpp_config() # # The Endpoint-groups # - epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1, - None, gbd1.bvi, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(60)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 440, + rd1, + gbd1, + None, + gbd1.bvi, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(60), + ) epg_220.add_vpp_config() - epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2, - None, gbd2.bvi, - "10.0.1.128", - "2001:11::128", - VppGbpEndpointRetention(60)) + epg_221 = VppGbpEndpointGroup( + self, + 221, + 441, + rd1, + gbd2, + None, + gbd2.bvi, + "10.0.1.128", + "2001:11::128", + VppGbpEndpointRetention(60), + ) epg_221.add_vpp_config() # # a GBP bridge domains for the SEPs # - bd_uu3 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, - self.pg7.remote_ip4, 116) + bd_uu3 = VppVxlanGbpTunnel(self, self.pg7.local_ip4, self.pg7.remote_ip4, 116) bd_uu3.add_vpp_config() bd3 = VppBridgeDomain(self, 3) bd3.add_vpp_config() - gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, - bd_uu3, learn=False) + gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2, bd_uu3, learn=False) gbd3.add_vpp_config() - ip4_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, - "12.0.0.128", 32, - bind=b_lo2_ip4).add_vpp_config() - ip6_addr3 = VppIpInterfaceAddress(self, gbd3.bvi, - "4001:10::128", 128, - bind=b_lo2_ip6).add_vpp_config() + ip4_addr3 = VppIpInterfaceAddress( + self, gbd3.bvi, "12.0.0.128", 32, bind=b_lo2_ip4 + ).add_vpp_config() + ip6_addr3 = VppIpInterfaceAddress( + self, gbd3.bvi, "4001:10::128", 128, bind=b_lo2_ip6 + ).add_vpp_config() # # self.logger.info(self.vapi.cli("show gbp bridge")) @@ -4343,38 +5173,69 @@ class TestGBP(VppTestCase): # # EPGs in which the service endpoints exist # - epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3, - None, gbd3.bvi, - "12.0.0.128", - "4001:10::128", - VppGbpEndpointRetention(60)) + epg_320 = VppGbpEndpointGroup( + self, + 320, + 550, + rd1, + gbd3, + None, + gbd3.bvi, + "12.0.0.128", + "4001:10::128", + VppGbpEndpointRetention(60), + ) epg_320.add_vpp_config() # # endpoints # - ep1 = VppGbpEndpoint(self, self.pg0, - epg_220, None, - "10.0.0.1", "11.0.0.1", - "2001:10::1", "3001:10::1") + ep1 = VppGbpEndpoint( + self, + self.pg0, + epg_220, + None, + "10.0.0.1", + "11.0.0.1", + "2001:10::1", + "3001:10::1", + ) ep1.add_vpp_config() - ep2 = VppGbpEndpoint(self, self.pg1, - epg_221, None, - "10.0.1.1", "11.0.1.1", - "2001:11::1", "3001:11::1") + ep2 = VppGbpEndpoint( + self, + self.pg1, + epg_221, + None, + "10.0.1.1", + "11.0.1.1", + "2001:11::1", + "3001:11::1", + ) ep2.add_vpp_config() # # service endpoints # - sep1 = VppGbpEndpoint(self, self.pg3, - epg_320, None, - "12.0.0.1", "13.0.0.1", - "4001:10::1", "5001:10::1") - sep2 = VppGbpEndpoint(self, self.pg4, - epg_320, None, - "12.0.0.2", "13.0.0.2", - "4001:10::2", "5001:10::2") + sep1 = VppGbpEndpoint( + self, + self.pg3, + epg_320, + None, + "12.0.0.1", + "13.0.0.1", + "4001:10::1", + "5001:10::1", + ) + sep2 = VppGbpEndpoint( + self, + self.pg4, + epg_320, + None, + "12.0.0.2", + "13.0.0.2", + "4001:10::2", + "5001:10::2", + ) # sep1 and sep2 are not added to config yet # they are unknown for now @@ -4382,34 +5243,54 @@ class TestGBP(VppTestCase): # # add routes to EPG subnets # - VppGbpSubnet(self, rd1, "10.0.0.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT - ).add_vpp_config() - VppGbpSubnet(self, rd1, "10.0.1.0", 24, - VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT - ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10.0.0.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT, + ).add_vpp_config() + VppGbpSubnet( + self, + rd1, + "10.0.1.0", + 24, + VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT, + ).add_vpp_config() # # Local host to known local host in different BD # with SFC contract (source and destination are in # one node and service endpoint in another node) # - p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IP(src=ep1.ip4, dst=ep2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IP(src=ep2.ip4, dst=ep1.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100))] - p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) / - IPv6(src=ep1.ip6, dst=ep2.ip6) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=ep2.mac, dst=str(self.router_mac)) / - IPv6(src=ep2.ip6, dst=ep1.ip6) / - UDP(sport=1234, dport=1230) / - Raw(b'\xa5' * 100))] + p4 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IP(src=ep1.ip4, dst=ep2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep2.mac, dst=str(self.router_mac)) + / IP(src=ep2.ip4, dst=ep1.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ] + p6 = [ + ( + Ether(src=ep1.mac, dst=str(self.router_mac)) + / IPv6(src=ep1.ip6, dst=ep2.ip6) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=ep2.mac, dst=str(self.router_mac)) + / IPv6(src=ep2.ip6, dst=ep1.ip6) + / UDP(sport=1234, dport=1230) + / Raw(b"\xa5" * 100) + ), + ] # should be dropped since no contract yet self.send_and_assert_no_replies(self.pg0, [p4[0]]) @@ -4420,8 +5301,12 @@ class TestGBP(VppTestCase): # one of the next-hops is via an EP that is not known # rule4 = AclRule(is_permit=1, proto=17) - rule6 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule6 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule4, rule6]) acl.add_vpp_config() @@ -4429,33 +5314,63 @@ class TestGBP(VppTestCase): # test the src-ip hash mode # c1 = VppGbpContract( - self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd)]), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip6, sep1.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 402, + epg_220.sclass, + epg_221.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ) + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip6, sep1.epg.rd + ) + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() c2 = VppGbpContract( - self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip4, sep1.epg.rd)]), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, - [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd, - sep1.ip6, sep1.epg.rd)])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 402, + epg_221.sclass, + epg_220.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip4, sep1.epg.rd + ) + ], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + [ + VppGbpContractNextHop( + sep1.vmac, sep1.epg.bd, sep1.ip6, sep1.epg.rd + ) + ], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() # ep1 <--> ep2 redirected through sep1 @@ -4564,16 +5479,16 @@ class TestGBP(VppTestCase): self.assertEqual(rx[IPv6].dst, ep1.ip6) # packet coming from the l2 spine-proxy to sep1 - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=116, gpid=440, gpflags=0x08, flags=0x88) / - Ether(src=str(self.router_mac), dst=sep1.mac) / - IP(src=ep1.ip4, dst=ep2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=116, gpid=440, gpflags=0x08, flags=0x88) + / Ether(src=str(self.router_mac), dst=sep1.mac) + / IP(src=ep1.ip4, dst=ep2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, [p] * 17, sep1.itf) @@ -4585,14 +5500,23 @@ class TestGBP(VppTestCase): # contract for SEP to communicate with dst EP c3 = VppGbpContract( - self, 402, epg_320.sclass, epg_221.sclass, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC)], - [ETH_P_IP, ETH_P_IPV6]) + self, + 402, + epg_320.sclass, + epg_221.sclass, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC, + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() # temporarily remove ep2, so that ep2 is remote & unknown @@ -4602,10 +5526,12 @@ class TestGBP(VppTestCase): # as ep2 is now unknown (see above), it must go through # the rd UU (packet is routed) - p1 = (Ether(src=sep1.mac, dst=self.router_mac) / - IP(src=ep1.ip4, dst=ep2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p1 = ( + Ether(src=sep1.mac, dst=self.router_mac) + / IP(src=ep1.ip4, dst=ep2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg3, [p1] * 17, self.pg7) @@ -4634,16 +5560,16 @@ class TestGBP(VppTestCase): ep2.add_vpp_config() # packet coming back from the remote sep through rd UU - p2 = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=114, gpid=441, gpflags=0x09, flags=0x88) / - Ether(src=str(self.router_mac), dst=self.router_mac) / - IP(src=ep1.ip4, dst=ep2.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p2 = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=114, gpid=441, gpflags=0x09, flags=0x88) + / Ether(src=str(self.router_mac), dst=self.router_mac) + / IP(src=ep1.ip4, dst=ep2.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, [p2], self.pg1) @@ -4666,7 +5592,7 @@ class TestGBP(VppTestCase): self.pg7.unconfig_ip4() def test_gbp_l3_out(self): - """ GBP L3 Out """ + """GBP L3 Out""" ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t self.vapi.cli("set logging class gbp level debug") @@ -4703,9 +5629,9 @@ class TestGBP(VppTestCase): # # a multicast vxlan-gbp tunnel for broadcast in the BD # - tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4, - "239.1.1.1", 88, - mcast_itf=self.pg7) + tun_bm = VppVxlanGbpTunnel( + self, self.pg7.local_ip4, "239.1.1.1", 88, mcast_itf=self.pg7 + ) tun_bm.add_vpp_config() # @@ -4719,24 +5645,37 @@ class TestGBP(VppTestCase): # # The Endpoint-groups in which the external endpoints exist # - epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1, - None, gbd1.bvi, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(4)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 113, + rd1, + gbd1, + None, + gbd1.bvi, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(4), + ) epg_220.add_vpp_config() # the BVIs have the subnets applied ... - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", - 24, bind=b_ip4).add_vpp_config() - ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", - 64, bind=b_ip6).add_vpp_config() + ip4_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 24, bind=b_ip4 + ).add_vpp_config() + ip6_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "2001:10::128", 64, bind=b_ip6 + ).add_vpp_config() # ... which are L3-out subnets l3o_1 = VppGbpSubnet( - self, rd1, "10.0.0.0", 24, + self, + rd1, + "10.0.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=113) + sclass=113, + ) l3o_1.add_vpp_config() # @@ -4753,90 +5692,139 @@ class TestGBP(VppTestCase): # an unicast vxlan-gbp for inter-RD traffic # vx_tun_l3 = VppGbpVxlanTunnel( - self, 444, rd1.rd_id, + self, + 444, + rd1.rd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l3.add_vpp_config() # # External Endpoints # - eep1 = VppGbpEndpoint(self, self.vlan_100, - epg_220, None, - "10.0.0.1", "11.0.0.1", - "2001:10::1", "3001::1", - ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep1 = VppGbpEndpoint( + self, + self.vlan_100, + epg_220, + None, + "10.0.0.1", + "11.0.0.1", + "2001:10::1", + "3001::1", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL, + ) eep1.add_vpp_config() - eep2 = VppGbpEndpoint(self, self.vlan_101, - epg_220, None, - "10.0.0.2", "11.0.0.2", - "2001:10::2", "3001::2", - ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep2 = VppGbpEndpoint( + self, + self.vlan_101, + epg_220, + None, + "10.0.0.2", + "11.0.0.2", + "2001:10::2", + "3001::2", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL, + ) eep2.add_vpp_config() - eep3 = VppGbpEndpoint(self, self.vlan_102, - epg_220, None, - "10.0.0.3", "11.0.0.3", - "2001:10::3", "3001::3", - ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL) + eep3 = VppGbpEndpoint( + self, + self.vlan_102, + epg_220, + None, + "10.0.0.3", + "11.0.0.3", + "2001:10::3", + "3001::3", + ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL, + ) eep3.add_vpp_config() # # A remote external endpoint # - rep = VppGbpEndpoint(self, vx_tun_l3, - epg_220, None, - "10.0.0.101", "11.0.0.101", - "2001:10::101", "3001::101", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg7.local_ip4, - self.pg7.remote_ip4, - mac=None) + rep = VppGbpEndpoint( + self, + vx_tun_l3, + epg_220, + None, + "10.0.0.101", + "11.0.0.101", + "2001:10::101", + "3001::101", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg7.local_ip4, + self.pg7.remote_ip4, + mac=None, + ) rep.add_vpp_config() # # EP1 impersonating EP3 is dropped # - p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") / - Dot1Q(vlan=100) / - ARP(op="who-has", - psrc="10.0.0.3", pdst="10.0.0.128", - hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff")) + p = ( + Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") + / Dot1Q(vlan=100) + / ARP( + op="who-has", + psrc="10.0.0.3", + pdst="10.0.0.128", + hwsrc=eep1.mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) self.send_and_assert_no_replies(self.pg0, p) # # ARP packet from External EPs are accepted and replied to # - p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") / - Dot1Q(vlan=100) / - ARP(op="who-has", - psrc=eep1.ip4, pdst="10.0.0.128", - hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff")) + p_arp = ( + Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") + / Dot1Q(vlan=100) + / ARP( + op="who-has", + psrc=eep1.ip4, + pdst="10.0.0.128", + hwsrc=eep1.mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) # # ARP packet from host in remote subnet are accepted and replied to # - p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") / - Dot1Q(vlan=102) / - ARP(op="who-has", - psrc=eep3.ip4, pdst="10.0.0.128", - hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff")) + p_arp = ( + Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") + / Dot1Q(vlan=102) + / ARP( + op="who-has", + psrc=eep3.ip4, + pdst="10.0.0.128", + hwsrc=eep3.mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) # # packets destined to unknown addresses in the BVI's subnet # are ARP'd for # - p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.0.0.1", dst="10.0.0.88") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) - p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IPv6(src="2001:10::1", dst="2001:10::88") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p4 = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.0.0.1", dst="10.0.0.88") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) + p6 = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IPv6(src="2001:10::1", dst="2001:10::88") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7) @@ -4860,26 +5848,28 @@ class TestGBP(VppTestCase): # # remote to external # - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=113, flags=0x88) / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.0.0.101", dst="10.0.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=113, flags=0x88) + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.0.0.101", dst="10.0.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # # local EP pings router # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src=eep1.ip4, dst="10.0.0.128") / - ICMP(type='echo-request')) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src=eep1.ip4, dst="10.0.0.128") + / ICMP(type="echo-request") + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4891,10 +5881,12 @@ class TestGBP(VppTestCase): # # local EP pings other local EP # - p = (Ether(src=eep1.mac, dst=eep2.mac) / - Dot1Q(vlan=100) / - IP(src=eep1.ip4, dst=eep2.ip4) / - ICMP(type='echo-request')) + p = ( + Ether(src=eep1.mac, dst=eep2.mac) + / Dot1Q(vlan=100) + / IP(src=eep1.ip4, dst=eep2.ip4) + / ICMP(type="echo-request") + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4906,10 +5898,12 @@ class TestGBP(VppTestCase): # # local EP pings router w/o vlan tag poped # - p = (Ether(src=eep3.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=102) / - IP(src=eep3.ip4, dst="10.0.0.128") / - ICMP(type='echo-request')) + p = ( + Ether(src=eep3.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=102) + / IP(src=eep3.ip4, dst="10.0.0.128") + / ICMP(type="echo-request") + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -4920,56 +5914,79 @@ class TestGBP(VppTestCase): # # A ip4 subnet reachable through the external EP1 # - ip_220 = VppIpRoute(self, "10.220.0.0", 24, - [VppRoutePath(eep1.ip4, - eep1.epg.bvi.sw_if_index)], - table_id=t4.table_id) + ip_220 = VppIpRoute( + self, + "10.220.0.0", + 24, + [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)], + table_id=t4.table_id, + ) ip_220.add_vpp_config() l3o_220 = VppGbpSubnet( - self, rd1, "10.220.0.0", 24, + self, + rd1, + "10.220.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220) + sclass=4220, + ) l3o_220.add_vpp_config() # # An ip6 subnet reachable through the external EP1 # - ip6_220 = VppIpRoute(self, "10:220::", 64, - [VppRoutePath(eep1.ip6, - eep1.epg.bvi.sw_if_index)], - table_id=t6.table_id) + ip6_220 = VppIpRoute( + self, + "10:220::", + 64, + [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)], + table_id=t6.table_id, + ) ip6_220.add_vpp_config() l3o6_220 = VppGbpSubnet( - self, rd1, "10:220::", 64, + self, + rd1, + "10:220::", + 64, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220) + sclass=4220, + ) l3o6_220.add_vpp_config() # # A subnet reachable through the external EP2 # - ip_221 = VppIpRoute(self, "10.221.0.0", 24, - [VppRoutePath(eep2.ip4, - eep2.epg.bvi.sw_if_index)], - table_id=t4.table_id) + ip_221 = VppIpRoute( + self, + "10.221.0.0", + 24, + [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)], + table_id=t4.table_id, + ) ip_221.add_vpp_config() l3o_221 = VppGbpSubnet( - self, rd1, "10.221.0.0", 24, + self, + rd1, + "10.221.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4221) + sclass=4221, + ) l3o_221.add_vpp_config() # # ping between hosts in remote subnets # dropped without a contract # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.221.0.1") / - ICMP(type='echo-request')) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.221.0.1") + / ICMP(type="echo-request") + ) self.send_and_assert_no_replies(self.pg0, p * 1) @@ -4977,8 +5994,12 @@ class TestGBP(VppTestCase): # contract for the external nets to communicate # rule4 = AclRule(is_permit=1, proto=17) - rule6 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule6 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule4, rule6]) acl.add_vpp_config() @@ -4986,68 +6007,106 @@ class TestGBP(VppTestCase): # A contract with the wrong scope is not matched # c_44 = VppGbpContract( - self, 44, 4220, 4221, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), - VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + self, + 44, + 4220, + 4221, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c_44.add_vpp_config() self.send_and_assert_no_replies(self.pg0, p * 1) c1 = VppGbpContract( - self, 55, 4220, 4221, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 4221, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() # # Contracts allowing ext-net 200 to talk with external EPs # c2 = VppGbpContract( - self, 55, 4220, 113, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 113, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() c3 = VppGbpContract( - self, 55, 113, 4220, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 113, + 4220, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() # # ping between hosts in remote subnets # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.221.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.221.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -5063,27 +6122,29 @@ class TestGBP(VppTestCase): # # from remote external EP to local external EP # - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=113, flags=0x88) / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.0.0.101", dst="10.220.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=113, flags=0x88) + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.0.0.101", dst="10.220.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # # ping from an external host to the remote external EP # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst=rep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst=rep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg7) @@ -5113,10 +6174,14 @@ class TestGBP(VppTestCase): # first the VXLAN-GBP tunnel over which it is reached # vx_tun_r1 = VppVxlanGbpTunnel( - self, self.pg7.local_ip4, - self.pg7.remote_ip4, 445, - mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. - VXLAN_GBP_API_TUNNEL_MODE_L3)) + self, + self.pg7.local_ip4, + self.pg7.remote_ip4, + 445, + mode=( + VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.VXLAN_GBP_API_TUNNEL_MODE_L3 + ), + ) vx_tun_r1.add_vpp_config() VppIpInterfaceBind(self, vx_tun_r1, t4).add_vpp_config() @@ -5125,36 +6190,44 @@ class TestGBP(VppTestCase): # # then the special adj to resolve through on that tunnel # - n1 = VppNeighbor(self, - vx_tun_r1.sw_if_index, - "00:0c:0c:0c:0c:0c", - self.pg7.remote_ip4) + n1 = VppNeighbor( + self, vx_tun_r1.sw_if_index, "00:0c:0c:0c:0c:0c", self.pg7.remote_ip4 + ) n1.add_vpp_config() # # the route via the adj above # - ip_222 = VppIpRoute(self, "10.222.0.0", 24, - [VppRoutePath(self.pg7.remote_ip4, - vx_tun_r1.sw_if_index)], - table_id=t4.table_id) + ip_222 = VppIpRoute( + self, + "10.222.0.0", + 24, + [VppRoutePath(self.pg7.remote_ip4, vx_tun_r1.sw_if_index)], + table_id=t4.table_id, + ) ip_222.add_vpp_config() l3o_222 = VppGbpSubnet( - self, rd1, "10.222.0.0", 24, + self, + rd1, + "10.222.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4222) + sclass=4222, + ) l3o_222.add_vpp_config() # # ping between hosts in local and remote external subnets # dropped without a contract # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_assert_no_replies(self.pg0, p * 1) @@ -5162,26 +6235,37 @@ class TestGBP(VppTestCase): # Add contracts ext-nets for 220 -> 222 # c4 = VppGbpContract( - self, 55, 4220, 4222, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 4222, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c4.add_vpp_config() # # ping from host in local to remote external subnets # - p = (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 3, self.pg7) @@ -5208,39 +6292,50 @@ class TestGBP(VppTestCase): # make the external subnet ECMP # vx_tun_r2 = VppVxlanGbpTunnel( - self, self.pg7.local_ip4, - self.pg7.remote_ip4, 446, - mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. - VXLAN_GBP_API_TUNNEL_MODE_L3)) + self, + self.pg7.local_ip4, + self.pg7.remote_ip4, + 446, + mode=( + VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.VXLAN_GBP_API_TUNNEL_MODE_L3 + ), + ) vx_tun_r2.add_vpp_config() VppIpInterfaceBind(self, vx_tun_r2, t4).add_vpp_config() self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel")) - n2 = VppNeighbor(self, - vx_tun_r2.sw_if_index, - "00:0c:0c:0c:0c:0c", - self.pg7.remote_ip4) + n2 = VppNeighbor( + self, vx_tun_r2.sw_if_index, "00:0c:0c:0c:0c:0c", self.pg7.remote_ip4 + ) n2.add_vpp_config() - ip_222.modify([VppRoutePath(self.pg7.remote_ip4, - vx_tun_r1.sw_if_index), - VppRoutePath(self.pg7.remote_ip4, - vx_tun_r2.sw_if_index)]) + ip_222.modify( + [ + VppRoutePath(self.pg7.remote_ip4, vx_tun_r1.sw_if_index), + VppRoutePath(self.pg7.remote_ip4, vx_tun_r2.sw_if_index), + ] + ) # # now expect load-balance # - p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1222, dport=1235) / - Raw(b'\xa5' * 100))] + p = [ + ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1222, dport=1235) + / Raw(b"\xa5" * 100) + ), + ] rxs = self.send_and_expect(self.pg0, p, self.pg7) @@ -5250,41 +6345,53 @@ class TestGBP(VppTestCase): # # Same LB test for v6 # - n3 = VppNeighbor(self, - vx_tun_r1.sw_if_index, - "00:0c:0c:0c:0c:0c", - self.pg7.remote_ip6) + n3 = VppNeighbor( + self, vx_tun_r1.sw_if_index, "00:0c:0c:0c:0c:0c", self.pg7.remote_ip6 + ) n3.add_vpp_config() - n4 = VppNeighbor(self, - vx_tun_r2.sw_if_index, - "00:0c:0c:0c:0c:0c", - self.pg7.remote_ip6) + n4 = VppNeighbor( + self, vx_tun_r2.sw_if_index, "00:0c:0c:0c:0c:0c", self.pg7.remote_ip6 + ) n4.add_vpp_config() - ip_222_6 = VppIpRoute(self, "10:222::", 64, - [VppRoutePath(self.pg7.remote_ip6, - vx_tun_r1.sw_if_index), - VppRoutePath(self.pg7.remote_ip6, - vx_tun_r2.sw_if_index)], - table_id=t6.table_id) + ip_222_6 = VppIpRoute( + self, + "10:222::", + 64, + [ + VppRoutePath(self.pg7.remote_ip6, vx_tun_r1.sw_if_index), + VppRoutePath(self.pg7.remote_ip6, vx_tun_r2.sw_if_index), + ], + table_id=t6.table_id, + ) ip_222_6.add_vpp_config() l3o_222_6 = VppGbpSubnet( - self, rd1, "10:222::", 64, + self, + rd1, + "10:222::", + 64, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4222) + sclass=4222, + ) l3o_222_6.add_vpp_config() - p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IPv6(src="10:220::1", dst="10:222::1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=eep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IPv6(src="10:220::1", dst="10:222::1") / - UDP(sport=7777, dport=8881) / - Raw(b'\xa5' * 100))] + p = [ + ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IPv6(src="10:220::1", dst="10:222::1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=eep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IPv6(src="10:220::1", dst="10:222::1") + / UDP(sport=7777, dport=8881) + / Raw(b"\xa5" * 100) + ), + ] self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1")) rxs = self.send_and_expect(self.pg0, p, self.pg7) @@ -5296,14 +6403,16 @@ class TestGBP(VppTestCase): # ping from host in remote to local external subnets # there's no contract for this, but the A bit is set. # - p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.222.0.1", dst="10.220.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=445, gpid=4222, flags=0x88, gpflags="A") + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.222.0.1", dst="10.220.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) @@ -5312,45 +6421,57 @@ class TestGBP(VppTestCase): # ping from host in remote to remote external subnets # this is dropped by reflection check. # - p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.222.0.1", dst="10.222.0.2") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=445, gpid=4222, flags=0x88, gpflags="A") + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.222.0.1", dst="10.222.0.2") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) - p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IPv6(src="10:222::1", dst="10:222::2") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=445, gpid=4222, flags=0x88, gpflags="A") + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IPv6(src="10:222::1", dst="10:222::2") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) # # local EP # - lep1 = VppGbpEndpoint(self, vlan_144, - epg_220, None, - "10.0.0.44", "11.0.0.44", - "2001:10::44", "3001::44") + lep1 = VppGbpEndpoint( + self, + vlan_144, + epg_220, + None, + "10.0.0.44", + "11.0.0.44", + "2001:10::44", + "3001::44", + ) lep1.add_vpp_config() # # local EP to local ip4 external subnet # - p = (Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IP(src=lep1.ip4, dst="10.220.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IP(src=lep1.ip4, dst="10.220.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -5362,11 +6483,13 @@ class TestGBP(VppTestCase): # # local EP to local ip6 external subnet # - p = (Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IPv6(src=lep1.ip6, dst="10:220::1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IPv6(src=lep1.ip6, dst="10:220::1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -5378,48 +6501,70 @@ class TestGBP(VppTestCase): # # ip4 and ip6 subnets that load-balance # - ip_20 = VppIpRoute(self, "10.20.0.0", 24, - [VppRoutePath(eep1.ip4, - eep1.epg.bvi.sw_if_index), - VppRoutePath(eep2.ip4, - eep2.epg.bvi.sw_if_index)], - table_id=t4.table_id) + ip_20 = VppIpRoute( + self, + "10.20.0.0", + 24, + [ + VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index), + VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index), + ], + table_id=t4.table_id, + ) ip_20.add_vpp_config() l3o_20 = VppGbpSubnet( - self, rd1, "10.20.0.0", 24, + self, + rd1, + "10.20.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220) + sclass=4220, + ) l3o_20.add_vpp_config() - ip6_20 = VppIpRoute(self, "10:20::", 64, - [VppRoutePath(eep1.ip6, - eep1.epg.bvi.sw_if_index), - VppRoutePath(eep2.ip6, - eep2.epg.bvi.sw_if_index)], - table_id=t6.table_id) + ip6_20 = VppIpRoute( + self, + "10:20::", + 64, + [ + VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index), + VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index), + ], + table_id=t6.table_id, + ) ip6_20.add_vpp_config() l3o6_20 = VppGbpSubnet( - self, rd1, "10:20::", 64, + self, + rd1, + "10:20::", + 64, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220) + sclass=4220, + ) l3o6_20.add_vpp_config() self.logger.info(self.vapi.cli("sh ip fib 10.20.0.1")) self.logger.info(self.vapi.cli("sh ip6 fib 10:20::1")) # two ip6 packets whose port are chosen so they load-balance - p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IPv6(src=lep1.ip6, dst="10:20::1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)), - (Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IPv6(src=lep1.ip6, dst="10:20::1") / - UDP(sport=124, dport=1230) / - Raw(b'\xa5' * 100))] + p = [ + ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IPv6(src=lep1.ip6, dst="10:20::1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IPv6(src=lep1.ip6, dst="10:20::1") + / UDP(sport=124, dport=1230) + / Raw(b"\xa5" * 100) + ), + ] rxs = self.send_and_expect(self.pg0, p, self.pg0, 2) @@ -5427,16 +6572,22 @@ class TestGBP(VppTestCase): self.assertEqual(rxs[1][Dot1Q].vlan, 100) # two ip4 packets whose port are chosen so they load-balance - p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IP(src=lep1.ip4, dst="10.20.0.1") / - UDP(sport=1235, dport=1235) / - Raw(b'\xa5' * 100)), - (Ether(src=lep1.mac, dst=str(self.router_mac)) / - Dot1Q(vlan=144) / - IP(src=lep1.ip4, dst="10.20.0.1") / - UDP(sport=124, dport=1230) / - Raw(b'\xa5' * 100))] + p = [ + ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IP(src=lep1.ip4, dst="10.20.0.1") + / UDP(sport=1235, dport=1235) + / Raw(b"\xa5" * 100) + ), + ( + Ether(src=lep1.mac, dst=str(self.router_mac)) + / Dot1Q(vlan=144) + / IP(src=lep1.ip4, dst="10.20.0.1") + / UDP(sport=124, dport=1230) + / Raw(b"\xa5" * 100) + ), + ] rxs = self.send_and_expect(self.pg0, p, self.pg0, 2) @@ -5452,7 +6603,7 @@ class TestGBP(VppTestCase): self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED) def test_gbp_anon_l3_out(self): - """ GBP Anonymous L3 Out """ + """GBP Anonymous L3 Out""" ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t self.vapi.cli("set logging class gbp level debug") @@ -5497,23 +6648,34 @@ class TestGBP(VppTestCase): # # The Endpoint-groups in which the external endpoints exist # - epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1, - None, gbd1.bvi, - "10.0.0.128", - "2001:10::128", - VppGbpEndpointRetention(4)) + epg_220 = VppGbpEndpointGroup( + self, + 220, + 113, + rd1, + gbd1, + None, + gbd1.bvi, + "10.0.0.128", + "2001:10::128", + VppGbpEndpointRetention(4), + ) epg_220.add_vpp_config() # the BVIs have the subnet applied ... - ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, - "10.0.0.128", 24, - bind=bind_l0_ip4).add_vpp_config() + ip4_addr = VppIpInterfaceAddress( + self, gbd1.bvi, "10.0.0.128", 24, bind=bind_l0_ip4 + ).add_vpp_config() # ... which is an Anonymous L3-out subnets l3o_1 = VppGbpSubnet( - self, rd1, "10.0.0.0", 24, + self, + rd1, + "10.0.0.0", + 24, VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_ANON_L3_OUT, - sclass=113) + sclass=113, + ) l3o_1.add_vpp_config() # @@ -5535,22 +6697,31 @@ class TestGBP(VppTestCase): # an unicast vxlan-gbp for inter-RD traffic # vx_tun_l3 = VppGbpVxlanTunnel( - self, 444, rd1.rd_id, + self, + 444, + rd1.rd_id, VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3, - self.pg2.local_ip4) + self.pg2.local_ip4, + ) vx_tun_l3.add_vpp_config() # # A remote external endpoint # - rep = VppGbpEndpoint(self, vx_tun_l3, - epg_220, None, - "10.0.0.201", "11.0.0.201", - "2001:10::201", "3001::101", - ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, - self.pg7.local_ip4, - self.pg7.remote_ip4, - mac=None) + rep = VppGbpEndpoint( + self, + vx_tun_l3, + epg_220, + None, + "10.0.0.201", + "11.0.0.201", + "2001:10::201", + "3001::101", + ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE, + self.pg7.local_ip4, + self.pg7.remote_ip4, + mac=None, + ) rep.add_vpp_config() # @@ -5559,48 +6730,56 @@ class TestGBP(VppTestCase): # - APR request flooded over the other vlan subif # - ARP reply from BVI # - p_arp = (Ether(src=self.vlan_100.remote_mac, - dst="ff:ff:ff:ff:ff:ff") / - Dot1Q(vlan=100) / - ARP(op="who-has", - psrc="10.0.0.100", - pdst="10.0.0.128", - hwsrc=self.vlan_100.remote_mac, - hwdst="ff:ff:ff:ff:ff:ff")) + p_arp = ( + Ether(src=self.vlan_100.remote_mac, dst="ff:ff:ff:ff:ff:ff") + / Dot1Q(vlan=100) + / ARP( + op="who-has", + psrc="10.0.0.100", + pdst="10.0.0.128", + hwsrc=self.vlan_100.remote_mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2) - p_arp = (Ether(src=self.vlan_101.remote_mac, - dst="ff:ff:ff:ff:ff:ff") / - Dot1Q(vlan=101) / - ARP(op="who-has", - psrc='10.0.0.101', - pdst="10.0.0.128", - hwsrc=self.vlan_101.remote_mac, - hwdst="ff:ff:ff:ff:ff:ff")) + p_arp = ( + Ether(src=self.vlan_101.remote_mac, dst="ff:ff:ff:ff:ff:ff") + / Dot1Q(vlan=101) + / ARP( + op="who-has", + psrc="10.0.0.101", + pdst="10.0.0.128", + hwsrc=self.vlan_101.remote_mac, + hwdst="ff:ff:ff:ff:ff:ff", + ) + ) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2) # # remote to external # - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=vx_tun_l3.vni, gpid=epg_220.sclass, flags=0x88) / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=str(rep.ip4), dst="10.0.0.100") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=vx_tun_l3.vni, gpid=epg_220.sclass, flags=0x88) + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=str(rep.ip4), dst="10.0.0.100") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # # local EP pings router # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.0.0.100", dst="10.0.0.128") / - ICMP(type='echo-request')) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.0.0.100", dst="10.0.0.128") + / ICMP(type="echo-request") + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) for rx in rxs: @@ -5611,11 +6790,12 @@ class TestGBP(VppTestCase): # # local EP pings other local EP # - p = (Ether(src=self.vlan_100.remote_mac, - dst=self.vlan_101.remote_mac) / - Dot1Q(vlan=100) / - IP(src="10.0.0.100", dst="10.0.0.101") / - ICMP(type='echo-request')) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=self.vlan_101.remote_mac) + / Dot1Q(vlan=100) + / IP(src="10.0.0.100", dst="10.0.0.101") + / ICMP(type="echo-request") + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) for rx in rxs: @@ -5626,43 +6806,59 @@ class TestGBP(VppTestCase): # # A subnet reachable through an external router on vlan 100 # - ip_220 = VppIpRoute(self, "10.220.0.0", 24, - [VppRoutePath("10.0.0.100", - epg_220.bvi.sw_if_index)], - table_id=t4.table_id) + ip_220 = VppIpRoute( + self, + "10.220.0.0", + 24, + [VppRoutePath("10.0.0.100", epg_220.bvi.sw_if_index)], + table_id=t4.table_id, + ) ip_220.add_vpp_config() l3o_220 = VppGbpSubnet( - self, rd1, "10.220.0.0", 24, + self, + rd1, + "10.220.0.0", + 24, # note: this a "regular" L3 out subnet (not connected) VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4220) + sclass=4220, + ) l3o_220.add_vpp_config() # # A subnet reachable through an external router on vlan 101 # - ip_221 = VppIpRoute(self, "10.221.0.0", 24, - [VppRoutePath("10.0.0.101", - epg_220.bvi.sw_if_index)], - table_id=t4.table_id) + ip_221 = VppIpRoute( + self, + "10.221.0.0", + 24, + [VppRoutePath("10.0.0.101", epg_220.bvi.sw_if_index)], + table_id=t4.table_id, + ) ip_221.add_vpp_config() l3o_221 = VppGbpSubnet( - self, rd1, "10.221.0.0", 24, + self, + rd1, + "10.221.0.0", + 24, # note: this a "regular" L3 out subnet (not connected) VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4221) + sclass=4221, + ) l3o_221.add_vpp_config() # # ping between hosts in remote subnets # dropped without a contract # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.221.0.1") / - ICMP(type='echo-request')) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.221.0.1") + / ICMP(type="echo-request") + ) rxs = self.send_and_assert_no_replies(self.pg0, p * 1) @@ -5670,60 +6866,93 @@ class TestGBP(VppTestCase): # contract for the external nets to communicate # rule4 = AclRule(is_permit=1, proto=17) - rule6 = AclRule(src_prefix=IPv6Network((0, 0)), - dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17) + rule6 = AclRule( + src_prefix=IPv6Network((0, 0)), + dst_prefix=IPv6Network((0, 0)), + is_permit=1, + proto=17, + ) acl = VppAcl(self, rules=[rule4, rule6]) acl.add_vpp_config() c1 = VppGbpContract( - self, 55, 4220, 4221, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 4221, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c1.add_vpp_config() # # Contracts allowing ext-net 200 to talk with external EPs # c2 = VppGbpContract( - self, 55, 4220, 113, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 113, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c2.add_vpp_config() c3 = VppGbpContract( - self, 55, 113, 4220, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 113, + 4220, + acl.acl_index, + [ VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c3.add_vpp_config() # # ping between hosts in remote subnets # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.221.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.221.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg0) @@ -5739,27 +6968,29 @@ class TestGBP(VppTestCase): # # from remote external EP to local external EP # - p = (Ether(src=self.pg7.remote_mac, - dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, - dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=444, gpid=113, flags=0x88) / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src=rep.ip4, dst="10.220.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=444, gpid=113, flags=0x88) + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src=rep.ip4, dst="10.220.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 1, self.pg0) # # ping from an external host to the remote external EP # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst=rep.ip4) / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst=rep.ip4) + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 1, self.pg7) @@ -5789,10 +7020,14 @@ class TestGBP(VppTestCase): # first the VXLAN-GBP tunnel over which it is reached # vx_tun_r = VppVxlanGbpTunnel( - self, self.pg7.local_ip4, - self.pg7.remote_ip4, 445, - mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t. - VXLAN_GBP_API_TUNNEL_MODE_L3)) + self, + self.pg7.local_ip4, + self.pg7.remote_ip4, + 445, + mode=( + VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.VXLAN_GBP_API_TUNNEL_MODE_L3 + ), + ) vx_tun_r.add_vpp_config() VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config() @@ -5801,37 +7036,45 @@ class TestGBP(VppTestCase): # # then the special adj to resolve through on that tunnel # - n1 = VppNeighbor(self, - vx_tun_r.sw_if_index, - "00:0c:0c:0c:0c:0c", - self.pg7.remote_ip4) + n1 = VppNeighbor( + self, vx_tun_r.sw_if_index, "00:0c:0c:0c:0c:0c", self.pg7.remote_ip4 + ) n1.add_vpp_config() # # the route via the adj above # - ip_222 = VppIpRoute(self, "10.222.0.0", 24, - [VppRoutePath(self.pg7.remote_ip4, - vx_tun_r.sw_if_index)], - table_id=t4.table_id) + ip_222 = VppIpRoute( + self, + "10.222.0.0", + 24, + [VppRoutePath(self.pg7.remote_ip4, vx_tun_r.sw_if_index)], + table_id=t4.table_id, + ) ip_222.add_vpp_config() l3o_222 = VppGbpSubnet( - self, rd1, "10.222.0.0", 24, + self, + rd1, + "10.222.0.0", + 24, # note: this a "regular" l3out subnet (not connected) VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT, - sclass=4222) + sclass=4222, + ) l3o_222.add_vpp_config() # # ping between hosts in local and remote external subnets # dropped without a contract # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_assert_no_replies(self.pg0, p * 1) @@ -5839,26 +7082,37 @@ class TestGBP(VppTestCase): # Add contracts ext-nets for 220 -> 222 # c4 = VppGbpContract( - self, 55, 4220, 4222, acl.acl_index, - [VppGbpContractRule( - VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, - VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - []), + self, + 55, + 4220, + 4222, + acl.acl_index, + [ + VppGbpContractRule( + VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, + VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, + [], + ), VppGbpContractRule( VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT, VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP, - [])], - [ETH_P_IP, ETH_P_IPV6]) + [], + ), + ], + [ETH_P_IP, ETH_P_IPV6], + ) c4.add_vpp_config() # # ping from host in local to remote external subnets # - p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) / - Dot1Q(vlan=100) / - IP(src="10.220.0.1", dst="10.222.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) + / Dot1Q(vlan=100) + / IP(src="10.220.0.1", dst="10.222.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg0, p * 3, self.pg7) @@ -5885,14 +7139,16 @@ class TestGBP(VppTestCase): # ping from host in remote to local external subnets # there's no contract for this, but the A bit is set. # - p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.222.0.1", dst="10.220.0.1") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=445, gpid=4222, flags=0x88, gpflags="A") + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.222.0.1", dst="10.220.0.1") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) @@ -5901,14 +7157,16 @@ class TestGBP(VppTestCase): # ping from host in remote to remote external subnets # this is dropped by reflection check. # - p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / - IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / - UDP(sport=1234, dport=48879) / - VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') / - Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / - IP(src="10.222.0.1", dst="10.222.0.2") / - UDP(sport=1234, dport=1234) / - Raw(b'\xa5' * 100)) + p = ( + Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) + / IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) + / UDP(sport=1234, dport=48879) + / VXLAN(vni=445, gpid=4222, flags=0x88, gpflags="A") + / Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) + / IP(src="10.222.0.1", dst="10.222.0.2") + / UDP(sport=1234, dport=1234) + / Raw(b"\xa5" * 100) + ) rxs = self.send_and_assert_no_replies(self.pg7, p * 3) @@ -5922,5 +7180,5 @@ class TestGBP(VppTestCase): self.wait_for_ep_timeout(sw_if_index=rep.itf.sw_if_index, ip=rep.ip4) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(testRunner=VppTestRunner) diff --git a/extras/deprecated/vnet/vxlan-gbp/test_vxlan_gbp.py b/extras/deprecated/vnet/vxlan-gbp/test_vxlan_gbp.py index f332aced7d8..1d64937b6dd 100644 --- a/extras/deprecated/vnet/vxlan-gbp/test_vxlan_gbp.py +++ b/extras/deprecated/vnet/vxlan-gbp/test_vxlan_gbp.py @@ -16,37 +16,43 @@ from vpp_ip import INVALID_INDEX class TestVxlanGbp(VppTestCase): - """ VXLAN GBP Test Case """ + """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)) + """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)) + """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) + 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 """ + """range of remote ip's""" return ip4_range(self.pg0.remote_ip4, start, end) def decapsulate(self, pkt): @@ -54,7 +60,7 @@ class TestVxlanGbp(VppTestCase): 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)) + self.assertEqual(pkt[VXLAN].flags, int("0x88", 16)) return pkt[VXLAN].payload # Method for checking VXLAN GBP encapsulation. @@ -94,28 +100,28 @@ class TestVxlanGbp(VppTestCase): 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): + 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 = 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, + "src": cls.pg0.local_ip4, + "dst": dest_ip4, + "vni": vni, + "instance": INVALID_INDEX, + "mcast_sw_if_index": INVALID_INDEX, + "mode": 1, }, - is_add=1 + is_add=1, ) - cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=r.sw_if_index, - bd_id=vni) + 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. @@ -146,33 +152,33 @@ class TestVxlanGbp(VppTestCase): # 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 + 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, + "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 + 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=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) + 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.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) + rx_sw_if_index=cls.pg3.sw_if_index, bd_id=cls.ucast_flood_bd + ) except Exception: super(TestVxlanGbp, cls).tearDownClass() raise @@ -182,7 +188,7 @@ class TestVxlanGbp(VppTestCase): super(TestVxlanGbp, cls).tearDownClass() def assert_eq_pkts(self, pkt1, pkt2): - """ Verify the Ether, IP, UDP, payload are equal in both + """Verify the Ether, IP, UDP, payload are equal in both packets """ self.assertEqual(pkt1[Ether].src, pkt2[Ether].src) @@ -194,14 +200,17 @@ class TestVxlanGbp(VppTestCase): self.assertEqual(pkt1[Raw], pkt2[Raw]) def test_decap(self): - """ Decapsulation test + """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) + encapsulated_pkt = self.encapsulate(self.frame_request, self.single_tunnel_vni) - self.pg0.add_stream([encapsulated_pkt, ]) + self.pg0.add_stream( + [ + encapsulated_pkt, + ] + ) self.pg1.enable_capture() @@ -214,7 +223,7 @@ class TestVxlanGbp(VppTestCase): self.assert_eq_pkts(pkt, self.frame_request) def test_encap(self): - """ Encapsulation test + """Encapsulation test Send frames from pg1 Verify receipt of encapsulated frames on pg0 """ @@ -233,7 +242,7 @@ class TestVxlanGbp(VppTestCase): self.assert_eq_pkts(payload, self.frame_reply) def test_ucast_flood(self): - """ Unicast flood test + """Unicast flood test Send frames from pg3 Verify receipt of encapsulated frames on pg0 """ @@ -251,16 +260,18 @@ class TestVxlanGbp(VppTestCase): self.assert_eq_pkts(payload, self.frame_reply) def test_encap_big_packet(self): - """ Encapsulation test send big frame from pg1 + """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)) + 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]) @@ -276,9 +287,9 @@ class TestVxlanGbp(VppTestCase): 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. + # 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() @@ -289,5 +300,5 @@ class TestVxlanGbp(VppTestCase): self.logger.info(self.vapi.cli("show error")) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(testRunner=VppTestRunner) diff --git a/extras/deprecated/vnet/vxlan-gbp/vpp_vxlan_gbp_tunnel.py b/extras/deprecated/vnet/vxlan-gbp/vpp_vxlan_gbp_tunnel.py index 0898bd9f810..1b6b4e731ca 100644 --- a/extras/deprecated/vnet/vxlan-gbp/vpp_vxlan_gbp_tunnel.py +++ b/extras/deprecated/vnet/vxlan-gbp/vpp_vxlan_gbp_tunnel.py @@ -1,17 +1,18 @@ - from vpp_interface import VppInterface from vpp_papi import VppEnum -INDEX_INVALID = 0xffffffff +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: + 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 @@ -21,9 +22,19 @@ 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 """ + 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 @@ -33,21 +44,23 @@ class VppVxlanGbpTunnel(VppInterface): 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) + 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, + "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): @@ -65,11 +78,14 @@ class VppVxlanGbpTunnel(VppInterface): ) def query_vpp_config(self): - return (INDEX_INVALID != find_vxlan_gbp_tunnel(self._test, - self.src, - self.dst, - self.vni)) + 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) + return "vxlan-gbp-%d-%d-%s-%s" % ( + self.sw_if_index, + self.vni, + self.src, + self.dst, + ) diff --git a/extras/deprecated/vom/test/test_vom.py b/extras/deprecated/vom/test/test_vom.py index a77b935263d..51944296233 100644 --- a/extras/deprecated/vom/test/test_vom.py +++ b/extras/deprecated/vom/test/test_vom.py @@ -4,13 +4,12 @@ import unittest import os import signal -from framework import VppTestCase, running_extended_tests, \ - VppTestRunner, Worker +from framework import VppTestCase, running_extended_tests, VppTestRunner, Worker @unittest.skipUnless(running_extended_tests, "part of extended tests") class VOMTestCase(VppTestCase): - """ VPP Object Model Test """ + """VPP Object Model Test""" @classmethod def setUpClass(cls): @@ -21,14 +20,14 @@ class VOMTestCase(VppTestCase): super(VOMTestCase, cls).tearDownClass() def test_vom_cpp(self): - """ run C++ VOM tests """ + """run C++ VOM tests""" var = "TEST_BR" built_root = os.getenv(var, None) - self.assertIsNotNone(built_root, - "Environment variable `%s' not set" % var) + self.assertIsNotNone(built_root, "Environment variable `%s' not set" % var) executable = "%s/vom_test/vom_test" % built_root - worker = Worker([executable, "vpp object model", - self.get_api_segment_prefix()], self.logger) + worker = Worker( + [executable, "vpp object model", self.get_api_segment_prefix()], self.logger + ) worker.start() timeout = 120 worker.join(timeout) @@ -37,17 +36,15 @@ class VOMTestCase(VppTestCase): if worker.result is None: try: error = True - self.logger.error( - "Timeout! Worker did not finish in %ss" % timeout) + self.logger.error("Timeout! Worker did not finish in %ss" % timeout) os.killpg(os.getpgid(worker.process.pid), signal.SIGTERM) worker.join() except: raise Exception("Couldn't kill worker-spawned process") if error: - raise Exception( - "Timeout! Worker did not finish in %ss" % timeout) + raise Exception("Timeout! Worker did not finish in %ss" % timeout) self.assert_equal(worker.result, 0, "Binary test return code") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(testRunner=VppTestRunner) diff --git a/extras/scripts/crcchecker.py b/extras/scripts/crcchecker.py index f3021c3c8b6..01cb02523d0 100755 --- a/extras/scripts/crcchecker.py +++ b/extras/scripts/crcchecker.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -''' +""" crcchecker is a tool to used to enforce that .api messages do not change. API files with a semantic version < 1.0.0 are ignored. -''' +""" import sys import os @@ -14,67 +14,75 @@ from subprocess import run, PIPE, check_output, CalledProcessError # pylint: disable=subprocess-run-check -ROOTDIR = os.path.dirname(os.path.realpath(__file__)) + '/../..' -APIGENBIN = f'{ROOTDIR}/src/tools/vppapigen/vppapigen.py' +ROOTDIR = os.path.dirname(os.path.realpath(__file__)) + "/../.." +APIGENBIN = f"{ROOTDIR}/src/tools/vppapigen/vppapigen.py" def crc_from_apigen(revision, filename): - '''Runs vppapigen with crc plugin returning a JSON object with CRCs for - all APIs in filename''' + """Runs vppapigen with crc plugin returning a JSON object with CRCs for + all APIs in filename""" if not revision and not os.path.isfile(filename): - print(f'skipping: {filename}', file=sys.stderr) + print(f"skipping: {filename}", file=sys.stderr) # Return <class 'set'> instead of <class 'dict'> return {-1} if revision: - apigen = (f'{APIGENBIN} --git-revision {revision} --includedir src ' - f'--input {filename} CRC') + apigen = ( + f"{APIGENBIN} --git-revision {revision} --includedir src " + f"--input {filename} CRC" + ) else: - apigen = (f'{APIGENBIN} --includedir src --input {filename} CRC') + apigen = f"{APIGENBIN} --includedir src --input {filename} CRC" returncode = run(apigen.split(), stdout=PIPE, stderr=PIPE) if returncode.returncode == 2: # No such file - print(f'skipping: {revision}:{filename} {returncode}', file=sys.stderr) + print(f"skipping: {revision}:{filename} {returncode}", file=sys.stderr) return {} if returncode.returncode != 0: - print(f'vppapigen failed for {revision}:{filename} with ' - 'command\n {apigen}\n error: {rv}', - returncode.stderr.decode('ascii'), file=sys.stderr) + print( + f"vppapigen failed for {revision}:{filename} with " + "command\n {apigen}\n error: {rv}", + returncode.stderr.decode("ascii"), + file=sys.stderr, + ) sys.exit(-2) return json.loads(returncode.stdout) def dict_compare(dict1, dict2): - '''Compare two dictionaries returning added, removed, modified - and equal entries''' + """Compare two dictionaries returning added, removed, modified + and equal entries""" d1_keys = set(dict1.keys()) d2_keys = set(dict2.keys()) intersect_keys = d1_keys.intersection(d2_keys) added = d1_keys - d2_keys removed = d2_keys - d1_keys - modified = {o: (dict1[o], dict2[o]) for o in intersect_keys - if dict1[o]['crc'] != dict2[o]['crc']} + modified = { + o: (dict1[o], dict2[o]) + for o in intersect_keys + if dict1[o]["crc"] != dict2[o]["crc"] + } same = set(o for o in intersect_keys if dict1[o] == dict2[o]) return added, removed, modified, same def filelist_from_git_ls(): - '''Returns a list of all api files in the git repository''' + """Returns a list of all api files in the git repository""" filelist = [] - git_ls = 'git ls-files *.api' + git_ls = "git ls-files *.api" returncode = run(git_ls.split(), stdout=PIPE, stderr=PIPE) if returncode.returncode != 0: sys.exit(returncode.returncode) - for line in returncode.stdout.decode('ascii').split('\n'): + for line in returncode.stdout.decode("ascii").split("\n"): if line: filelist.append(line) return filelist def is_uncommitted_changes(): - '''Returns true if there are uncommitted changes in the repo''' - git_status = 'git status --porcelain -uno' + """Returns true if there are uncommitted changes in the repo""" + git_status = "git status --porcelain -uno" returncode = run(git_status.split(), stdout=PIPE, stderr=PIPE) if returncode.returncode != 0: sys.exit(returncode.returncode) @@ -85,27 +93,29 @@ def is_uncommitted_changes(): def filelist_from_git_grep(filename): - '''Returns a list of api files that this <filename> api files imports.''' + """Returns a list of api files that this <filename> api files imports.""" filelist = [] try: - returncode = check_output(f'git grep -e "import .*{filename}"' - ' -- *.api', - shell=True) + returncode = check_output( + f'git grep -e "import .*{filename}"' " -- *.api", shell=True + ) except CalledProcessError: return [] - for line in returncode.decode('ascii').split('\n'): + for line in returncode.decode("ascii").split("\n"): if line: - filename, _ = line.split(':') + filename, _ = line.split(":") filelist.append(filename) return filelist def filelist_from_patchset(pattern): - '''Returns list of api files in changeset and the list of api - files they import.''' + """Returns list of api files in changeset and the list of api + files they import.""" filelist = [] - git_cmd = ('((git diff HEAD~1.. --name-only;git ls-files -m) | ' - 'sort -u | grep "\\.api$")') + git_cmd = ( + "((git diff HEAD~1.. --name-only;git ls-files -m) | " + 'sort -u | grep "\\.api$")' + ) try: res = check_output(git_cmd, shell=True) except CalledProcessError: @@ -113,7 +123,7 @@ def filelist_from_patchset(pattern): # Check for dependencies (imports) imported_files = [] - for line in res.decode('ascii').split('\n'): + for line in res.decode("ascii").split("\n"): if not line: continue if not re.search(pattern, line): @@ -126,88 +136,91 @@ def filelist_from_patchset(pattern): def is_deprecated(message): - '''Given a message, return True if message is deprecated''' - if 'options' in message: - if 'deprecated' in message['options']: + """Given a message, return True if message is deprecated""" + if "options" in message: + if "deprecated" in message["options"]: return True # recognize the deprecated format - if 'status' in message['options'] and \ - message['options']['status'] == 'deprecated': + if ( + "status" in message["options"] + and message["options"]["status"] == "deprecated" + ): print("WARNING: please use 'option deprecated;'") return True return False def is_in_progress(message): - '''Given a message, return True if message is marked as in_progress''' - if 'options' in message: - if 'in_progress' in message['options']: + """Given a message, return True if message is marked as in_progress""" + if "options" in message: + if "in_progress" in message["options"]: return True # recognize the deprecated format - if 'status' in message['options'] and \ - message['options']['status'] == 'in_progress': + if ( + "status" in message["options"] + and message["options"]["status"] == "in_progress" + ): print("WARNING: please use 'option in_progress;'") return True return False def report(new, old): - '''Given a dictionary of new crcs and old crcs, print all the + """Given a dictionary of new crcs and old crcs, print all the added, removed, modified, in-progress, deprecated messages. - Return the number of backwards incompatible changes made.''' + Return the number of backwards incompatible changes made.""" # pylint: disable=too-many-branches - new.pop('_version', None) - old.pop('_version', None) + new.pop("_version", None) + old.pop("_version", None) added, removed, modified, _ = dict_compare(new, old) backwards_incompatible = 0 # print the full list of in-progress messages # they should eventually either disappear of become supported for k in new.keys(): - newversion = int(new[k]['version']) + newversion = int(new[k]["version"]) if newversion == 0 or is_in_progress(new[k]): - print(f'in-progress: {k}') + print(f"in-progress: {k}") for k in added: - print(f'added: {k}') + print(f"added: {k}") for k in removed: - oldversion = int(old[k]['version']) - if oldversion > 0 and not is_deprecated(old[k]) and not \ - is_in_progress(old[k]): + oldversion = int(old[k]["version"]) + if oldversion > 0 and not is_deprecated(old[k]) and not is_in_progress(old[k]): backwards_incompatible += 1 - print(f'removed: ** {k}') + print(f"removed: ** {k}") else: - print(f'removed: {k}') + print(f"removed: {k}") for k in modified.keys(): - oldversion = int(old[k]['version']) - newversion = int(new[k]['version']) + oldversion = int(old[k]["version"]) + newversion = int(new[k]["version"]) if oldversion > 0 and not is_in_progress(old[k]): backwards_incompatible += 1 - print(f'modified: ** {k}') + print(f"modified: ** {k}") else: - print(f'modified: {k}') + print(f"modified: {k}") # check which messages are still there but were marked for deprecation for k in new.keys(): - newversion = int(new[k]['version']) + newversion = int(new[k]["version"]) if newversion > 0 and is_deprecated(new[k]): if k in old: if not is_deprecated(old[k]): - print(f'deprecated: {k}') + print(f"deprecated: {k}") else: - print(f'added+deprecated: {k}') + print(f"added+deprecated: {k}") return backwards_incompatible def check_patchset(): - '''Compare the changes to API messages in this changeset. + """Compare the changes to API messages in this changeset. Ignores API files with version < 1.0.0. Only considers API files located under the src directory in the repo. - ''' - files = filelist_from_patchset('^src/') - revision = 'HEAD~1' + """ + files = filelist_from_patchset("^src/") + revision = "HEAD~1" oldcrcs = {} newcrcs = {} @@ -216,7 +229,7 @@ def check_patchset(): _ = crc_from_apigen(None, filename) # Ignore removed files if isinstance(_, set) == 0: - if isinstance(_, set) == 0 and _['_version']['major'] == '0': + if isinstance(_, set) == 0 and _["_version"]["major"] == "0": continue newcrcs.update(_) @@ -225,27 +238,31 @@ def check_patchset(): backwards_incompatible = report(newcrcs, oldcrcs) if backwards_incompatible: # alert on changing production API - print("crcchecker: Changing production APIs in an incompatible way", - file=sys.stderr) + print( + "crcchecker: Changing production APIs in an incompatible way", + file=sys.stderr, + ) sys.exit(-1) else: - print('*' * 67) - print('* VPP CHECKAPI SUCCESSFULLY COMPLETED') - print('*' * 67) + print("*" * 67) + print("* VPP CHECKAPI SUCCESSFULLY COMPLETED") + print("*" * 67) def main(): - '''Main entry point.''' - parser = argparse.ArgumentParser(description='VPP CRC checker.') - parser.add_argument('--git-revision', - help='Git revision to compare against') - parser.add_argument('--dump-manifest', action='store_true', - help='Dump CRC for all messages') - parser.add_argument('--check-patchset', action='store_true', - help='Check patchset for backwards incompatbile changes') - parser.add_argument('files', nargs='*') - parser.add_argument('--diff', help='Files to compare (on filesystem)', - nargs=2) + """Main entry point.""" + parser = argparse.ArgumentParser(description="VPP CRC checker.") + parser.add_argument("--git-revision", help="Git revision to compare against") + parser.add_argument( + "--dump-manifest", action="store_true", help="Dump CRC for all messages" + ) + parser.add_argument( + "--check-patchset", + action="store_true", + help="Check patchset for backwards incompatbile changes", + ) + parser.add_argument("files", nargs="*") + parser.add_argument("--diff", help="Files to compare (on filesystem)", nargs=2) args = parser.parse_args() @@ -267,17 +284,16 @@ def main(): for filename in files: crcs.update(crc_from_apigen(args.git_revision, filename)) for k, value in crcs.items(): - print(f'{k}: {value}') + print(f"{k}: {value}") sys.exit(0) # Find changes between current patchset and given revision (previous) if args.check_patchset: if args.git_revision: - print('Argument git-revision ignored', file=sys.stderr) + print("Argument git-revision ignored", file=sys.stderr) # Check there are no uncomitted changes if is_uncommitted_changes(): - print('Please stash or commit changes in workspace', - file=sys.stderr) + print("Please stash or commit changes in workspace", file=sys.stderr) sys.exit(-1) check_patchset() sys.exit(0) @@ -286,7 +302,7 @@ def main(): # Find changes between a given file and a revision files = args.files if args.files else filelist_from_git_ls() - revision = args.git_revision if args.git_revision else 'HEAD~1' + revision = args.git_revision if args.git_revision else "HEAD~1" oldcrcs = {} newcrcs = {} @@ -299,13 +315,16 @@ def main(): if args.check_patchset: if backwards_incompatible: # alert on changing production API - print("crcchecker: Changing production APIs in an incompatible way", file=sys.stderr) + print( + "crcchecker: Changing production APIs in an incompatible way", + file=sys.stderr, + ) sys.exit(-1) else: - print('*' * 67) - print('* VPP CHECKAPI SUCCESSFULLY COMPLETED') - print('*' * 67) + print("*" * 67) + print("* VPP CHECKAPI SUCCESSFULLY COMPLETED") + print("*" * 67) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/extras/scripts/list_api_changes.py b/extras/scripts/list_api_changes.py index ac8cf477810..7433f542aaa 100755 --- a/extras/scripts/list_api_changes.py +++ b/extras/scripts/list_api_changes.py @@ -4,21 +4,21 @@ import fnmatch import os import subprocess -starttag = 'v19.08-rc0' -endtag = 'HEAD' +starttag = "v19.08-rc0" +endtag = "HEAD" emit_md = True apifiles = [] -for root, dirnames, filenames in os.walk('.'): - for filename in fnmatch.filter(filenames, '*.api'): +for root, dirnames, filenames in os.walk("."): + for filename in fnmatch.filter(filenames, "*.api"): apifiles.append(os.path.join(root, filename)) for f in apifiles: - commits = subprocess.check_output(['git', 'log', - '--oneline', starttag + '..' + endtag, - f]) + commits = subprocess.check_output( + ["git", "log", "--oneline", starttag + ".." + endtag, f] + ) if commits: - if f[0:2] == './': + if f[0:2] == "./": f = f[2:] if emit_md: print("| @c %s ||" % f) @@ -27,9 +27,10 @@ for f in apifiles: parts = line.strip().split() commit = parts[0] message = b" ".join(parts[1:]).decode().replace("|", r"\|") - print("| [%s](https://gerrit.fd.io/r/gitweb?" - "p=vpp.git;a=commit;h=%s) | %s |" % ( - commit, commit, message)) + print( + "| [%s](https://gerrit.fd.io/r/gitweb?" + "p=vpp.git;a=commit;h=%s) | %s |" % (commit, commit, message) + ) print() else: print(f) diff --git a/extras/vpp_config/scripts/dpdk-devbind.py b/extras/vpp_config/scripts/dpdk-devbind.py index 80edb3b9eea..140e4346894 100755 --- a/extras/vpp_config/scripts/dpdk-devbind.py +++ b/extras/vpp_config/scripts/dpdk-devbind.py @@ -56,9 +56,10 @@ args = [] def usage(): - '''Print usage information for the program''' + """Print usage information for the program""" argv0 = basename(sys.argv[0]) - print(""" + print( + """ Usage: ------ @@ -115,33 +116,40 @@ To unbind 0000:01:00.0 from using any driver To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver %(argv0)s -b ixgbe 02:00.0 02:00.1 - """ % locals()) # replace items from local variables + """ + % locals() + ) # replace items from local variables # This is roughly compatible with check_output function in subprocess module # which is only available in python 2.7. def check_output(args, stderr=None): - '''Run a command and capture its output''' - return subprocess.Popen(args, stdout=subprocess.PIPE, - stderr=stderr).communicate()[0] + """Run a command and capture its output""" + return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=stderr).communicate()[ + 0 + ] def find_module(mod): - '''find the .ko file for kernel module named mod. + """find the .ko file for kernel module named mod. Searches the $RTE_SDK/$RTE_TARGET directory, the kernel modules directory and finally under the parent directory of - the script ''' + the script""" # check $RTE_SDK/$RTE_TARGET directory - if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ: - path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'], - os.environ['RTE_TARGET'], mod) + if "RTE_SDK" in os.environ and "RTE_TARGET" in os.environ: + path = "%s/%s/kmod/%s.ko" % ( + os.environ["RTE_SDK"], + os.environ["RTE_TARGET"], + mod, + ) if exists(path): return path # check using depmod try: - depmod_out = check_output(["modinfo", "-n", mod], - stderr=subprocess.STDOUT).lower() + depmod_out = check_output( + ["modinfo", "-n", mod], stderr=subprocess.STDOUT + ).lower() if "error" not in depmod_out: path = depmod_out.strip() if exists(path): @@ -151,7 +159,7 @@ def find_module(mod): # check for a copy based off current path tools_dir = dirname(abspath(sys.argv[0])) - if (tools_dir.endswith("tools")): + if tools_dir.endswith("tools"): base_dir = dirname(tools_dir) find_out = check_output(["find", base_dir, "-name", mod + ".ko"]) if len(find_out) > 0: # something matched @@ -161,7 +169,7 @@ def find_module(mod): def check_modules(): - '''Checks that igb_uio is loaded''' + """Checks that igb_uio is loaded""" global dpdk_drivers # list of supported modules @@ -170,20 +178,21 @@ def check_modules(): # first check if module is loaded try: # Get list of sysfs modules (both built-in and dynamically loaded) - sysfs_path = '/sys/module/' + sysfs_path = "/sys/module/" # Get the list of directories in sysfs_path - sysfs_mods = [os.path.join(sysfs_path, o) for o - in os.listdir(sysfs_path) - if os.path.isdir(os.path.join(sysfs_path, o))] + sysfs_mods = [ + os.path.join(sysfs_path, o) + for o in os.listdir(sysfs_path) + if os.path.isdir(os.path.join(sysfs_path, o)) + ] # Extract the last element of '/sys/module/abc' in the array - sysfs_mods = [a.split('/')[-1] for a in sysfs_mods] + sysfs_mods = [a.split("/")[-1] for a in sysfs_mods] # special case for vfio_pci (module is named vfio-pci, # but its .ko is named vfio_pci) - sysfs_mods = map(lambda a: - a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods) + sysfs_mods = map(lambda a: a if a != "vfio_pci" else "vfio-pci", sysfs_mods) for mod in mods: if mod["Name"] in sysfs_mods: @@ -204,12 +213,12 @@ def check_modules(): def has_driver(dev_id): - '''return true if a device is assigned to a driver. False otherwise''' + """return true if a device is assigned to a driver. False otherwise""" return "Driver_str" in devices[dev_id] def get_pci_device_details(dev_id): - '''This function gets additional details for a PCI device''' + """This function gets additional details for a PCI device""" device = {} extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines() @@ -225,8 +234,7 @@ def get_pci_device_details(dev_id): device["Interface"] = "" for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id): if "net" in dirs: - device["Interface"] = \ - ",".join(os.listdir(os.path.join(base, "net"))) + device["Interface"] = ",".join(os.listdir(os.path.join(base, "net"))) break # check if a port is used for ssh connection device["Ssh_if"] = False @@ -236,9 +244,9 @@ def get_pci_device_details(dev_id): def get_nic_details(): - '''This function populates the "devices" dictionary. The keys used are + """This function populates the "devices" dictionary. The keys used are the pci addresses (domain:bus:slot.func). The values are themselves - dictionaries - one for each NIC.''' + dictionaries - one for each NIC.""" global devices global dpdk_drivers @@ -249,7 +257,7 @@ def get_nic_details(): dev = {} dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines() for dev_line in dev_lines: - if (len(dev_line) == 0): + if len(dev_line) == 0: if dev["Class"][0:2] == NETWORK_BASE_CLASS: # convert device and vendor ids to numbers, then add to global dev["Vendor"] = int(dev["Vendor"], 16) @@ -265,12 +273,13 @@ def get_nic_details(): ssh_if = [] route = check_output(["ip", "-o", "route"]) # filter out all lines for 169.254 routes - route = "\n".join(filter(lambda ln: not ln.startswith("169.254"), - route.decode().splitlines())) + route = "\n".join( + filter(lambda ln: not ln.startswith("169.254"), route.decode().splitlines()) + ) rt_info = route.split() for i in range(len(rt_info) - 1): if rt_info[i] == "dev": - ssh_if.append(rt_info[i+1]) + ssh_if.append(rt_info[i + 1]) # based on the basic info, get extended text details for d in devices.keys(): @@ -288,8 +297,7 @@ def get_nic_details(): if "Module_str" in devices[d]: for driver in dpdk_drivers: if driver not in devices[d]["Module_str"]: - devices[d]["Module_str"] = \ - devices[d]["Module_str"] + ",%s" % driver + devices[d]["Module_str"] = devices[d]["Module_str"] + ",%s" % driver else: devices[d]["Module_str"] = ",".join(dpdk_drivers) @@ -302,9 +310,9 @@ def get_nic_details(): def get_crypto_details(): - '''This function populates the "devices" dictionary. The keys used are + """This function populates the "devices" dictionary. The keys used are the pci addresses (domain:bus:slot.func). The values are themselves - dictionaries - one for each NIC.''' + dictionaries - one for each NIC.""" global devices global dpdk_drivers @@ -315,8 +323,8 @@ def get_crypto_details(): dev = {} dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines() for dev_line in dev_lines: - if (len(dev_line) == 0): - if (dev["Class"][0:2] == CRYPTO_BASE_CLASS): + if len(dev_line) == 0: + if dev["Class"][0:2] == CRYPTO_BASE_CLASS: # convert device and vendor ids to numbers, then add to global dev["Vendor"] = int(dev["Vendor"], 16) dev["Device"] = int(dev["Device"], 16) @@ -336,8 +344,7 @@ def get_crypto_details(): if "Module_str" in devices[d]: for driver in dpdk_drivers: if driver not in devices[d]["Module_str"]: - devices[d]["Module_str"] = \ - devices[d]["Module_str"] + ",%s" % driver + devices[d]["Module_str"] = devices[d]["Module_str"] + ",%s" % driver else: devices[d]["Module_str"] = ",".join(dpdk_drivers) @@ -350,9 +357,9 @@ def get_crypto_details(): def dev_id_from_dev_name(dev_name): - '''Take a device "name" - a string passed in by user to identify a NIC + """Take a device "name" - a string passed in by user to identify a NIC device, and determine the device id - i.e. the domain:bus:slot.func - for - it, which can then be used to index into the devices array''' + it, which can then be used to index into the devices array""" # check if it's already a suitable index if dev_name in devices: @@ -366,23 +373,29 @@ def dev_id_from_dev_name(dev_name): if dev_name in devices[d]["Interface"].split(","): return devices[d]["Slot"] # if nothing else matches - error - print("Unknown device: %s. " - "Please specify device in \"bus:slot.func\" format" % dev_name) + print( + "Unknown device: %s. " + 'Please specify device in "bus:slot.func" format' % dev_name + ) sys.exit(1) def unbind_one(dev_id, force): - '''Unbind the device identified by "dev_id" from its current driver''' + """Unbind the device identified by "dev_id" from its current driver""" dev = devices[dev_id] if not has_driver(dev_id): - print("%s %s %s is not currently managed by any driver\n" % - (dev["Slot"], dev["Device_str"], dev["Interface"])) + print( + "%s %s %s is not currently managed by any driver\n" + % (dev["Slot"], dev["Device_str"], dev["Interface"]) + ) return # prevent us disconnecting ourselves if dev["Ssh_if"] and not force: - print("Routing table indicates that interface %s is active. " - "Skipping unbind" % (dev_id)) + print( + "Routing table indicates that interface %s is active. " + "Skipping unbind" % (dev_id) + ) return # write to /sys to unbind @@ -390,30 +403,30 @@ def unbind_one(dev_id, force): try: f = open(filename, "a") except: - print("Error: unbind failed for %s - Cannot open %s" - % (dev_id, filename)) + print("Error: unbind failed for %s - Cannot open %s" % (dev_id, filename)) sys.exit(1) f.write(dev_id) f.close() def bind_one(dev_id, driver, force): - '''Bind the device given by "dev_id" to the driver "driver". If the device - is already bound to a different driver, it will be unbound first''' + """Bind the device given by "dev_id" to the driver "driver". If the device + is already bound to a different driver, it will be unbound first""" dev = devices[dev_id] saved_driver = None # used to rollback any unbind in case of failure # prevent disconnection of our ssh session if dev["Ssh_if"] and not force: - print("Routing table indicates that interface %s is active. " - "Not modifying" % (dev_id)) + print( + "Routing table indicates that interface %s is active. " + "Not modifying" % (dev_id) + ) return # unbind any existing drivers we don't want if has_driver(dev_id): if dev["Driver_str"] == driver: - print("%s already bound to driver %s, skipping\n" - % (dev_id, driver)) + print("%s already bound to driver %s, skipping\n" % (dev_id, driver)) return else: saved_driver = dev["Driver_str"] @@ -426,15 +439,16 @@ def bind_one(dev_id, driver, force): try: f = open(filename, "w") except: - print("Error: bind failed for %s - Cannot open %s" - % (dev_id, filename)) + print("Error: bind failed for %s - Cannot open %s" % (dev_id, filename)) return try: f.write("%04x %04x" % (dev["Vendor"], dev["Device"])) f.close() except: - print("Error: bind failed for %s - Cannot write new PCI ID to " - "driver %s" % (dev_id, driver)) + print( + "Error: bind failed for %s - Cannot write new PCI ID to " + "driver %s" % (dev_id, driver) + ) return # do the bind by writing to /sys @@ -442,8 +456,7 @@ def bind_one(dev_id, driver, force): try: f = open(filename, "a") except: - print("Error: bind failed for %s - Cannot open %s" - % (dev_id, filename)) + print("Error: bind failed for %s - Cannot open %s" % (dev_id, filename)) if saved_driver is not None: # restore any previous driver bind_one(dev_id, saved_driver, force) return @@ -457,8 +470,7 @@ def bind_one(dev_id, driver, force): tmp = get_pci_device_details(dev_id) if "Driver_str" in tmp and tmp["Driver_str"] == driver: return - print("Error: bind failed for %s - Cannot bind to driver %s" - % (dev_id, driver)) + print("Error: bind failed for %s - Cannot bind to driver %s" % (dev_id, driver)) if saved_driver is not None: # restore any previous driver bind_one(dev_id, saved_driver, force) return @@ -491,8 +503,7 @@ def bind_all(dev_list, driver, force=False): continue # update information about this device - devices[d] = dict(devices[d].items() + - get_pci_device_details(d).items()) + devices[d] = dict(devices[d].items() + get_pci_device_details(d).items()) # check if updated information indicates that the device was bound if "Driver_str" in devices[d]: @@ -500,20 +511,21 @@ def bind_all(dev_list, driver, force=False): def display_devices(title, dev_list, extra_params=None): - '''Displays to the user the details of a list of devices given in + """Displays to the user the details of a list of devices given in "dev_list". The "extra_params" parameter, if given, should contain a string with %()s fields in it for replacement by the named fields in each - device's dictionary.''' + device's dictionary.""" strings = [] # this holds the strings to print. We sort before printing print("\n%s" % title) - print("="*len(title)) + print("=" * len(title)) if len(dev_list) == 0: strings.append("<none>") else: for dev in dev_list: if extra_params is not None: - strings.append("%s '%s' %s" % (dev["Slot"], - dev["Device_str"], extra_params % dev)) + strings.append( + "%s '%s' %s" % (dev["Slot"], dev["Device_str"], extra_params % dev) + ) else: strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"])) # sort before printing, so that the entries appear in PCI order @@ -522,9 +534,9 @@ def display_devices(title, dev_list, extra_params=None): def show_status(): - '''Function called when the script is passed the "--status" option. + """Function called when the script is passed the "--status" option. Displays to the user what devices are bound to the igb_uio driver, the - kernel driver or to no driver''' + kernel driver or to no driver""" global dpdk_drivers kernel_drv = [] dpdk_drv = [] @@ -532,7 +544,7 @@ def show_status(): # split our list of network devices into the three categories above for d in devices.keys(): - if (NETWORK_BASE_CLASS in devices[d]["Class"]): + if NETWORK_BASE_CLASS in devices[d]["Class"]: if not has_driver(d): no_drv.append(devices[d]) continue @@ -542,11 +554,16 @@ def show_status(): kernel_drv.append(devices[d]) # print each category separately, so we can clearly see what's used by DPDK - display_devices("Network devices using DPDK-compatible driver", dpdk_drv, - "drv=%(Driver_str)s unused=%(Module_str)s") - display_devices("Network devices using kernel driver", kernel_drv, - "if=%(Interface)s drv=%(Driver_str)s " - "unused=%(Module_str)s %(Active)s") + display_devices( + "Network devices using DPDK-compatible driver", + dpdk_drv, + "drv=%(Driver_str)s unused=%(Module_str)s", + ) + display_devices( + "Network devices using kernel driver", + kernel_drv, + "if=%(Interface)s drv=%(Driver_str)s " "unused=%(Module_str)s %(Active)s", + ) display_devices("Other network devices", no_drv, "unused=%(Module_str)s") # split our list of crypto devices into the three categories above @@ -555,7 +572,7 @@ def show_status(): no_drv = [] for d in devices.keys(): - if (CRYPTO_BASE_CLASS in devices[d]["Class"]): + if CRYPTO_BASE_CLASS in devices[d]["Class"]: if not has_driver(d): no_drv.append(devices[d]) continue @@ -564,17 +581,22 @@ def show_status(): else: kernel_drv.append(devices[d]) - display_devices("Crypto devices using DPDK-compatible driver", dpdk_drv, - "drv=%(Driver_str)s unused=%(Module_str)s") - display_devices("Crypto devices using kernel driver", kernel_drv, - "drv=%(Driver_str)s " - "unused=%(Module_str)s") + display_devices( + "Crypto devices using DPDK-compatible driver", + dpdk_drv, + "drv=%(Driver_str)s unused=%(Module_str)s", + ) + display_devices( + "Crypto devices using kernel driver", + kernel_drv, + "drv=%(Driver_str)s " "unused=%(Module_str)s", + ) display_devices("Other crypto devices", no_drv, "unused=%(Module_str)s") def parse_args(): - '''Parses the command-line arguments given by the user and takes the - appropriate action for each''' + """Parses the command-line arguments given by the user and takes the + appropriate action for each""" global b_flag global status_flag global force_flag @@ -584,9 +606,11 @@ def parse_args(): sys.exit(0) try: - opts, args = getopt.getopt(sys.argv[1:], "b:us", - ["help", "usage", "status", "force", - "bind=", "unbind"]) + opts, args = getopt.getopt( + sys.argv[1:], + "b:us", + ["help", "usage", "status", "force", "bind=", "unbind"], + ) except getopt.GetoptError as error: print(str(error)) print("Run '%s --usage' for further information" % sys.argv[0]) @@ -611,15 +635,14 @@ def parse_args(): def do_arg_actions(): - '''do the actual action requested by the user''' + """do the actual action requested by the user""" global b_flag global status_flag global force_flag global args if b_flag is None and not status_flag: - print("Error: No action specified for devices." - "Please give a -b or -u option") + print("Error: No action specified for devices." "Please give a -b or -u option") print("Run '%s --usage' for further information" % sys.argv[0]) sys.exit(1) @@ -640,7 +663,7 @@ def do_arg_actions(): def main(): - '''program main function''' + """program main function""" parse_args() check_modules() get_nic_details() diff --git a/extras/vpp_config/setup.py b/extras/vpp_config/setup.py index 64f75d7cc89..010920bd7d5 100644 --- a/extras/vpp_config/setup.py +++ b/extras/vpp_config/setup.py @@ -1,33 +1,31 @@ from setuptools import setup -setup(name="vpp_config", - version="20.05.1", - author="John DeNisco", - author_email="jdenisco@cisco.com", - description="VPP Configuration Utility", - license='Apache-2.0', - keywords="vppconfig", - url='https://wiki.fd.io/view/VPP', - py_modules=['vpp_config'], - install_requires=['distro', 'pyyaml', 'requests'], - extra_requires=["ipaddress; python_version < '3.3'"], - packages=['vpplib'], - entry_points={ - 'console_scripts': ['vpp-config=vpp_config:config_main'], - }, - data_files=[('vpp/vpp-config/scripts', ['scripts/dpdk-devbind.py']), - ('vpp/vpp-config/configs', ['data/auto-config.yaml']), - ('vpp/vpp-config/configs', ['data/cloud-config.iso']), - ('vpp/vpp-config/configs', - ['data/iperf-centos.xml.template']), - ('vpp/vpp-config/configs', - ['data/iperf-ubuntu.xml.template']), - ('vpp/vpp-config/dryrun/sysctl.d', - ['data/80-vpp.conf.template']), - ('vpp/vpp-config/dryrun/default', ['data/grub.template']), - ('vpp/vpp-config/dryrun/vpp', - ['data/startup.conf.template']), - ], - long_description="The VPP configuration utility can be used to " - "easily configure VPP.", - ) +setup( + name="vpp_config", + version="20.05.1", + author="John DeNisco", + author_email="jdenisco@cisco.com", + description="VPP Configuration Utility", + license="Apache-2.0", + keywords="vppconfig", + url="https://wiki.fd.io/view/VPP", + py_modules=["vpp_config"], + install_requires=["distro", "pyyaml", "requests"], + extra_requires=["ipaddress; python_version < '3.3'"], + packages=["vpplib"], + entry_points={ + "console_scripts": ["vpp-config=vpp_config:config_main"], + }, + data_files=[ + ("vpp/vpp-config/scripts", ["scripts/dpdk-devbind.py"]), + ("vpp/vpp-config/configs", ["data/auto-config.yaml"]), + ("vpp/vpp-config/configs", ["data/cloud-config.iso"]), + ("vpp/vpp-config/configs", ["data/iperf-centos.xml.template"]), + ("vpp/vpp-config/configs", ["data/iperf-ubuntu.xml.template"]), + ("vpp/vpp-config/dryrun/sysctl.d", ["data/80-vpp.conf.template"]), + ("vpp/vpp-config/dryrun/default", ["data/grub.template"]), + ("vpp/vpp-config/dryrun/vpp", ["data/startup.conf.template"]), + ], + long_description="The VPP configuration utility can be used to " + "easily configure VPP.", +) diff --git a/extras/vpp_config/vpp_config.py b/extras/vpp_config/vpp_config.py index e863cde854e..74051300677 100755 --- a/extras/vpp_config/vpp_config.py +++ b/extras/vpp_config/vpp_config.py @@ -32,16 +32,16 @@ try: except NameError: pass -VPP_DRYRUNDIR = '/vpp/vpp-config/dryrun' -VPP_AUTO_CONFIGURATION_FILE = '/vpp/vpp-config/configs/auto-config.yaml' -VPP_HUGE_PAGE_FILE = '/vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf' -VPP_STARTUP_FILE = '/vpp/vpp-config/dryrun/vpp/startup.conf' -VPP_GRUB_FILE = '/vpp/vpp-config/dryrun/default/grub' -VPP_REAL_HUGE_PAGE_FILE = '/etc/sysctl.d/80-vpp.conf' -VPP_REAL_STARTUP_FILE = '/etc/vpp/startup.conf' -VPP_REAL_GRUB_FILE = '/etc/default/grub' +VPP_DRYRUNDIR = "/vpp/vpp-config/dryrun" +VPP_AUTO_CONFIGURATION_FILE = "/vpp/vpp-config/configs/auto-config.yaml" +VPP_HUGE_PAGE_FILE = "/vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf" +VPP_STARTUP_FILE = "/vpp/vpp-config/dryrun/vpp/startup.conf" +VPP_GRUB_FILE = "/vpp/vpp-config/dryrun/default/grub" +VPP_REAL_HUGE_PAGE_FILE = "/etc/sysctl.d/80-vpp.conf" +VPP_REAL_STARTUP_FILE = "/etc/vpp/startup.conf" +VPP_REAL_GRUB_FILE = "/etc/default/grub" -rootdir = '' +rootdir = "" def autoconfig_yn(question, default): @@ -57,16 +57,16 @@ def autoconfig_yn(question, default): """ input_valid = False default = default.lower() - answer = '' + answer = "" while not input_valid: answer = input(question) if len(answer) == 0: answer = default - if re.findall(r'[YyNn]', answer): + if re.findall(r"[YyNn]", answer): input_valid = True answer = answer[0].lower() else: - print ("Please answer Y, N or Return.") + print("Please answer Y, N or Return.") return answer @@ -86,24 +86,21 @@ def autoconfig_cp(node, src, dst): # If the destination file exist, create a copy if one does not already # exist - ofile = dst + '.orig' - (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(dst)) + ofile = dst + ".orig" + (ret, stdout, stderr) = VPPUtil.exec_command("ls {}".format(dst)) if ret == 0: - cmd = 'cp {} {}'.format(dst, ofile) + cmd = "cp {} {}".format(dst, ofile) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, - node['host'], - stdout, - stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) # Copy the source file - cmd = 'cp {} {}'.format(src, os.path.dirname(dst)) + cmd = "cp {} {}".format(src, os.path.dirname(dst)) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'. - format(cmd, node['host'], stderr)) + raise RuntimeError("{} failed on node {} {}".format(cmd, node["host"], stderr)) def autoconfig_diff(node, src, dst): @@ -124,12 +121,10 @@ def autoconfig_diff(node, src, dst): # Diff the files and return the output cmd = "diff {} {}".format(src, dst) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) - if stderr != '': - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, - node['host'], - ret, - stderr)) + if stderr != "": + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], ret, stderr) + ) return stdout @@ -160,13 +155,15 @@ def autoconfig_hugepage_apply(node, ask_questions=True): """ diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE) - if diffs != '': - print ("These are the changes we will apply to") - print ("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE)) - print (diffs) + if diffs != "": + print("These are the changes we will apply to") + print("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE)) + print(diffs) if ask_questions: - answer = autoconfig_yn("\nAre you sure you want to apply these changes [Y/n]? ", 'y') - if answer == 'n': + answer = autoconfig_yn( + "\nAre you sure you want to apply these changes [Y/n]? ", "y" + ) + if answer == "n": return -1 # Copy and sysctl @@ -174,10 +171,11 @@ def autoconfig_hugepage_apply(node, ask_questions=True): cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) else: - print ('\nThere are no changes to the huge page configuration.') + print("\nThere are no changes to the huge page configuration.") return 0 @@ -196,19 +194,21 @@ def autoconfig_vpp_apply(node, ask_questions=True): """ diffs = autoconfig_diff(node, VPP_REAL_STARTUP_FILE, rootdir + VPP_STARTUP_FILE) - if diffs != '': - print ("These are the changes we will apply to") - print ("the VPP startup file ({}).\n".format(VPP_REAL_STARTUP_FILE)) - print (diffs) + if diffs != "": + print("These are the changes we will apply to") + print("the VPP startup file ({}).\n".format(VPP_REAL_STARTUP_FILE)) + print(diffs) if ask_questions: - answer = autoconfig_yn("\nAre you sure you want to apply these changes [Y/n]? ", 'y') - if answer == 'n': + answer = autoconfig_yn( + "\nAre you sure you want to apply these changes [Y/n]? ", "y" + ) + if answer == "n": return -1 # Copy the VPP startup autoconfig_cp(node, rootdir + VPP_STARTUP_FILE, VPP_REAL_STARTUP_FILE) else: - print ('\nThere are no changes to VPP startup.') + print("\nThere are no changes to VPP startup.") return 0 @@ -226,49 +226,52 @@ def autoconfig_grub_apply(node, ask_questions=True): """ - print ("\nThe configured grub cmdline looks like this:") - configured_cmdline = node['grub']['default_cmdline'] - current_cmdline = node['grub']['current_cmdline'] - print (configured_cmdline) - print ("\nThe current boot cmdline looks like this:") - print (current_cmdline) + print("\nThe configured grub cmdline looks like this:") + configured_cmdline = node["grub"]["default_cmdline"] + current_cmdline = node["grub"]["current_cmdline"] + print(configured_cmdline) + print("\nThe current boot cmdline looks like this:") + print(current_cmdline) if ask_questions: question = "\nDo you want to keep the current boot cmdline [Y/n]? " - answer = autoconfig_yn(question, 'y') - if answer == 'y': + answer = autoconfig_yn(question, "y") + if answer == "y": return - node['grub']['keep_cmdline'] = False + node["grub"]["keep_cmdline"] = False # Diff the file diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE) - if diffs != '': - print ("These are the changes we will apply to") - print ("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE)) - print (diffs) + if diffs != "": + print("These are the changes we will apply to") + print("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE)) + print(diffs) if ask_questions: - answer = autoconfig_yn("\nAre you sure you want to apply these changes [y/N]? ", 'n') - if answer == 'n': + answer = autoconfig_yn( + "\nAre you sure you want to apply these changes [y/N]? ", "n" + ) + if answer == "n": return -1 # Copy and update grub autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE) distro = VPPUtil.get_linux_distro() - if distro[0] == 'Ubuntu': + if distro[0] == "Ubuntu": cmd = "update-grub" else: cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) - print ("There have been changes to the GRUB config a", end=' ') - print ("reboot will be required.") + print("There have been changes to the GRUB config a", end=" ") + print("reboot will be required.") return -1 else: - print ('\nThere are no changes to the GRUB config.') + print("\nThere are no changes to the GRUB config.") return 0 @@ -289,15 +292,15 @@ def autoconfig_apply(ask_questions=True): vutil = VPPUtil() pkgs = vutil.get_installed_vpp_pkgs() if len(pkgs) == 0: - print ("\nVPP is not installed, Install VPP with option 4.") + print("\nVPP is not installed, Install VPP with option 4.") return acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE) if ask_questions: - print ("\nWe are now going to configure your system(s).\n") - answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", 'y') - if answer == 'n': + print("\nWe are now going to configure your system(s).\n") + answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", "y") + if answer == "n": return nodes = acfg.get_nodes() @@ -369,7 +372,9 @@ def autoconfig_dryrun(ask_questions=True): for i in nodes.items(): node = i[1] if not acfg.has_interfaces(node): - print("\nThere are no VPP interfaces configured, please configure at least 1.") + print( + "\nThere are no VPP interfaces configured, please configure at least 1." + ) return # Modify CPU @@ -414,34 +419,31 @@ def autoconfig_install(): pkgs = vutil.get_installed_vpp_pkgs() if len(pkgs) > 0: - print ("\nThese packages are installed on node {}" - .format(node['host'])) - print ("{:25} {}".format("Name", "Version")) + print("\nThese packages are installed on node {}".format(node["host"])) + print("{:25} {}".format("Name", "Version")) for pkg in pkgs: try: - print ("{:25} {}".format( - pkg['name'], pkg['version'])) + print("{:25} {}".format(pkg["name"], pkg["version"])) except KeyError: - print ("{}".format(pkg['name'])) + print("{}".format(pkg["name"])) question = "\nDo you want to uninstall these " question += "packages [y/N]? " - answer = autoconfig_yn(question, 'n') - if answer == 'y': + answer = autoconfig_yn(question, "n") + if answer == "y": logger.setLevel(logging.INFO) vutil.uninstall_vpp(node) else: - print ("\nThere are no VPP packages on node {}." - .format(node['host'])) + print("\nThere are no VPP packages on node {}.".format(node["host"])) question = "Do you want to install VPP [Y/n]? " - answer = autoconfig_yn(question, 'y') - if answer == 'y': + answer = autoconfig_yn(question, "y") + if answer == "y": question = "Do you want to install the release version [Y/n]? " - answer = autoconfig_yn(question, 'y') - if answer == 'y': - branch = 'release' + answer = autoconfig_yn(question, "y") + if answer == "y": + branch = "release" else: - branch = 'master' + branch = "master" logger.setLevel(logging.INFO) vutil.install_vpp(node, branch) @@ -486,9 +488,9 @@ def autoconfig_create_iperf_vm(): """ acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE) - acfg.destroy_iperf_vm('iperf-server') + acfg.destroy_iperf_vm("iperf-server") acfg.create_and_bridge_iperf_virtual_interface() - acfg.create_iperf_vm('iperf-server') + acfg.create_iperf_vm("iperf-server") def autoconfig_not_implemented(): @@ -497,7 +499,7 @@ def autoconfig_not_implemented(): """ - print ("\nThis Feature is not implemented yet....") + print("\nThis Feature is not implemented yet....") def autoconfig_basic_test_menu(): @@ -506,28 +508,28 @@ def autoconfig_basic_test_menu(): """ - basic_menu_text = '\nWhat would you like to do?\n\n\ + basic_menu_text = "\nWhat would you like to do?\n\n\ 1) List/Create Simple IPv4 Setup\n\ 2) Create an iperf VM and Connect to VPP an interface\n\ -9 or q) Back to main menu.' +9 or q) Back to main menu." - print ("{}".format(basic_menu_text)) + print("{}".format(basic_menu_text)) input_valid = False - answer = '' + answer = "" while not input_valid: answer = input("\nCommand: ") if len(answer) > 1: - print ("Please enter only 1 character.") + print("Please enter only 1 character.") continue - if re.findall(r'[Qq1-29]', answer): + if re.findall(r"[Qq1-29]", answer): input_valid = True answer = answer[0].lower() else: - print ("Please enter a character between 1 and 2 or 9.") + print("Please enter a character between 1 and 2 or 9.") - if answer == '9': - answer = 'q' + if answer == "9": + answer = "q" return answer @@ -540,17 +542,17 @@ def autoconfig_basic_test(): vutil = VPPUtil() pkgs = vutil.get_installed_vpp_pkgs() if len(pkgs) == 0: - print ("\nVPP is not installed, install VPP with option 4.") + print("\nVPP is not installed, install VPP with option 4.") return - answer = '' - while answer != 'q': + answer = "" + while answer != "q": answer = autoconfig_basic_test_menu() - if answer == '1': + if answer == "1": autoconfig_ipv4_setup() - elif answer == '2': + elif answer == "2": autoconfig_create_iperf_vm() - elif answer == '9' or answer == 'q': + elif answer == "9" or answer == "q": return else: autoconfig_not_implemented() @@ -562,30 +564,32 @@ def autoconfig_main_menu(): """ - main_menu_text = '\nWhat would you like to do?\n\n\ + main_menu_text = "\nWhat would you like to do?\n\n\ 1) Show basic system information\n\ 2) Dry Run (Saves the configuration files in {}/vpp/vpp-config/dryrun.\n\ 3) Full configuration (WARNING: This will change the system configuration)\n\ 4) List/Install/Uninstall VPP.\n\ -q) Quit'.format(rootdir, rootdir) +q) Quit".format( + rootdir, rootdir + ) # 5) Dry Run from {}/vpp/vpp-config/auto-config.yaml (will not ask questions).\n\ # 6) Install QEMU patch (Needed when running openstack).\n\ - print ("{}".format(main_menu_text)) + print("{}".format(main_menu_text)) input_valid = False - answer = '' + answer = "" while not input_valid: answer = input("\nCommand: ") if len(answer) > 1: - print ("Please enter only 1 character.") + print("Please enter only 1 character.") continue - if re.findall(r'[Qq1-4]', answer): + if re.findall(r"[Qq1-4]", answer): input_valid = True answer = answer[0].lower() else: - print ("Please enter a character between 1 and 4 or q.") + print("Please enter a character between 1 and 4 or q.") return answer @@ -599,18 +603,18 @@ def autoconfig_main(): # Setup autoconfig_setup() - answer = '' - while answer != 'q': + answer = "" + while answer != "q": answer = autoconfig_main_menu() - if answer == '1': + if answer == "1": autoconfig_show_system() - elif answer == '2': + elif answer == "2": autoconfig_dryrun() - elif answer == '3': + elif answer == "3": autoconfig_apply() - elif answer == '4': + elif answer == "4": autoconfig_install() - elif answer == 'q': + elif answer == "q": return else: autoconfig_not_implemented() @@ -627,53 +631,65 @@ def autoconfig_setup(ask_questions=True): global rootdir distro = VPPUtil.get_linux_distro() - if distro[0] == 'Ubuntu': - rootdir = '/usr/local' + if distro[0] == "Ubuntu": + rootdir = "/usr/local" else: - rootdir = '/usr' + rootdir = "/usr" # If there is a system configuration file use that, if not use the initial auto-config file filename = rootdir + VPP_AUTO_CONFIGURATION_FILE if os.path.isfile(filename) is True: acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE) else: - raise RuntimeError('The Auto configuration file does not exist {}'. - format(filename)) + raise RuntimeError( + "The Auto configuration file does not exist {}".format(filename) + ) if ask_questions: - print ("\nWelcome to the VPP system configuration utility") + print("\nWelcome to the VPP system configuration utility") - print ("\nThese are the files we will modify:") - print (" /etc/vpp/startup.conf") - print (" /etc/sysctl.d/80-vpp.conf") - print (" /etc/default/grub") + print("\nThese are the files we will modify:") + print(" /etc/vpp/startup.conf") + print(" /etc/sysctl.d/80-vpp.conf") + print(" /etc/default/grub") - print ( + print( "\nBefore we change them, we'll create working copies in " - "{}".format(rootdir + VPP_DRYRUNDIR)) - print ( + "{}".format(rootdir + VPP_DRYRUNDIR) + ) + print( "Please inspect them carefully before applying the actual " - "configuration (option 3)!") + "configuration (option 3)!" + ) nodes = acfg.get_nodes() for i in nodes.items(): node = i[1] - if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and \ - (os.path.isfile(VPP_REAL_STARTUP_FILE) is True): - autoconfig_cp(node, VPP_REAL_STARTUP_FILE, '{}'.format(rootdir + VPP_STARTUP_FILE)) - if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and \ - (os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True): - autoconfig_cp(node, VPP_REAL_HUGE_PAGE_FILE, '{}'.format(rootdir + VPP_HUGE_PAGE_FILE)) - if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and \ - (os.path.isfile(VPP_REAL_GRUB_FILE) is True): - autoconfig_cp(node, VPP_REAL_GRUB_FILE, '{}'.format(rootdir + VPP_GRUB_FILE)) + if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and ( + os.path.isfile(VPP_REAL_STARTUP_FILE) is True + ): + autoconfig_cp( + node, VPP_REAL_STARTUP_FILE, "{}".format(rootdir + VPP_STARTUP_FILE) + ) + if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and ( + os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True + ): + autoconfig_cp( + node, VPP_REAL_HUGE_PAGE_FILE, "{}".format(rootdir + VPP_HUGE_PAGE_FILE) + ) + if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and ( + os.path.isfile(VPP_REAL_GRUB_FILE) is True + ): + autoconfig_cp( + node, VPP_REAL_GRUB_FILE, "{}".format(rootdir + VPP_GRUB_FILE) + ) # Be sure the uio_pci_generic driver is installed - cmd = 'modprobe uio_pci_generic' + cmd = "modprobe uio_pci_generic" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - logging.warning('{} failed on node {} {}'. format(cmd, node['host'], stderr)) + logging.warning("{} failed on node {} {}".format(cmd, node["host"], stderr)) # noinspection PyUnresolvedReferences @@ -707,10 +723,9 @@ def config_main(): # Check for root if not os.geteuid() == 0: - sys.exit('\nPlease run the VPP Configuration Utility as root.') + sys.exit("\nPlease run the VPP Configuration Utility as root.") - if len(sys.argv) > 1 and ((sys.argv[1] == '-d') or ( - sys.argv[1] == '--debug')): + if len(sys.argv) > 1 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")): logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.ERROR) @@ -720,37 +735,44 @@ def config_main(): if len(sys.argv) == 1: autoconfig_main() return - elif len(sys.argv) == 2 and ((sys.argv[1] == '-d') or ( - sys.argv[1] == '--debug')): + elif len(sys.argv) == 2 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")): autoconfig_main() return # There were arguments specified, so execute the utility using # command line arguments - description = 'The VPP configuration utility allows the user to ' - 'configure VPP in a simple and safe manner. The utility takes input ' - 'from the user or the specified .yaml file. The user should then ' - 'examine these files to be sure they are correct and then actually ' - 'apply the configuration. When run without arguments the utility run ' - 'in an interactive mode' + description = "The VPP configuration utility allows the user to " + "configure VPP in a simple and safe manner. The utility takes input " + "from the user or the specified .yaml file. The user should then " + "examine these files to be sure they are correct and then actually " + "apply the configuration. When run without arguments the utility run " + "in an interactive mode" main_parser = argparse.ArgumentParser( - prog='arg-test', + prog="arg-test", description=description, - epilog='See "%(prog)s help COMMAND" for help on a specific command.') - main_parser.add_argument('--apply', '-a', action='store_true', - help='Apply the cofiguration.') - main_parser.add_argument('--dry-run', '-dr', action='store_true', - help='Create the dryrun configuration files.') - main_parser.add_argument('--show', '-s', action='store_true', - help='Shows basic system information') - main_parser.add_argument('--debug', '-d', action='count', - help='Print debug output (multiple levels)') + epilog='See "%(prog)s help COMMAND" for help on a specific command.', + ) + main_parser.add_argument( + "--apply", "-a", action="store_true", help="Apply the cofiguration." + ) + main_parser.add_argument( + "--dry-run", + "-dr", + action="store_true", + help="Create the dryrun configuration files.", + ) + main_parser.add_argument( + "--show", "-s", action="store_true", help="Shows basic system information" + ) + main_parser.add_argument( + "--debug", "-d", action="count", help="Print debug output (multiple levels)" + ) args = main_parser.parse_args() return execute_with_args(args) -if __name__ == '__main__': +if __name__ == "__main__": config_main() diff --git a/extras/vpp_config/vpplib/AutoConfig.py b/extras/vpp_config/vpplib/AutoConfig.py index 62f18e27929..9a79039f69e 100644 --- a/extras/vpp_config/vpplib/AutoConfig.py +++ b/extras/vpp_config/vpplib/AutoConfig.py @@ -41,9 +41,9 @@ MIN_SYSTEM_CPUS = 2 MIN_TOTAL_HUGE_PAGES = 1024 MAX_PERCENT_FOR_HUGE_PAGES = 70 -IPERFVM_XML = 'configs/iperf-vm.xml' -IPERFVM_IMAGE = 'images/xenial-mod.img' -IPERFVM_ISO = 'configs/cloud-config.iso' +IPERFVM_XML = "configs/iperf-vm.xml" +IPERFVM_IMAGE = "images/xenial-mod.img" +IPERFVM_ISO = "configs/cloud-config.iso" class AutoConfig(object): @@ -90,12 +90,12 @@ class AutoConfig(object): """ # Does a copy of the file exist, if not create one - ofile = filename + '.orig' - (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(ofile)) + ofile = filename + ".orig" + (ret, stdout, stderr) = VPPUtil.exec_command("ls {}".format(ofile)) if ret != 0: logging.debug(stderr) - if stdout.strip('\n') != ofile: - cmd = 'sudo cp {} {}'.format(filename, ofile) + if stdout.strip("\n") != ofile: + cmd = "sudo cp {} {}".format(filename, ofile) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) @@ -114,14 +114,14 @@ class AutoConfig(object): while True: answer = input("Please enter the IPv4 Address [n.n.n.n/n]: ") try: - ipinput = answer.split('/') + ipinput = answer.split("/") ipaddr = ip_address(ipinput[0]) if len(ipinput) > 1: - plen = answer.split('/')[1] + plen = answer.split("/")[1] else: answer = input("Please enter the netmask [n.n.n.n]: ") plen = ip_address(answer).netmask_bits() - return '{}/{}'.format(ipaddr, plen) + return "{}/{}".format(ipaddr, plen) except ValueError: print("Please enter a valid IPv4 address.") @@ -145,18 +145,22 @@ class AutoConfig(object): while True: answer = input(question) - if answer == '': + if answer == "": answer = default break - if re.findall(r'[0-9+]', answer): + if re.findall(r"[0-9+]", answer): if int(answer) in range(first, last + 1): break else: - print("Please a value between {} and {} or Return.". - format(first, last)) + print( + "Please a value between {} and {} or Return.".format( + first, last + ) + ) else: - print("Please a number between {} and {} or Return.". - format(first, last)) + print( + "Please a number between {} and {} or Return.".format(first, last) + ) return int(answer) @@ -175,12 +179,12 @@ class AutoConfig(object): input_valid = False default = default.lower() - answer = '' + answer = "" while not input_valid: answer = input(question) - if answer == '': + if answer == "": answer = default - if re.findall(r'[YyNn]', answer): + if re.findall(r"[YyNn]", answer): input_valid = True answer = answer[0].lower() else: @@ -196,36 +200,40 @@ class AutoConfig(object): # Get the Topology, from the topology layout file topo = {} - with open(self._autoconfig_filename, 'r') as stream: + with open(self._autoconfig_filename, "r") as stream: try: topo = yaml.load(stream) - if 'metadata' in topo: - self._metadata = topo['metadata'] + if "metadata" in topo: + self._metadata = topo["metadata"] except yaml.YAMLError as exc: raise RuntimeError( "Couldn't read the Auto config file {}.".format( - self._autoconfig_filename, exc)) + self._autoconfig_filename, exc + ) + ) - systemfile = self._rootdir + self._metadata['system_config_file'] + systemfile = self._rootdir + self._metadata["system_config_file"] if self._clean is False and os.path.isfile(systemfile): - with open(systemfile, 'r') as sysstream: + with open(systemfile, "r") as sysstream: try: systopo = yaml.load(sysstream) - if 'nodes' in systopo: - self._nodes = systopo['nodes'] + if "nodes" in systopo: + self._nodes = systopo["nodes"] except yaml.YAMLError as sysexc: raise RuntimeError( "Couldn't read the System config file {}.".format( - systemfile, sysexc)) + systemfile, sysexc + ) + ) else: # Get the nodes from Auto Config - if 'nodes' in topo: - self._nodes = topo['nodes'] + if "nodes" in topo: + self._nodes = topo["nodes"] # Set the root directory in all the nodes for i in self._nodes.items(): node = i[1] - node['rootdir'] = self._rootdir + node["rootdir"] = self._rootdir def updateconfig(self): """ @@ -236,11 +244,11 @@ class AutoConfig(object): """ # Initialize the yaml data - ydata = {'metadata': self._metadata, 'nodes': self._nodes} + ydata = {"metadata": self._metadata, "nodes": self._nodes} # Write the system config file - filename = self._rootdir + self._metadata['system_config_file'] - with open(filename, 'w') as yamlfile: + filename = self._rootdir + self._metadata["system_config_file"] + with open(filename, "w") as yamlfile: yaml.dump(ydata, yamlfile) def _update_auto_config(self): @@ -252,11 +260,11 @@ class AutoConfig(object): # Initialize the yaml data nodes = {} - with open(self._autoconfig_filename, 'r') as stream: + with open(self._autoconfig_filename, "r") as stream: try: ydata = yaml.load(stream) - if 'nodes' in ydata: - nodes = ydata['nodes'] + if "nodes" in ydata: + nodes = ydata["nodes"] except yaml.YAMLError as exc: print(exc) return @@ -266,41 +274,45 @@ class AutoConfig(object): node = i[1] # Interfaces - node['interfaces'] = {} - for item in self._nodes[key]['interfaces'].items(): + node["interfaces"] = {} + for item in self._nodes[key]["interfaces"].items(): port = item[0] interface = item[1] - node['interfaces'][port] = {} - addr = '{}'.format(interface['pci_address']) - node['interfaces'][port]['pci_address'] = addr - if 'mac_address' in interface: - node['interfaces'][port]['mac_address'] = \ - interface['mac_address'] - - if 'total_other_cpus' in self._nodes[key]['cpu']: - node['cpu']['total_other_cpus'] = \ - self._nodes[key]['cpu']['total_other_cpus'] - if 'total_vpp_cpus' in self._nodes[key]['cpu']: - node['cpu']['total_vpp_cpus'] = \ - self._nodes[key]['cpu']['total_vpp_cpus'] - if 'reserve_vpp_main_core' in self._nodes[key]['cpu']: - node['cpu']['reserve_vpp_main_core'] = \ - self._nodes[key]['cpu']['reserve_vpp_main_core'] + node["interfaces"][port] = {} + addr = "{}".format(interface["pci_address"]) + node["interfaces"][port]["pci_address"] = addr + if "mac_address" in interface: + node["interfaces"][port]["mac_address"] = interface["mac_address"] + + if "total_other_cpus" in self._nodes[key]["cpu"]: + node["cpu"]["total_other_cpus"] = self._nodes[key]["cpu"][ + "total_other_cpus" + ] + if "total_vpp_cpus" in self._nodes[key]["cpu"]: + node["cpu"]["total_vpp_cpus"] = self._nodes[key]["cpu"][ + "total_vpp_cpus" + ] + if "reserve_vpp_main_core" in self._nodes[key]["cpu"]: + node["cpu"]["reserve_vpp_main_core"] = self._nodes[key]["cpu"][ + "reserve_vpp_main_core" + ] # TCP - if 'active_open_sessions' in self._nodes[key]['tcp']: - node['tcp']['active_open_sessions'] = \ - self._nodes[key]['tcp']['active_open_sessions'] - if 'passive_open_sessions' in self._nodes[key]['tcp']: - node['tcp']['passive_open_sessions'] = \ - self._nodes[key]['tcp']['passive_open_sessions'] + if "active_open_sessions" in self._nodes[key]["tcp"]: + node["tcp"]["active_open_sessions"] = self._nodes[key]["tcp"][ + "active_open_sessions" + ] + if "passive_open_sessions" in self._nodes[key]["tcp"]: + node["tcp"]["passive_open_sessions"] = self._nodes[key]["tcp"][ + "passive_open_sessions" + ] # Huge pages - node['hugepages']['total'] = self._nodes[key]['hugepages']['total'] + node["hugepages"]["total"] = self._nodes[key]["hugepages"]["total"] # Write the auto config config file - with open(self._autoconfig_filename, 'w') as yamlfile: + with open(self._autoconfig_filename, "w") as yamlfile: yaml.dump(ydata, yamlfile) def apply_huge_pages(self): @@ -325,28 +337,28 @@ class AutoConfig(object): """ # Get main core - cpu = '\n' - if 'vpp_main_core' in node['cpu']: - vpp_main_core = node['cpu']['vpp_main_core'] + cpu = "\n" + if "vpp_main_core" in node["cpu"]: + vpp_main_core = node["cpu"]["vpp_main_core"] else: vpp_main_core = 0 if vpp_main_core != 0: - cpu += ' main-core {}\n'.format(vpp_main_core) + cpu += " main-core {}\n".format(vpp_main_core) # Get workers - vpp_workers = node['cpu']['vpp_workers'] + vpp_workers = node["cpu"]["vpp_workers"] vpp_worker_len = len(vpp_workers) if vpp_worker_len > 0: - vpp_worker_str = '' + vpp_worker_str = "" for i, worker in enumerate(vpp_workers): if i > 0: - vpp_worker_str += ',' + vpp_worker_str += "," if worker[0] == worker[1]: vpp_worker_str += "{}".format(worker[0]) else: vpp_worker_str += "{}-{}".format(worker[0], worker[1]) - cpu += ' corelist-workers {}\n'.format(vpp_worker_str) + cpu += " corelist-workers {}\n".format(vpp_worker_str) return cpu @@ -359,41 +371,41 @@ class AutoConfig(object): :type node: dict """ - devices = '' - ports_per_numa = node['cpu']['ports_per_numa'] + devices = "" + ports_per_numa = node["cpu"]["ports_per_numa"] for item in ports_per_numa.items(): value = item[1] - interfaces = value['interfaces'] + interfaces = value["interfaces"] # if 0 was specified for the number of vpp workers, use 1 queue num_rx_queues = None num_tx_queues = None - if 'rx_queues' in value: - num_rx_queues = value['rx_queues'] - if 'tx_queues' in value: - num_tx_queues = value['tx_queues'] + if "rx_queues" in value: + num_rx_queues = value["rx_queues"] + if "tx_queues" in value: + num_tx_queues = value["tx_queues"] num_rx_desc = None num_tx_desc = None # Create the devices string for interface in interfaces: - pci_address = interface['pci_address'] + pci_address = interface["pci_address"] pci_address = pci_address.lstrip("'").rstrip("'") - devices += '\n' - devices += ' dev {} {{ \n'.format(pci_address) + devices += "\n" + devices += " dev {} {{ \n".format(pci_address) if num_rx_queues: - devices += ' num-rx-queues {}\n'.format(num_rx_queues) + devices += " num-rx-queues {}\n".format(num_rx_queues) else: - devices += ' num-rx-queues {}\n'.format(1) + devices += " num-rx-queues {}\n".format(1) if num_tx_queues: - devices += ' num-tx-queues {}\n'.format(num_tx_queues) + devices += " num-tx-queues {}\n".format(num_tx_queues) if num_rx_desc: - devices += ' num-rx-desc {}\n'.format(num_rx_desc) + devices += " num-rx-desc {}\n".format(num_rx_desc) if num_tx_desc: - devices += ' num-tx-desc {}\n'.format(num_tx_desc) - devices += ' }' + devices += " num-tx-desc {}\n".format(num_tx_desc) + devices += " }" return devices @@ -405,20 +417,25 @@ class AutoConfig(object): :param node: Node dictionary with cpuinfo. :type node: dict """ - buffers = '' - total_mbufs = node['cpu']['total_mbufs'] + buffers = "" + total_mbufs = node["cpu"]["total_mbufs"] # If the total mbufs is not 0 or less than the default, set num-bufs logging.debug("Total mbufs: {}".format(total_mbufs)) if total_mbufs != 0 and total_mbufs > 16384: - buffers += ' buffers-per-numa {}'.format(total_mbufs) + buffers += " buffers-per-numa {}".format(total_mbufs) return buffers @staticmethod - def _calc_vpp_workers(node, vpp_workers, numa_node, other_cpus_end, - total_vpp_workers, - reserve_vpp_main_core): + def _calc_vpp_workers( + node, + vpp_workers, + numa_node, + other_cpus_end, + total_vpp_workers, + reserve_vpp_main_core, + ): """ Calculate the VPP worker information @@ -440,7 +457,7 @@ class AutoConfig(object): """ # Can we fit the workers in one of these slices - cpus = node['cpu']['cpus_per_node'][numa_node] + cpus = node["cpu"]["cpus_per_node"][numa_node] for cpu in cpus: start = cpu[0] end = cpu[1] @@ -454,7 +471,7 @@ class AutoConfig(object): if workers_end <= end: if reserve_vpp_main_core: - node['cpu']['vpp_main_core'] = start - 1 + node["cpu"]["vpp_main_core"] = start - 1 reserve_vpp_main_core = False if total_vpp_workers: vpp_workers.append((start, workers_end)) @@ -462,15 +479,14 @@ class AutoConfig(object): # We still need to reserve the main core if reserve_vpp_main_core: - node['cpu']['vpp_main_core'] = other_cpus_end + 1 + node["cpu"]["vpp_main_core"] = other_cpus_end + 1 return reserve_vpp_main_core @staticmethod - def _calc_desc_and_queues(total_numa_nodes, - total_ports_per_numa, - total_rx_queues, - ports_per_numa_value): + def _calc_desc_and_queues( + total_numa_nodes, total_ports_per_numa, total_rx_queues, ports_per_numa_value + ): """ Calculate the number of descriptors and queues @@ -494,8 +510,10 @@ class AutoConfig(object): # Get the descriptor entries desc_entries = 1024 - ports_per_numa_value['rx_queues'] = rx_queues - total_mbufs = ((rx_queues * desc_entries) + (tx_queues * desc_entries)) * total_ports_per_numa + ports_per_numa_value["rx_queues"] = rx_queues + total_mbufs = ( + (rx_queues * desc_entries) + (tx_queues * desc_entries) + ) * total_ports_per_numa return total_mbufs @@ -515,12 +533,12 @@ class AutoConfig(object): ports_per_numa = {} for item in interfaces.items(): i = item[1] - if i['numa_node'] not in ports_per_numa: - ports_per_numa[i['numa_node']] = {'interfaces': []} - ports_per_numa[i['numa_node']]['interfaces'].append(i) + if i["numa_node"] not in ports_per_numa: + ports_per_numa[i["numa_node"]] = {"interfaces": []} + ports_per_numa[i["numa_node"]]["interfaces"].append(i) else: - ports_per_numa[i['numa_node']]['interfaces'].append(i) - node['cpu']['ports_per_numa'] = ports_per_numa + ports_per_numa[i["numa_node"]]["interfaces"].append(i) + node["cpu"]["ports_per_numa"] = ports_per_numa return ports_per_numa @@ -536,24 +554,24 @@ class AutoConfig(object): node = i[1] # get total number of nic ports - interfaces = node['interfaces'] + interfaces = node["interfaces"] # Make a list of ports by numa node ports_per_numa = self._create_ports_per_numa(node, interfaces) # Get the number of cpus to skip, we never use the first cpu other_cpus_start = 1 - other_cpus_end = other_cpus_start + node['cpu']['total_other_cpus'] - 1 + other_cpus_end = other_cpus_start + node["cpu"]["total_other_cpus"] - 1 other_workers = None if other_cpus_end != 0: other_workers = (other_cpus_start, other_cpus_end) - node['cpu']['other_workers'] = other_workers + node["cpu"]["other_workers"] = other_workers # Allocate the VPP main core and workers vpp_workers = [] - reserve_vpp_main_core = node['cpu']['reserve_vpp_main_core'] - total_vpp_cpus = node['cpu']['total_vpp_cpus'] - total_rx_queues = node['cpu']['total_rx_queues'] + reserve_vpp_main_core = node["cpu"]["reserve_vpp_main_core"] + total_vpp_cpus = node["cpu"]["total_vpp_cpus"] + total_rx_queues = node["cpu"]["total_rx_queues"] # If total_vpp_cpus is 0 or is less than the numa nodes with ports # then we shouldn't get workers @@ -572,14 +590,21 @@ class AutoConfig(object): # Get the number of descriptors and queues mbufs = self._calc_desc_and_queues( len(ports_per_numa), - len(value['interfaces']), total_rx_queues, value) + len(value["interfaces"]), + total_rx_queues, + value, + ) total_mbufs += mbufs # Get the VPP workers reserve_vpp_main_core = self._calc_vpp_workers( - node, vpp_workers, numa_node, - other_cpus_end, total_workers_node, - reserve_vpp_main_core) + node, + vpp_workers, + numa_node, + other_cpus_end, + total_workers_node, + reserve_vpp_main_core, + ) total_mbufs *= 2.5 total_mbufs = int(total_mbufs) @@ -587,8 +612,8 @@ class AutoConfig(object): total_mbufs = 0 # Save the info - node['cpu']['vpp_workers'] = vpp_workers - node['cpu']['total_mbufs'] = total_mbufs + node["cpu"]["vpp_workers"] = vpp_workers + node["cpu"]["total_mbufs"] = total_mbufs # Write the config self.updateconfig() @@ -602,54 +627,55 @@ class AutoConfig(object): :type node: dict """ - active_open_sessions = node['tcp']['active_open_sessions'] + active_open_sessions = node["tcp"]["active_open_sessions"] aos = int(active_open_sessions) - passive_open_sessions = node['tcp']['passive_open_sessions'] + passive_open_sessions = node["tcp"]["passive_open_sessions"] pos = int(passive_open_sessions) # Generate the api-segment gid vpp sheit in any case if (aos + pos) == 0: - tcp = '\n'.join([ + tcp = "\n".join(["api-segment {", " gid vpp", "}"]) + return tcp.rstrip("\n") + + tcp = "\n".join( + [ + "# TCP stack-related configuration parameters", + "# expecting {:d} client sessions, {:d} server sessions\n".format( + aos, pos + ), + "heapsize 4g\n", "api-segment {", - " gid vpp", - "}" - ]) - return tcp.rstrip('\n') - - tcp = '\n'.join([ - "# TCP stack-related configuration parameters", - "# expecting {:d} client sessions, {:d} server sessions\n".format( - aos, pos), - "heapsize 4g\n", - "api-segment {", - " global-size 2000M", - " api-size 1G", - "}\n", - - "session {", - " event-queue-length {:d}".format(aos + pos), - " preallocated-sessions {:d}".format(aos + pos), - " v4-session-table-buckets {:d}".format((aos + pos) // 4), - " v4-session-table-memory 3g\n" - ]) + " global-size 2000M", + " api-size 1G", + "}\n", + "session {", + " event-queue-length {:d}".format(aos + pos), + " preallocated-sessions {:d}".format(aos + pos), + " v4-session-table-buckets {:d}".format((aos + pos) // 4), + " v4-session-table-memory 3g\n", + ] + ) if aos > 0: - tcp = tcp + " v4-halfopen-table-buckets {:d}".format( - (aos + pos) // 4) + "\n" + tcp = ( + tcp + " v4-halfopen-table-buckets {:d}".format((aos + pos) // 4) + "\n" + ) tcp = tcp + " v4-halfopen-table-memory 3g\n" - tcp = tcp + " local-endpoints-table-buckets {:d}".format( - (aos + pos) // 4) + "\n" + tcp = ( + tcp + + " local-endpoints-table-buckets {:d}".format((aos + pos) // 4) + + "\n" + ) tcp = tcp + " local-endpoints-table-memory 3g\n" tcp = tcp + "}\n\n" tcp = tcp + "tcp {\n" tcp = tcp + " preallocated-connections {:d}".format(aos + pos) + "\n" if aos > 0: - tcp = tcp + " preallocated-half-open-connections {:d}".format( - aos) + "\n" + tcp = tcp + " preallocated-half-open-connections {:d}".format(aos) + "\n" tcp = tcp + "}\n\n" - return tcp.rstrip('\n') + return tcp.rstrip("\n") def apply_vpp_startup(self): """ @@ -662,8 +688,8 @@ class AutoConfig(object): node = i[1] # Get the startup file - rootdir = node['rootdir'] - sfile = rootdir + node['vpp']['startup_config_file'] + rootdir = node["rootdir"] + sfile = rootdir + node["vpp"]["startup_config_file"] # Get the buffers devices = self._apply_vpp_devices(node) @@ -680,27 +706,22 @@ class AutoConfig(object): self._autoconfig_backup_file(sfile) # Get the template - tfile = sfile + '.template' - (ret, stdout, stderr) = \ - VPPUtil.exec_command('cat {}'.format(tfile)) + tfile = sfile + ".template" + (ret, stdout, stderr) = VPPUtil.exec_command("cat {}".format(tfile)) if ret != 0: - raise RuntimeError('Executing cat command failed to node {}'. - format(node['host'])) - startup = stdout.format(cpu=cpu, - buffers=buffers, - devices=devices, - tcp=tcp) - - (ret, stdout, stderr) = \ - VPPUtil.exec_command('rm {}'.format(sfile)) + raise RuntimeError( + "Executing cat command failed to node {}".format(node["host"]) + ) + startup = stdout.format(cpu=cpu, buffers=buffers, devices=devices, tcp=tcp) + + (ret, stdout, stderr) = VPPUtil.exec_command("rm {}".format(sfile)) if ret != 0: logging.debug(stderr) cmd = "sudo cat > {0} << EOF\n{1}\n".format(sfile, startup) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('Writing config failed node {}'. - format(node['host'])) + raise RuntimeError("Writing config failed node {}".format(node["host"])) def apply_grub_cmdline(self): """ @@ -712,10 +733,10 @@ class AutoConfig(object): node = i[1] # Get the isolated CPUs - other_workers = node['cpu']['other_workers'] - vpp_workers = node['cpu']['vpp_workers'] - if 'vpp_main_core' in node['cpu']: - vpp_main_core = node['cpu']['vpp_main_core'] + other_workers = node["cpu"]["other_workers"] + vpp_workers = node["cpu"]["vpp_workers"] + if "vpp_main_core" in node["cpu"]: + vpp_main_core = node["cpu"]["vpp_main_core"] else: vpp_main_core = 0 all_workers = [] @@ -724,12 +745,12 @@ class AutoConfig(object): if vpp_main_core != 0: all_workers += [(vpp_main_core, vpp_main_core)] all_workers += vpp_workers - isolated_cpus = '' + isolated_cpus = "" for idx, worker in enumerate(all_workers): if worker is None: continue if idx > 0: - isolated_cpus += ',' + isolated_cpus += "," if worker[0] == worker[1]: isolated_cpus += "{}".format(worker[0]) else: @@ -737,11 +758,10 @@ class AutoConfig(object): vppgrb = VppGrubUtil(node) current_cmdline = vppgrb.get_current_cmdline() - if 'grub' not in node: - node['grub'] = {} - node['grub']['current_cmdline'] = current_cmdline - node['grub']['default_cmdline'] = \ - vppgrb.apply_cmdline(node, isolated_cpus) + if "grub" not in node: + node["grub"] = {} + node["grub"]["current_cmdline"] = current_cmdline + node["grub"]["default_cmdline"] = vppgrb.apply_cmdline(node, isolated_cpus) self.updateconfig() @@ -756,14 +776,14 @@ class AutoConfig(object): hpg = VppHugePageUtil(node) max_map_count, shmmax = hpg.get_huge_page_config() - node['hugepages']['max_map_count'] = max_map_count - node['hugepages']['shmax'] = shmmax + node["hugepages"]["max_map_count"] = max_map_count + node["hugepages"]["shmax"] = shmmax total, free, size, memtotal, memfree = hpg.get_actual_huge_pages() - node['hugepages']['actual_total'] = total - node['hugepages']['free'] = free - node['hugepages']['size'] = size - node['hugepages']['memtotal'] = memtotal - node['hugepages']['memfree'] = memfree + node["hugepages"]["actual_total"] = total + node["hugepages"]["free"] = free + node["hugepages"]["size"] = size + node["hugepages"]["memtotal"] = memtotal + node["hugepages"]["memfree"] = memfree self.updateconfig() @@ -782,14 +802,14 @@ class AutoConfig(object): # Get the total number of isolated CPUs current_iso_cpus = 0 - iso_cpur = re.findall(r'isolcpus=[\w+\-,]+', current_cmdline) + iso_cpur = re.findall(r"isolcpus=[\w+\-,]+", current_cmdline) iso_cpurl = len(iso_cpur) if iso_cpurl > 0: iso_cpu_str = iso_cpur[0] - iso_cpu_str = iso_cpu_str.split('=')[1] - iso_cpul = iso_cpu_str.split(',') + iso_cpu_str = iso_cpu_str.split("=")[1] + iso_cpul = iso_cpu_str.split(",") for iso_cpu in iso_cpul: - isocpuspl = iso_cpu.split('-') + isocpuspl = iso_cpu.split("-") if len(isocpuspl) == 1: current_iso_cpus += 1 else: @@ -800,11 +820,11 @@ class AutoConfig(object): else: current_iso_cpus += second - first - if 'grub' not in node: - node['grub'] = {} - node['grub']['current_cmdline'] = current_cmdline - node['grub']['default_cmdline'] = default_cmdline - node['grub']['current_iso_cpus'] = current_iso_cpus + if "grub" not in node: + node["grub"] = {} + node["grub"]["current_cmdline"] = current_cmdline + node["grub"]["default_cmdline"] = default_cmdline + node["grub"]["current_iso_cpus"] = current_iso_cpus self.updateconfig() @@ -822,11 +842,11 @@ class AutoConfig(object): vpp.get_all_devices() # Save the device information - node['devices'] = {} - node['devices']['dpdk_devices'] = vpp.get_dpdk_devices() - node['devices']['kernel_devices'] = vpp.get_kernel_devices() - node['devices']['other_devices'] = vpp.get_other_devices() - node['devices']['linkup_devices'] = vpp.get_link_up_devices() + node["devices"] = {} + node["devices"]["dpdk_devices"] = vpp.get_dpdk_devices() + node["devices"]["kernel_devices"] = vpp.get_kernel_devices() + node["devices"]["other_devices"] = vpp.get_other_devices() + node["devices"]["linkup_devices"] = vpp.get_link_up_devices() def get_devices_per_node(self): """ @@ -856,20 +876,25 @@ class AutoConfig(object): :rtype: list """ - cmd = 'lscpu -p' + cmd = "lscpu -p" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'. - format(cmd, node['host'], stderr)) + raise RuntimeError( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) pcpus = [] - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: - if line == '' or line[0] == '#': + if line == "" or line[0] == "#": continue - linesplit = line.split(',') - layout = {'cpu': linesplit[0], 'core': linesplit[1], - 'socket': linesplit[2], 'node': linesplit[3]} + linesplit = line.split(",") + layout = { + "cpu": linesplit[0], + "core": linesplit[1], + "socket": linesplit[2], + "node": linesplit[3], + } # cpu, core, socket, node pcpus.append(layout) @@ -890,14 +915,14 @@ class AutoConfig(object): # Get the cpu layout layout = self.get_cpu_layout(node) - node['cpu']['layout'] = layout + node["cpu"]["layout"] = layout - cpuinfo = node['cpuinfo'] + cpuinfo = node["cpuinfo"] smt_enabled = CpuUtils.is_smt_enabled(cpuinfo) - node['cpu']['smt_enabled'] = smt_enabled + node["cpu"]["smt_enabled"] = smt_enabled # We don't want to write the cpuinfo - node['cpuinfo'] = "" + node["cpuinfo"] = "" # Write the config self.updateconfig() @@ -932,46 +957,59 @@ class AutoConfig(object): :type numa_nodes: list """ - print("\nYour system has {} core(s) and {} Numa Nodes.". - format(total_cpus, len(numa_nodes))) - print("To begin, we suggest not reserving any cores for " - "VPP or other processes.") - print("Then to improve performance start reserving cores and " - "adding queues as needed.") + print( + "\nYour system has {} core(s) and {} Numa Nodes.".format( + total_cpus, len(numa_nodes) + ) + ) + print( + "To begin, we suggest not reserving any cores for " + "VPP or other processes." + ) + print( + "Then to improve performance start reserving cores and " + "adding queues as needed." + ) # Leave 1 for the general system total_cpus -= 1 max_vpp_cpus = min(total_cpus, 4) total_vpp_cpus = 0 if max_vpp_cpus > 0: - question = "\nHow many core(s) shall we reserve for " \ - "VPP [0-{}][0]? ".format(max_vpp_cpus) + question = ( + "\nHow many core(s) shall we reserve for " + "VPP [0-{}][0]? ".format(max_vpp_cpus) + ) total_vpp_cpus = self._ask_user_range(question, 0, max_vpp_cpus, 0) - node['cpu']['total_vpp_cpus'] = total_vpp_cpus + node["cpu"]["total_vpp_cpus"] = total_vpp_cpus total_other_cpus = 0 max_other_cores = total_cpus - total_vpp_cpus if max_other_cores > 0: - question = 'How many core(s) do you want to reserve for ' \ - 'processes other than VPP? [0-{}][0]? '. format(str(max_other_cores)) + question = ( + "How many core(s) do you want to reserve for " + "processes other than VPP? [0-{}][0]? ".format(str(max_other_cores)) + ) total_other_cpus = self._ask_user_range(question, 0, max_other_cores, 0) - node['cpu']['total_other_cpus'] = total_other_cpus + node["cpu"]["total_other_cpus"] = total_other_cpus max_main_cpus = total_cpus - total_vpp_cpus - total_other_cpus reserve_vpp_main_core = False if max_main_cpus > 0: question = "Should we reserve 1 core for the VPP Main thread? " question += "[y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + answer = self._ask_user_yn(question, "n") + if answer == "y": reserve_vpp_main_core = True - node['cpu']['reserve_vpp_main_core'] = reserve_vpp_main_core - node['cpu']['vpp_main_core'] = 0 + node["cpu"]["reserve_vpp_main_core"] = reserve_vpp_main_core + node["cpu"]["vpp_main_core"] = 0 - question = "How many RX queues per port shall we use for " \ - "VPP [1-4][1]? ".format(max_vpp_cpus) + question = ( + "How many RX queues per port shall we use for " + "VPP [1-4][1]? ".format(max_vpp_cpus) + ) total_rx_queues = self._ask_user_range(question, 1, 4, 1) - node['cpu']['total_rx_queues'] = total_rx_queues + node["cpu"]["total_rx_queues"] = total_rx_queues def modify_cpu(self, ask_questions=True): """ @@ -995,50 +1033,50 @@ class AutoConfig(object): # Assume the number of cpus per slice is always the same as the # first slice - first_node = '0' + first_node = "0" for cpu in cpu_layout: - if cpu['node'] != first_node: + if cpu["node"] != first_node: break total_cpus_per_slice += 1 # Get the total number of cpus, cores, and numa nodes from the # cpu layout for cpul in cpu_layout: - numa_node = cpul['node'] - core = cpul['core'] - cpu = cpul['cpu'] + numa_node = cpul["node"] + core = cpul["core"] + cpu = cpul["cpu"] total_cpus += 1 if numa_node not in cpus_per_node: cpus_per_node[numa_node] = [] cpuperslice = int(cpu) % total_cpus_per_slice if cpuperslice == 0: - cpus_per_node[numa_node].append((int(cpu), int(cpu) + - total_cpus_per_slice - 1)) + cpus_per_node[numa_node].append( + (int(cpu), int(cpu) + total_cpus_per_slice - 1) + ) if numa_node not in numa_nodes: numa_nodes.append(numa_node) if core not in cores: cores.append(core) - node['cpu']['cpus_per_node'] = cpus_per_node + node["cpu"]["cpus_per_node"] = cpus_per_node # Ask the user some questions if ask_questions and total_cpus >= 4: self._modify_cpu_questions(node, total_cpus, numa_nodes) # Populate the interfaces with the numa node - if 'interfaces' in node: - ikeys = node['interfaces'].keys() + if "interfaces" in node: + ikeys = node["interfaces"].keys() VPPUtil.get_interfaces_numa_node(node, *tuple(ikeys)) # We don't want to write the cpuinfo - node['cpuinfo'] = "" + node["cpuinfo"] = "" # Write the configs self._update_auto_config() self.updateconfig() - def _modify_other_devices(self, node, - other_devices, kernel_devices, dpdk_devices): + def _modify_other_devices(self, node, other_devices, kernel_devices, dpdk_devices): """ Modify the devices configuration, asking for the user for the values. @@ -1046,31 +1084,31 @@ class AutoConfig(object): odevices_len = len(other_devices) if odevices_len > 0: - print("\nThese device(s) are currently NOT being used " - "by VPP or the OS.\n") + print( + "\nThese device(s) are currently NOT being used " "by VPP or the OS.\n" + ) VppPCIUtil.show_vpp_devices(other_devices, show_interfaces=False) question = "\nWould you like to give any of these devices" question += " back to the OS [Y/n]? " - answer = self._ask_user_yn(question, 'Y') - if answer == 'y': + answer = self._ask_user_yn(question, "Y") + if answer == "y": vppd = {} for dit in other_devices.items(): dvid = dit[0] device = dit[1] - question = "Would you like to use device {} for". \ - format(dvid) + question = "Would you like to use device {} for".format(dvid) question += " the OS [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': - if 'unused' in device and len( - device['unused']) != 0 and \ - device['unused'][0] != '': - driver = device['unused'][0] - ret = VppPCIUtil.bind_vpp_device( - node, driver, dvid) + answer = self._ask_user_yn(question, "n") + if answer == "y": + if ( + "unused" in device + and len(device["unused"]) != 0 + and device["unused"][0] != "" + ): + driver = device["unused"][0] + ret = VppPCIUtil.bind_vpp_device(node, driver, dvid) if ret: - logging.debug( - 'Could not bind device {}'.format(dvid)) + logging.debug("Could not bind device {}".format(dvid)) else: vppd[dvid] = device for dit in vppd.items(): @@ -1081,34 +1119,35 @@ class AutoConfig(object): odevices_len = len(other_devices) if odevices_len > 0: - print("\nThese device(s) are still NOT being used " - "by VPP or the OS.\n") + print("\nThese device(s) are still NOT being used " "by VPP or the OS.\n") VppPCIUtil.show_vpp_devices(other_devices, show_interfaces=False) question = "\nWould you like use any of these for VPP [y/N]? " - answer = self._ask_user_yn(question, 'N') - if answer == 'y': + answer = self._ask_user_yn(question, "N") + if answer == "y": vppd = {} for dit in other_devices.items(): dvid = dit[0] device = dit[1] question = "Would you like to use device {} ".format(dvid) question += "for VPP [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + answer = self._ask_user_yn(question, "n") + if answer == "y": vppd[dvid] = device for dit in vppd.items(): dvid = dit[0] device = dit[1] - if 'unused' in device and len(device['unused']) != 0 and \ - device['unused'][0] != '': - driver = device['unused'][0] + if ( + "unused" in device + and len(device["unused"]) != 0 + and device["unused"][0] != "" + ): + driver = device["unused"][0] logging.debug( - 'Binding device {} to driver {}'.format(dvid, - driver)) + "Binding device {} to driver {}".format(dvid, driver) + ) ret = VppPCIUtil.bind_vpp_device(node, driver, dvid) if ret: - logging.debug( - 'Could not bind device {}'.format(dvid)) + logging.debug("Could not bind device {}".format(dvid)) else: dpdk_devices[dvid] = device del other_devices[dvid] @@ -1121,22 +1160,23 @@ class AutoConfig(object): for i in self._nodes.items(): node = i[1] - devices = node['devices'] - all_devices = devices['other_devices'] - all_devices.update(devices['dpdk_devices']) - all_devices.update(devices['kernel_devices']) + devices = node["devices"] + all_devices = devices["other_devices"] + all_devices.update(devices["dpdk_devices"]) + all_devices.update(devices["kernel_devices"]) current_ifcs = {} interfaces = {} - if 'interfaces' in node: - current_ifcs = node['interfaces'] + if "interfaces" in node: + current_ifcs = node["interfaces"] if current_ifcs: for ifc in current_ifcs.values(): - dvid = ifc['pci_address'] + dvid = ifc["pci_address"] if dvid in all_devices: - VppPCIUtil.vpp_create_interface(interfaces, dvid, - all_devices[dvid]) - node['interfaces'] = interfaces + VppPCIUtil.vpp_create_interface( + interfaces, dvid, all_devices[dvid] + ) + node["interfaces"] = interfaces self.updateconfig() @@ -1148,86 +1188,98 @@ class AutoConfig(object): for i in self._nodes.items(): node = i[1] - devices = node['devices'] - other_devices = devices['other_devices'] - kernel_devices = devices['kernel_devices'] - dpdk_devices = devices['dpdk_devices'] + devices = node["devices"] + other_devices = devices["other_devices"] + kernel_devices = devices["kernel_devices"] + dpdk_devices = devices["dpdk_devices"] if other_devices: - self._modify_other_devices(node, other_devices, - kernel_devices, dpdk_devices) + self._modify_other_devices( + node, other_devices, kernel_devices, dpdk_devices + ) # Get the devices again for this node self._get_device(node) - devices = node['devices'] - kernel_devices = devices['kernel_devices'] - dpdk_devices = devices['dpdk_devices'] + devices = node["devices"] + kernel_devices = devices["kernel_devices"] + dpdk_devices = devices["dpdk_devices"] klen = len(kernel_devices) if klen > 0: print("\nThese devices are safe to be used with VPP.\n") VppPCIUtil.show_vpp_devices(kernel_devices) - question = "\nWould you like to use any of these " \ - "device(s) for VPP [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + question = ( + "\nWould you like to use any of these " "device(s) for VPP [y/N]? " + ) + answer = self._ask_user_yn(question, "n") + if answer == "y": vppd = {} for dit in kernel_devices.items(): dvid = dit[0] device = dit[1] question = "Would you like to use device {} ".format(dvid) question += "for VPP [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + answer = self._ask_user_yn(question, "n") + if answer == "y": vppd[dvid] = device for dit in vppd.items(): dvid = dit[0] device = dit[1] - if 'unused' in device and len( - device['unused']) != 0 and device['unused'][0] != '': - driver = device['unused'][0] - question = "Would you like to bind the driver {} for {} [y/N]? ".format(driver, dvid) - answer = self._ask_user_yn(question, 'n') - if answer == 'y': - logging.debug('Binding device {} to driver {}'.format(dvid, driver)) + if ( + "unused" in device + and len(device["unused"]) != 0 + and device["unused"][0] != "" + ): + driver = device["unused"][0] + question = "Would you like to bind the driver {} for {} [y/N]? ".format( + driver, dvid + ) + answer = self._ask_user_yn(question, "n") + if answer == "y": + logging.debug( + "Binding device {} to driver {}".format( + dvid, driver + ) + ) ret = VppPCIUtil.bind_vpp_device(node, driver, dvid) if ret: - logging.debug('Could not bind device {}'.format(dvid)) + logging.debug( + "Could not bind device {}".format(dvid) + ) dpdk_devices[dvid] = device del kernel_devices[dvid] dlen = len(dpdk_devices) if dlen > 0: print("\nThese device(s) are already using DPDK.\n") - VppPCIUtil.show_vpp_devices(dpdk_devices, - show_interfaces=False) + VppPCIUtil.show_vpp_devices(dpdk_devices, show_interfaces=False) question = "\nWould you like to remove any of " question += "these device(s) [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + answer = self._ask_user_yn(question, "n") + if answer == "y": vppdl = {} for dit in dpdk_devices.items(): dvid = dit[0] device = dit[1] - question = "Would you like to remove {} [y/N]? ". \ - format(dvid) - answer = self._ask_user_yn(question, 'n') - if answer == 'y': + question = "Would you like to remove {} [y/N]? ".format(dvid) + answer = self._ask_user_yn(question, "n") + if answer == "y": vppdl[dvid] = device for dit in vppdl.items(): dvid = dit[0] device = dit[1] - if 'unused' in device and len( - device['unused']) != 0 and device['unused'][0] != '': - driver = device['unused'][0] + if ( + "unused" in device + and len(device["unused"]) != 0 + and device["unused"][0] != "" + ): + driver = device["unused"][0] logging.debug( - 'Binding device {} to driver {}'.format( - dvid, driver)) - ret = VppPCIUtil.bind_vpp_device(node, driver, - dvid) + "Binding device {} to driver {}".format(dvid, driver) + ) + ret = VppPCIUtil.bind_vpp_device(node, driver, dvid) if ret: - logging.debug( - 'Could not bind device {}'.format(dvid)) + logging.debug("Could not bind device {}".format(dvid)) else: kernel_devices[dvid] = device del dpdk_devices[dvid] @@ -1237,7 +1289,7 @@ class AutoConfig(object): dvid = dit[0] device = dit[1] VppPCIUtil.vpp_create_interface(interfaces, dvid, device) - node['interfaces'] = interfaces + node["interfaces"] = interfaces self._update_auto_config() self.updateconfig() @@ -1251,29 +1303,27 @@ class AutoConfig(object): for i in self._nodes.items(): node = i[1] - total = node['hugepages']['actual_total'] - free = node['hugepages']['free'] - size = node['hugepages']['size'] - memfree = node['hugepages']['memfree'].split(' ')[0] - hugesize = int(size.split(' ')[0]) + total = node["hugepages"]["actual_total"] + free = node["hugepages"]["free"] + size = node["hugepages"]["size"] + memfree = node["hugepages"]["memfree"].split(" ")[0] + hugesize = int(size.split(" ")[0]) # The max number of huge pages should be no more than # 70% of total free memory maxpages = (int(memfree) * MAX_PERCENT_FOR_HUGE_PAGES // 100) // hugesize - print("\nThere currently {} {} huge pages free.".format( - free, size)) - question = "Do you want to reconfigure the number of " \ - "huge pages [y/N]? " - answer = self._ask_user_yn(question, 'n') - if answer == 'n': - node['hugepages']['total'] = total + print("\nThere currently {} {} huge pages free.".format(free, size)) + question = "Do you want to reconfigure the number of " "huge pages [y/N]? " + answer = self._ask_user_yn(question, "n") + if answer == "n": + node["hugepages"]["total"] = total continue - print("\nThere currently a total of {} huge pages.". - format(total)) - question = "How many huge pages do you want [{} - {}][{}]? ". \ - format(MIN_TOTAL_HUGE_PAGES, maxpages, MIN_TOTAL_HUGE_PAGES) + print("\nThere currently a total of {} huge pages.".format(total)) + question = "How many huge pages do you want [{} - {}][{}]? ".format( + MIN_TOTAL_HUGE_PAGES, maxpages, MIN_TOTAL_HUGE_PAGES + ) answer = self._ask_user_range(question, 1024, maxpages, 1024) - node['hugepages']['total'] = str(answer) + node["hugepages"]["total"] = str(answer) # Update auto-config.yaml self._update_auto_config() @@ -1298,21 +1348,25 @@ class AutoConfig(object): for i in self._nodes.items(): node = i[1] - question = "\nHow many active-open / tcp client sessions are " \ - "expected [0-10000000][0]? " + question = ( + "\nHow many active-open / tcp client sessions are " + "expected [0-10000000][0]? " + ) answer = self._ask_user_range(question, 0, 10000000, 0) # Less than 10K is equivalent to 0 if int(answer) < 10000: answer = 0 - node['tcp']['active_open_sessions'] = answer + node["tcp"]["active_open_sessions"] = answer - question = "How many passive-open / tcp server sessions are " \ - "expected [0-10000000][0]? " + question = ( + "How many passive-open / tcp server sessions are " + "expected [0-10000000][0]? " + ) answer = self._ask_user_range(question, 0, 10000000, 0) # Less than 10K is equivalent to 0 if int(answer) < 10000: answer = 0 - node['tcp']['passive_open_sessions'] = answer + node["tcp"]["passive_open_sessions"] = answer # Update auto-config.yaml self._update_auto_config() @@ -1329,7 +1383,7 @@ class AutoConfig(object): :type node: dict """ - print('\nWe are patching the node "{}":\n'.format(node['host'])) + print('\nWe are patching the node "{}":\n'.format(node["host"])) QemuUtils.build_qemu(node, force_install=True, apply_patch=True) @staticmethod @@ -1341,44 +1395,44 @@ class AutoConfig(object): cpu = CpuUtils.get_cpu_info_per_node(node) - item = 'Model name' + item = "Model name" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'CPU(s)' + item = "CPU(s)" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'Thread(s) per core' + item = "Thread(s) per core" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'Core(s) per socket' + item = "Core(s) per socket" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'Socket(s)' + item = "Socket(s)" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'NUMA node(s)' + item = "NUMA node(s)" numa_nodes = 0 if item in cpu: numa_nodes = int(cpu[item]) for i in range(0, numa_nodes): item = "NUMA node{} CPU(s)".format(i) print("{:>20}: {}".format(item, cpu[item])) - item = 'CPU max MHz' + item = "CPU max MHz" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - item = 'CPU min MHz' + item = "CPU min MHz" if item in cpu: print("{:>20}: {}".format(item, cpu[item])) - if node['cpu']['smt_enabled']: - smt = 'Enabled' + if node["cpu"]["smt_enabled"]: + smt = "Enabled" else: - smt = 'Disabled' - print("{:>20}: {}".format('SMT', smt)) + smt = "Disabled" + print("{:>20}: {}".format("SMT", smt)) # VPP Threads print("\nVPP Threads: (Name: Cpu Number)") - vpp_processes = cpu['vpp_processes'] + vpp_processes = cpu["vpp_processes"] for i in vpp_processes.items(): print(" {:10}: {:4}".format(i[0], i[1])) @@ -1389,8 +1443,8 @@ class AutoConfig(object): """ - if 'cpu' in node and 'total_mbufs' in node['cpu']: - total_mbufs = node['cpu']['total_mbufs'] + if "cpu" in node and "total_mbufs" in node["cpu"]: + total_mbufs = node["cpu"]["total_mbufs"] if total_mbufs != 0: print("Total Number of Buffers: {}".format(total_mbufs)) @@ -1412,16 +1466,14 @@ class AutoConfig(object): dpdk_devs = vpp.get_dpdk_devices() if len(dpdk_devs): print("\nDevices bound to DPDK drivers:") - vpp.show_vpp_devices(dpdk_devs, show_interfaces=True, - show_header=False) + vpp.show_vpp_devices(dpdk_devs, show_interfaces=True, show_header=False) else: print("\nNo devices bound to DPDK drivers") other_devs = vpp.get_other_devices() if len(other_devs): print("\nDevices not bound to Kernel or DPDK drivers:") - vpp.show_vpp_devices(other_devs, show_interfaces=True, - show_header=False) + vpp.show_vpp_devices(other_devs, show_interfaces=True, show_header=False) else: print("\nNo devices not bound to Kernel or DPDK drivers") @@ -1436,28 +1488,33 @@ class AutoConfig(object): print("None") return - print("{:30} {:4} {:4} {:7} {:4} {:7}". - format('Name', 'Numa', 'RXQs', - 'RXDescs', 'TXQs', 'TXDescs')) + print( + "{:30} {:4} {:4} {:7} {:4} {:7}".format( + "Name", "Numa", "RXQs", "RXDescs", "TXQs", "TXDescs" + ) + ) for intf in sorted(interfaces.items()): name = intf[0] value = intf[1] - if name == 'local0': + if name == "local0": continue - numa = rx_qs = rx_ds = tx_qs = tx_ds = '' - if 'numa' in value: - numa = int(value['numa']) - if 'rx queues' in value: - rx_qs = int(value['rx queues']) - if 'rx descs' in value: - rx_ds = int(value['rx descs']) - if 'tx queues' in value: - tx_qs = int(value['tx queues']) - if 'tx descs' in value: - tx_ds = int(value['tx descs']) - - print("{:30} {:>4} {:>4} {:>7} {:>4} {:>7}". - format(name, numa, rx_qs, rx_ds, tx_qs, tx_ds)) + numa = rx_qs = rx_ds = tx_qs = tx_ds = "" + if "numa" in value: + numa = int(value["numa"]) + if "rx queues" in value: + rx_qs = int(value["rx queues"]) + if "rx descs" in value: + rx_ds = int(value["rx descs"]) + if "tx queues" in value: + tx_qs = int(value["tx queues"]) + if "tx descs" in value: + tx_ds = int(value["tx descs"]) + + print( + "{:30} {:>4} {:>4} {:>7} {:>4} {:>7}".format( + name, numa, rx_qs, rx_ds, tx_qs, tx_ds + ) + ) @staticmethod def hugepage_info(node): @@ -1476,7 +1533,7 @@ class AutoConfig(object): :returns: boolean """ - if 'interfaces' in node and len(node['interfaces']): + if "interfaces" in node and len(node["interfaces"]): return True else: return False @@ -1493,30 +1550,33 @@ class AutoConfig(object): min_sys_res = True # CPUs - if 'layout' in node['cpu']: - total_cpus = len(node['cpu']['layout']) + if "layout" in node["cpu"]: + total_cpus = len(node["cpu"]["layout"]) if total_cpus < 2: - print("\nThere is only {} CPU(s) available on this system. " - "This is not enough to run VPP.".format(total_cpus)) + print( + "\nThere is only {} CPU(s) available on this system. " + "This is not enough to run VPP.".format(total_cpus) + ) min_sys_res = False # System Memory - if 'free' in node['hugepages'] and \ - 'memfree' in node['hugepages'] and \ - 'size' in node['hugepages']: - free = node['hugepages']['free'] - memfree = float(node['hugepages']['memfree'].split(' ')[0]) - hugesize = float(node['hugepages']['size'].split(' ')[0]) + if ( + "free" in node["hugepages"] + and "memfree" in node["hugepages"] + and "size" in node["hugepages"] + ): + free = node["hugepages"]["free"] + memfree = float(node["hugepages"]["memfree"].split(" ")[0]) + hugesize = float(node["hugepages"]["size"].split(" ")[0]) memhugepages = MIN_TOTAL_HUGE_PAGES * hugesize percentmemhugepages = (memhugepages / memfree) * 100 - if free is '0' and \ - percentmemhugepages > MAX_PERCENT_FOR_HUGE_PAGES: + if free is "0" and percentmemhugepages > MAX_PERCENT_FOR_HUGE_PAGES: print( "\nThe System has only {} of free memory. You will not " "be able to allocate enough Huge Pages for VPP.".format( - int( - memfree)) + int(memfree) + ) ) min_sys_res = False @@ -1541,11 +1601,9 @@ class AutoConfig(object): # Grub print("\nGrub Command Line:") - if 'grub' in node: - print(" Current: {}".format( - node['grub']['current_cmdline'])) - print(" Configured: {}".format( - node['grub']['default_cmdline'])) + if "grub" in node: + print(" Current: {}".format(node["grub"]["current_cmdline"])) + print(" Configured: {}".format(node["grub"]["default_cmdline"])) # Huge Pages print("\nHuge Pages:") @@ -1586,17 +1644,18 @@ class AutoConfig(object): interfaces_with_ip = [] for intf in sorted(interfaces.items()): name = intf[0] - if name == 'local0': + if name == "local0": continue - question = "Would you like add address to " \ - "interface {} [Y/n]? ".format(name) - answer = self._ask_user_yn(question, 'y') - if answer == 'y': + question = "Would you like add address to " "interface {} [Y/n]? ".format( + name + ) + answer = self._ask_user_yn(question, "y") + if answer == "y": address = {} addr = self._ask_user_ipv4() - address['name'] = name - address['addr'] = addr + address["name"] = name + address["addr"] = addr interfaces_with_ip.append(address) return interfaces_with_ip @@ -1618,40 +1677,37 @@ class AutoConfig(object): for items in sorted(current_ints.items()): name = items[0] value = items[1] - if 'address' not in value: - address = 'Not Set' + if "address" not in value: + address = "Not Set" else: - address = value['address'] - print("{:30} {:20} {:10}".format(name, address, - value['state'])) - question = "\nWould you like to keep this configuration " \ - "[Y/n]? " - answer = self._ask_user_yn(question, 'y') - if answer == 'y': + address = value["address"] + print("{:30} {:20} {:10}".format(name, address, value["state"])) + question = "\nWould you like to keep this configuration " "[Y/n]? " + answer = self._ask_user_yn(question, "y") + if answer == "y": continue else: - print("\nThere are currently no interfaces with IP " - "addresses.") + print("\nThere are currently no interfaces with IP " "addresses.") # Create a script that add the ip addresses to the interfaces # and brings the interfaces up ints_with_addrs = self._ipv4_interface_setup_questions(node) - content = '' + content = "" for ints in ints_with_addrs: - name = ints['name'] - addr = ints['addr'] - setipstr = 'set int ip address {} {}\n'.format(name, addr) - setintupstr = 'set int state {} up\n'.format(name) + name = ints["name"] + addr = ints["addr"] + setipstr = "set int ip address {} {}\n".format(name, addr) + setintupstr = "set int state {} up\n".format(name) content += setipstr + setintupstr # Write the content to the script - rootdir = node['rootdir'] - filename = rootdir + '/vpp/vpp-config/scripts/set_int_ipv4_and_up' - with open(filename, 'w+') as sfile: + rootdir = node["rootdir"] + filename = rootdir + "/vpp/vpp-config/scripts/set_int_ipv4_and_up" + with open(filename, "w+") as sfile: sfile.write(content) # Execute the script - cmd = 'vppctl exec {}'.format(filename) + cmd = "vppctl exec {}".format(filename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) @@ -1679,12 +1735,13 @@ class AutoConfig(object): # First delete all the Virtual interfaces for intf in sorted(interfaces.items()): name = intf[0] - if name[:7] == 'Virtual': - cmd = 'vppctl delete vhost-user {}'.format(name) + if name[:7] == "Virtual": + cmd = "vppctl delete vhost-user {}".format(name) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, node['host'], stderr)) + logging.debug( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) # Create a virtual interface, for each interface the user wants to use interfaces = vpputl.get_hardware(node) @@ -1694,36 +1751,38 @@ class AutoConfig(object): inum = 1 for intf in sorted(interfaces.items()): name = intf[0] - if name == 'local0': + if name == "local0": continue - question = "Would you like connect this interface {} to " \ - "the VM [Y/n]? ".format(name) - answer = self._ask_user_yn(question, 'y') - if answer == 'y': - sockfilename = '/var/run/vpp/{}.sock'.format( - name.replace('/', '_')) + question = ( + "Would you like connect this interface {} to " + "the VM [Y/n]? ".format(name) + ) + answer = self._ask_user_yn(question, "y") + if answer == "y": + sockfilename = "/var/run/vpp/{}.sock".format(name.replace("/", "_")) if os.path.exists(sockfilename): os.remove(sockfilename) - cmd = 'vppctl create vhost-user socket {} server'.format( - sockfilename) + cmd = "vppctl create vhost-user socket {} server".format(sockfilename) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: raise RuntimeError( - "Couldn't execute the command {}, {}.".format(cmd, - stderr)) - vintname = stdout.rstrip('\r\n') + "Couldn't execute the command {}, {}.".format(cmd, stderr) + ) + vintname = stdout.rstrip("\r\n") - cmd = 'chmod 777 {}'.format(sockfilename) + cmd = "chmod 777 {}".format(sockfilename) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: raise RuntimeError( - "Couldn't execute the command {}, {}.".format(cmd, - stderr)) - - interface = {'name': name, - 'virtualinterface': '{}'.format(vintname), - 'bridge': '{}'.format(inum)} + "Couldn't execute the command {}, {}.".format(cmd, stderr) + ) + + interface = { + "name": name, + "virtualinterface": "{}".format(vintname), + "bridge": "{}".format(inum), + } inum += 1 interfaces_with_virtual_interfaces.append(interface) @@ -1743,49 +1802,58 @@ class AutoConfig(object): print("\nThis the current bridge configuration:") VPPUtil.show_bridge(node) question = "\nWould you like to keep this configuration [Y/n]? " - answer = self._ask_user_yn(question, 'y') - if answer == 'y': + answer = self._ask_user_yn(question, "y") + if answer == "y": continue # Create a script that builds a bridge configuration with # physical interfaces and virtual interfaces ints_with_vints = self._create_vints_questions(node) - content = '' + content = "" for intf in ints_with_vints: - vhoststr = '\n'.join([ - 'comment { The following command creates the socket }', - 'comment { and returns a virtual interface }', - 'comment {{ create vhost-user socket ' - '/var/run/vpp/sock{}.sock server }}\n'.format( - intf['bridge']) - ]) - - setintdnstr = 'set interface state {} down\n'.format( - intf['name']) - - setintbrstr = 'set interface l2 bridge {} {}\n'.format( - intf['name'], intf['bridge']) - setvintbrstr = 'set interface l2 bridge {} {}\n'.format( - intf['virtualinterface'], intf['bridge']) + vhoststr = "\n".join( + [ + "comment { The following command creates the socket }", + "comment { and returns a virtual interface }", + "comment {{ create vhost-user socket " + "/var/run/vpp/sock{}.sock server }}\n".format(intf["bridge"]), + ] + ) + + setintdnstr = "set interface state {} down\n".format(intf["name"]) + + setintbrstr = "set interface l2 bridge {} {}\n".format( + intf["name"], intf["bridge"] + ) + setvintbrstr = "set interface l2 bridge {} {}\n".format( + intf["virtualinterface"], intf["bridge"] + ) # set interface state VirtualEthernet/0/0/0 up - setintvststr = 'set interface state {} up\n'.format( - intf['virtualinterface']) + setintvststr = "set interface state {} up\n".format( + intf["virtualinterface"] + ) # set interface state VirtualEthernet/0/0/0 down - setintupstr = 'set interface state {} up\n'.format( - intf['name']) - - content += vhoststr + setintdnstr + setintbrstr + setvintbrstr + setintvststr + setintupstr + setintupstr = "set interface state {} up\n".format(intf["name"]) + + content += ( + vhoststr + + setintdnstr + + setintbrstr + + setvintbrstr + + setintvststr + + setintupstr + ) # Write the content to the script - rootdir = node['rootdir'] - filename = rootdir + '/vpp/vpp-config/scripts/create_vms_and_connect_to_vpp' - with open(filename, 'w+') as sfile: + rootdir = node["rootdir"] + filename = rootdir + "/vpp/vpp-config/scripts/create_vms_and_connect_to_vpp" + with open(filename, "w+") as sfile: sfile.write(content) # Execute the script - cmd = 'vppctl exec {}'.format(filename) + cmd = "vppctl exec {}".format(filename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) @@ -1813,12 +1881,13 @@ class AutoConfig(object): # First delete all the Virtual interfaces for intf in sorted(interfaces.items()): name = intf[0] - if name[:7] == 'Virtual': - cmd = 'vppctl delete vhost-user {}'.format(name) + if name[:7] == "Virtual": + cmd = "vppctl delete vhost-user {}".format(name) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, node['host'], stderr)) + logging.debug( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) # Create a virtual interface, for each interface the user wants to use interfaces = vpputl.get_hardware(node) @@ -1828,39 +1897,45 @@ class AutoConfig(object): inum = 1 while True: - print('\nPlease pick one interface to connect to the iperf VM.') + print("\nPlease pick one interface to connect to the iperf VM.") for intf in sorted(interfaces.items()): name = intf[0] - if name == 'local0': + if name == "local0": continue - question = "Would you like connect this interface {} to " \ - "the VM [y/N]? ".format(name) - answer = self._ask_user_yn(question, 'n') - if answer == 'y': - self._sockfilename = '/var/run/vpp/{}.sock'.format( - name.replace('/', '_')) + question = ( + "Would you like connect this interface {} to " + "the VM [y/N]? ".format(name) + ) + answer = self._ask_user_yn(question, "n") + if answer == "y": + self._sockfilename = "/var/run/vpp/{}.sock".format( + name.replace("/", "_") + ) if os.path.exists(self._sockfilename): os.remove(self._sockfilename) - cmd = 'vppctl create vhost-user socket {} server'.format( - self._sockfilename) + cmd = "vppctl create vhost-user socket {} server".format( + self._sockfilename + ) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: raise RuntimeError( - "Couldn't execute the command {}, {}.".format( - cmd, stderr)) - vintname = stdout.rstrip('\r\n') + "Couldn't execute the command {}, {}.".format(cmd, stderr) + ) + vintname = stdout.rstrip("\r\n") - cmd = 'chmod 777 {}'.format(self._sockfilename) + cmd = "chmod 777 {}".format(self._sockfilename) (ret, stdout, stderr) = vpputl.exec_command(cmd) if ret != 0: raise RuntimeError( - "Couldn't execute the command {}, {}.".format( - cmd, stderr)) - - interface = {'name': name, - 'virtualinterface': '{}'.format(vintname), - 'bridge': '{}'.format(inum)} + "Couldn't execute the command {}, {}.".format(cmd, stderr) + ) + + interface = { + "name": name, + "virtualinterface": "{}".format(vintname), + "bridge": "{}".format(inum), + } inum += 1 interfaces_with_virtual_interfaces.append(interface) return interfaces_with_virtual_interfaces @@ -1879,52 +1954,62 @@ class AutoConfig(object): print("\nThis the current bridge configuration:") ifaces = VPPUtil.show_bridge(node) question = "\nWould you like to keep this configuration [Y/n]? " - answer = self._ask_user_yn(question, 'y') - if answer == 'y': - self._sockfilename = '/var/run/vpp/{}.sock'.format( - ifaces[0]['name'].replace('/', '_')) + answer = self._ask_user_yn(question, "y") + if answer == "y": + self._sockfilename = "/var/run/vpp/{}.sock".format( + ifaces[0]["name"].replace("/", "_") + ) if os.path.exists(self._sockfilename): continue # Create a script that builds a bridge configuration with # physical interfaces and virtual interfaces ints_with_vints = self._iperf_vm_questions(node) - content = '' + content = "" for intf in ints_with_vints: - vhoststr = '\n'.join([ - 'comment { The following command creates the socket }', - 'comment { and returns a virtual interface }', - 'comment {{ create vhost-user socket ' - '/var/run/vpp/sock{}.sock server }}\n'.format( - intf['bridge']) - ]) - - setintdnstr = 'set interface state {} down\n'.format( - intf['name']) - - setintbrstr = 'set interface l2 bridge {} {}\n'.format( - intf['name'], intf['bridge']) - setvintbrstr = 'set interface l2 bridge {} {}\n'.format( - intf['virtualinterface'], intf['bridge']) + vhoststr = "\n".join( + [ + "comment { The following command creates the socket }", + "comment { and returns a virtual interface }", + "comment {{ create vhost-user socket " + "/var/run/vpp/sock{}.sock server }}\n".format(intf["bridge"]), + ] + ) + + setintdnstr = "set interface state {} down\n".format(intf["name"]) + + setintbrstr = "set interface l2 bridge {} {}\n".format( + intf["name"], intf["bridge"] + ) + setvintbrstr = "set interface l2 bridge {} {}\n".format( + intf["virtualinterface"], intf["bridge"] + ) # set interface state VirtualEthernet/0/0/0 up - setintvststr = 'set interface state {} up\n'.format( - intf['virtualinterface']) + setintvststr = "set interface state {} up\n".format( + intf["virtualinterface"] + ) # set interface state VirtualEthernet/0/0/0 down - setintupstr = 'set interface state {} up\n'.format( - intf['name']) - - content += vhoststr + setintdnstr + setintbrstr + setvintbrstr + setintvststr + setintupstr + setintupstr = "set interface state {} up\n".format(intf["name"]) + + content += ( + vhoststr + + setintdnstr + + setintbrstr + + setvintbrstr + + setintvststr + + setintupstr + ) # Write the content to the script - rootdir = node['rootdir'] - filename = rootdir + '/vpp/vpp-config/scripts/create_iperf_vm' - with open(filename, 'w+') as sfile: + rootdir = node["rootdir"] + filename = rootdir + "/vpp/vpp-config/scripts/create_iperf_vm" + with open(filename, "w+") as sfile: sfile.write(content) # Execute the script - cmd = 'vppctl exec {}'.format(filename) + cmd = "vppctl exec {}".format(filename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) @@ -1943,21 +2028,22 @@ class AutoConfig(object): :type name: str """ - cmd = 'virsh list' + cmd = "virsh list" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) raise RuntimeError( - "Couldn't execute the command {} : {}".format(cmd, stderr)) + "Couldn't execute the command {} : {}".format(cmd, stderr) + ) if re.findall(name, stdout): - cmd = 'virsh destroy {}'.format(name) + cmd = "virsh destroy {}".format(name) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) raise RuntimeError( - "Couldn't execute the command {} : {}".format( - cmd, stderr)) + "Couldn't execute the command {} : {}".format(cmd, stderr) + ) def create_iperf_vm(self, vmname): """ @@ -1968,36 +2054,39 @@ class AutoConfig(object): # Read the iperf VM template file distro = VPPUtil.get_linux_distro() - if distro[0] == 'Ubuntu': - tfilename = \ - '{}/vpp/vpp-config/configs/iperf-ubuntu.xml.template'.format( - self._rootdir) + if distro[0] == "Ubuntu": + tfilename = "{}/vpp/vpp-config/configs/iperf-ubuntu.xml.template".format( + self._rootdir + ) else: - tfilename = \ - '{}/vpp/vpp-config/configs/iperf-centos.xml.template'.format( - self._rootdir) + tfilename = "{}/vpp/vpp-config/configs/iperf-centos.xml.template".format( + self._rootdir + ) - with open(tfilename, 'r') as tfile: + with open(tfilename, "r") as tfile: tcontents = tfile.read() tfile.close() # Add the variables - imagename = '{}/vpp/vpp-config/{}'.format( - self._rootdir, IPERFVM_IMAGE) - isoname = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_ISO) - tcontents = tcontents.format(vmname=vmname, imagename=imagename, - isoname=isoname, - vhostsocketname=self._sockfilename) + imagename = "{}/vpp/vpp-config/{}".format(self._rootdir, IPERFVM_IMAGE) + isoname = "{}/vpp/vpp-config/{}".format(self._rootdir, IPERFVM_ISO) + tcontents = tcontents.format( + vmname=vmname, + imagename=imagename, + isoname=isoname, + vhostsocketname=self._sockfilename, + ) # Write the xml - ifilename = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_XML) - with open(ifilename, 'w+') as ifile: + ifilename = "{}/vpp/vpp-config/{}".format(self._rootdir, IPERFVM_XML) + with open(ifilename, "w+") as ifile: ifile.write(tcontents) ifile.close() - cmd = 'virsh create {}'.format(ifilename) + cmd = "virsh create {}".format(ifilename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: logging.debug(stderr) raise RuntimeError( - "Couldn't execute the command {} : {}".format(cmd, stderr)) + "Couldn't execute the command {} : {}".format(cmd, stderr) + ) diff --git a/extras/vpp_config/vpplib/CpuUtils.py b/extras/vpp_config/vpplib/CpuUtils.py index 23f418d33be..f6ba3d74746 100644 --- a/extras/vpp_config/vpplib/CpuUtils.py +++ b/extras/vpp_config/vpplib/CpuUtils.py @@ -78,13 +78,14 @@ class CpuUtils(object): # 1,1,0,0,,1,1,1,0 if ret != 0: raise RuntimeError( - "Failed to execute ssh command, ret: {} err: {}".format( - ret, stderr)) - node['cpuinfo'] = list() + "Failed to execute ssh command, ret: {} err: {}".format(ret, stderr) + ) + node["cpuinfo"] = list() for line in stdout.split("\n"): - if line != '' and line[0] != "#": - node['cpuinfo'].append([CpuUtils.__str2int(x) for x in - line.split(",")]) + if line != "" and line[0] != "#": + node["cpuinfo"].append( + [CpuUtils.__str2int(x) for x in line.split(",")] + ) @staticmethod def cpu_node_count(node): @@ -137,13 +138,14 @@ class CpuUtils(object): if smt_enabled and not smt_used: cpu_list_len = len(cpu_list) - cpu_list = cpu_list[:cpu_list_len // CpuUtils.NR_OF_THREADS] + cpu_list = cpu_list[: cpu_list_len // CpuUtils.NR_OF_THREADS] return cpu_list @staticmethod - def cpu_slice_of_list_per_node(node, cpu_node, skip_cnt=0, cpu_cnt=0, - smt_used=False): + def cpu_slice_of_list_per_node( + node, cpu_node, skip_cnt=0, cpu_cnt=0, smt_used=False + ): """Return string of node related list of CPU numbers. :param node: Node dictionary with cpuinfo. @@ -171,20 +173,20 @@ class CpuUtils(object): cpu_cnt = cpu_list_len - skip_cnt if smt_used: - cpu_list_0 = cpu_list[:cpu_list_len // CpuUtils.NR_OF_THREADS] - cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS:] - cpu_list = [cpu for cpu in cpu_list_0[skip_cnt:skip_cnt + cpu_cnt]] - cpu_list_ex = [cpu for cpu in - cpu_list_1[skip_cnt:skip_cnt + cpu_cnt]] + cpu_list_0 = cpu_list[: cpu_list_len // CpuUtils.NR_OF_THREADS] + cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS :] + cpu_list = [cpu for cpu in cpu_list_0[skip_cnt : skip_cnt + cpu_cnt]] + cpu_list_ex = [cpu for cpu in cpu_list_1[skip_cnt : skip_cnt + cpu_cnt]] cpu_list.extend(cpu_list_ex) else: - cpu_list = [cpu for cpu in cpu_list[skip_cnt:skip_cnt + cpu_cnt]] + cpu_list = [cpu for cpu in cpu_list[skip_cnt : skip_cnt + cpu_cnt]] return cpu_list @staticmethod - def cpu_list_per_node_str(node, cpu_node, skip_cnt=0, cpu_cnt=0, sep=",", - smt_used=False): + def cpu_list_per_node_str( + node, cpu_node, skip_cnt=0, cpu_cnt=0, sep=",", smt_used=False + ): """Return string of node related list of CPU numbers. :param node: Node dictionary with cpuinfo. @@ -203,15 +205,15 @@ class CpuUtils(object): :rtype: str """ - cpu_list = CpuUtils.cpu_slice_of_list_per_node(node, cpu_node, - skip_cnt=skip_cnt, - cpu_cnt=cpu_cnt, - smt_used=smt_used) + cpu_list = CpuUtils.cpu_slice_of_list_per_node( + node, cpu_node, skip_cnt=skip_cnt, cpu_cnt=cpu_cnt, smt_used=smt_used + ) return sep.join(str(cpu) for cpu in cpu_list) @staticmethod - def cpu_range_per_node_str(node, cpu_node, skip_cnt=0, cpu_cnt=0, sep="-", - smt_used=False): + def cpu_range_per_node_str( + node, cpu_node, skip_cnt=0, cpu_cnt=0, sep="-", smt_used=False + ): """Return string of node related range of CPU numbers, e.g. 0-4. :param node: Node dictionary with cpuinfo. @@ -230,18 +232,16 @@ class CpuUtils(object): :rtype: str """ - cpu_list = CpuUtils.cpu_slice_of_list_per_node(node, cpu_node, - skip_cnt=skip_cnt, - cpu_cnt=cpu_cnt, - smt_used=smt_used) + cpu_list = CpuUtils.cpu_slice_of_list_per_node( + node, cpu_node, skip_cnt=skip_cnt, cpu_cnt=cpu_cnt, smt_used=smt_used + ) if smt_used: cpu_list_len = len(cpu_list) - cpu_list_0 = cpu_list[:cpu_list_len // CpuUtils.NR_OF_THREADS] - cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS:] - cpu_range = "{}{}{},{}{}{}".format(cpu_list_0[0], sep, - cpu_list_0[-1], - cpu_list_1[0], sep, - cpu_list_1[-1]) + cpu_list_0 = cpu_list[: cpu_list_len // CpuUtils.NR_OF_THREADS] + cpu_list_1 = cpu_list[cpu_list_len // CpuUtils.NR_OF_THREADS :] + cpu_range = "{}{}{},{}{}{}".format( + cpu_list_0[0], sep, cpu_list_0[-1], cpu_list_1[0], sep, cpu_list_1[-1] + ) else: cpu_range = "{}{}{}".format(cpu_list[0], sep, cpu_list[-1]) @@ -260,28 +260,30 @@ class CpuUtils(object): cmd = "lscpu" ret, stdout, stderr = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError("lscpu command failed on node {} {}." - .format(node['host'], stderr)) + raise RuntimeError( + "lscpu command failed on node {} {}.".format(node["host"], stderr) + ) cpuinfo = {} - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: - if line != '': - linesplit = re.split(r':\s+', line) + if line != "": + linesplit = re.split(r":\s+", line) cpuinfo[linesplit[0]] = linesplit[1] cmd = "cat /proc/*/task/*/stat | awk '{print $1" "$2" "$39}'" ret, stdout, stderr = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError("cat command failed on node {} {}." - .format(node['host'], stderr)) + raise RuntimeError( + "cat command failed on node {} {}.".format(node["host"], stderr) + ) vpp_processes = {} - vpp_lines = re.findall(r'\w+\(vpp_\w+\)\w+', stdout) + vpp_lines = re.findall(r"\w+\(vpp_\w+\)\w+", stdout) for line in vpp_lines: - linesplit = re.split(r'\w+\(', line)[1].split(')') + linesplit = re.split(r"\w+\(", line)[1].split(")") vpp_processes[linesplit[0]] = linesplit[1] - cpuinfo['vpp_processes'] = vpp_processes + cpuinfo["vpp_processes"] = vpp_processes return cpuinfo diff --git a/extras/vpp_config/vpplib/QemuUtils.py b/extras/vpp_config/vpplib/QemuUtils.py index 0b7e08b12d8..e1da7ae72bf 100644 --- a/extras/vpp_config/vpplib/QemuUtils.py +++ b/extras/vpp_config/vpplib/QemuUtils.py @@ -12,7 +12,7 @@ # limitations under the License. """QEMU utilities library.""" -from __future__ import absolute_import, division +from __future__ import absolute_import, division from time import time, sleep import json @@ -24,12 +24,13 @@ from vpplib.constants import Constants class NodeType(object): """Defines node types used in topology dictionaries.""" + # Device Under Test (this node has VPP running on it) - DUT = 'DUT' + DUT = "DUT" # Traffic Generator (this node has traffic generator on it) - TG = 'TG' + TG = "TG" # Virtual Machine (this node running on DUT node) - VM = 'VM' + VM = "VM" class QemuUtils(object): @@ -39,43 +40,46 @@ class QemuUtils(object): def __init__(self, qemu_id=1): self._qemu_id = qemu_id # Path to QEMU binary - self._qemu_bin = '/usr/bin/qemu-system-x86_64' + self._qemu_bin = "/usr/bin/qemu-system-x86_64" # QEMU Machine Protocol socket - self._qmp_sock = '/tmp/qmp{0}.sock'.format(self._qemu_id) + self._qmp_sock = "/tmp/qmp{0}.sock".format(self._qemu_id) # QEMU Guest Agent socket - self._qga_sock = '/tmp/qga{0}.sock'.format(self._qemu_id) + self._qga_sock = "/tmp/qga{0}.sock".format(self._qemu_id) # QEMU PID file - self._pid_file = '/tmp/qemu{0}.pid'.format(self._qemu_id) + self._pid_file = "/tmp/qemu{0}.pid".format(self._qemu_id) self._qemu_opt = {} # Default 1 CPU. - self._qemu_opt['smp'] = '-smp 1,sockets=1,cores=1,threads=1' + self._qemu_opt["smp"] = "-smp 1,sockets=1,cores=1,threads=1" # Daemonize the QEMU process after initialization. Default one # management interface. - self._qemu_opt['options'] = '-cpu host -daemonize -enable-kvm ' \ - '-machine pc,accel=kvm,usb=off,mem-merge=off ' \ - '-net nic,macaddr=52:54:00:00:{0:02x}:ff -balloon none'\ - .format(self._qemu_id) - self._qemu_opt['ssh_fwd_port'] = 10021 + qemu_id + self._qemu_opt["options"] = ( + "-cpu host -daemonize -enable-kvm " + "-machine pc,accel=kvm,usb=off,mem-merge=off " + "-net nic,macaddr=52:54:00:00:{0:02x}:ff -balloon none".format( + self._qemu_id + ) + ) + self._qemu_opt["ssh_fwd_port"] = 10021 + qemu_id # Default serial console port - self._qemu_opt['serial_port'] = 4555 + qemu_id + self._qemu_opt["serial_port"] = 4555 + qemu_id # Default 512MB virtual RAM - self._qemu_opt['mem_size'] = 512 + self._qemu_opt["mem_size"] = 512 # Default huge page mount point, required for Vhost-user interfaces. - self._qemu_opt['huge_mnt'] = '/mnt/huge' + self._qemu_opt["huge_mnt"] = "/mnt/huge" # Default do not allocate huge pages. - self._qemu_opt['huge_allocate'] = False + self._qemu_opt["huge_allocate"] = False # Default image for CSIT virl setup - self._qemu_opt['disk_image'] = '/var/lib/vm/vhost-nested.img' + self._qemu_opt["disk_image"] = "/var/lib/vm/vhost-nested.img" # VM node info dict self._vm_info = { - 'type': NodeType.VM, - 'port': self._qemu_opt['ssh_fwd_port'], - 'username': 'cisco', - 'password': 'cisco', - 'interfaces': {}, + "type": NodeType.VM, + "port": self._qemu_opt["ssh_fwd_port"], + "username": "cisco", + "password": "cisco", + "interfaces": {}, } # Virtio queue count - self._qemu_opt['queues'] = 1 + self._qemu_opt["queues"] = 1 self._vhost_id = 0 self._ssh = None self._node = None @@ -101,9 +105,9 @@ class QemuUtils(object): :type threads: int :type sockets: int """ - self._qemu_opt['smp'] = \ - '-smp {},cores={},threads={},sockets={}'.format( - cpus, cores, threads, sockets) + self._qemu_opt["smp"] = "-smp {},cores={},threads={},sockets={}".format( + cpus, cores, threads, sockets + ) def qemu_set_ssh_fwd_port(self, fwd_port): """Set host port for guest SSH forwarding. @@ -111,8 +115,8 @@ class QemuUtils(object): :param fwd_port: Port number on host for guest SSH forwarding. :type fwd_port: int """ - self._qemu_opt['ssh_fwd_port'] = fwd_port - self._vm_info['port'] = fwd_port + self._qemu_opt["ssh_fwd_port"] = fwd_port + self._vm_info["port"] = fwd_port def qemu_set_serial_port(self, port): """Set serial console port. @@ -120,7 +124,7 @@ class QemuUtils(object): :param port: Serial console port. :type port: int """ - self._qemu_opt['serial_port'] = port + self._qemu_opt["serial_port"] = port def qemu_set_mem_size(self, mem_size): """Set virtual RAM size. @@ -128,7 +132,7 @@ class QemuUtils(object): :param mem_size: RAM size in Mega Bytes. :type mem_size: int """ - self._qemu_opt['mem_size'] = int(mem_size) + self._qemu_opt["mem_size"] = int(mem_size) def qemu_set_huge_mnt(self, huge_mnt): """Set hugefile mount point. @@ -136,11 +140,11 @@ class QemuUtils(object): :param huge_mnt: System hugefile mount point. :type huge_mnt: int """ - self._qemu_opt['huge_mnt'] = huge_mnt + self._qemu_opt["huge_mnt"] = huge_mnt def qemu_set_huge_allocate(self): """Set flag to allocate more huge pages if needed.""" - self._qemu_opt['huge_allocate'] = True + self._qemu_opt["huge_allocate"] = True def qemu_set_disk_image(self, disk_image): """Set disk image. @@ -148,7 +152,7 @@ class QemuUtils(object): :param disk_image: Path of the disk image. :type disk_image: str """ - self._qemu_opt['disk_image'] = disk_image + self._qemu_opt["disk_image"] = disk_image def qemu_set_affinity(self, *host_cpus): """Set qemu affinity by getting thread PIDs via QMP and taskset to list @@ -157,36 +161,41 @@ class QemuUtils(object): :param host_cpus: List of CPU cores. :type host_cpus: list """ - qemu_cpus = self._qemu_qmp_exec('query-cpus')['return'] + qemu_cpus = self._qemu_qmp_exec("query-cpus")["return"] if len(qemu_cpus) != len(host_cpus): - logging.debug('Host CPU count {0}, Qemu Thread count {1}'.format( - len(host_cpus), len(qemu_cpus))) - raise ValueError('Host CPU count must match Qemu Thread count') + logging.debug( + "Host CPU count {0}, Qemu Thread count {1}".format( + len(host_cpus), len(qemu_cpus) + ) + ) + raise ValueError("Host CPU count must match Qemu Thread count") for qemu_cpu, host_cpu in zip(qemu_cpus, host_cpus): - cmd = 'taskset -pc {0} {1}'.format(host_cpu, qemu_cpu['thread_id']) + cmd = "taskset -pc {0} {1}".format(host_cpu, qemu_cpu["thread_id"]) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) if int(ret_code) != 0: - logging.debug('Set affinity failed {0}'.format(stderr)) - raise RuntimeError('Set affinity failed on {0}'.format( - self._node['host'])) + logging.debug("Set affinity failed {0}".format(stderr)) + raise RuntimeError( + "Set affinity failed on {0}".format(self._node["host"]) + ) def qemu_set_scheduler_policy(self): """Set scheduler policy to SCHED_RR with priority 1 for all Qemu CPU - processes. + processes. - :raises RuntimeError: Set scheduler policy failed. + :raises RuntimeError: Set scheduler policy failed. """ - qemu_cpus = self._qemu_qmp_exec('query-cpus')['return'] + qemu_cpus = self._qemu_qmp_exec("query-cpus")["return"] for qemu_cpu in qemu_cpus: - cmd = 'chrt -r -p 1 {0}'.format(qemu_cpu['thread_id']) + cmd = "chrt -r -p 1 {0}".format(qemu_cpu["thread_id"]) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) if int(ret_code) != 0: - logging.debug('Set SCHED_RR failed {0}'.format(stderr)) - raise RuntimeError('Set SCHED_RR failed on {0}'.format( - self._node['host'])) + logging.debug("Set SCHED_RR failed {0}".format(stderr)) + raise RuntimeError( + "Set SCHED_RR failed on {0}".format(self._node["host"]) + ) def qemu_set_node(self, node): """Set node to run QEMU on. @@ -195,7 +204,7 @@ class QemuUtils(object): :type node: dict """ self._node = node - self._vm_info['host'] = node['host'] + self._vm_info["host"] = node["host"] def qemu_add_vhost_user_if(self, socket, server=True, mac=None): """Add Vhost-user interface. @@ -210,31 +219,33 @@ class QemuUtils(object): """ self._vhost_id += 1 # Create unix socket character device. - chardev = ' -chardev socket,id=char{0},path={1}'.format(self._vhost_id, - socket) + chardev = " -chardev socket,id=char{0},path={1}".format(self._vhost_id, socket) if server is True: - chardev += ',server' - self._qemu_opt['options'] += chardev + chardev += ",server" + self._qemu_opt["options"] += chardev # Create Vhost-user network backend. - netdev = (' -netdev vhost-user,id=vhost{0},chardev=char{0},queues={1}' - .format(self._vhost_id, self._qemu_opt['queues'])) - self._qemu_opt['options'] += netdev + netdev = " -netdev vhost-user,id=vhost{0},chardev=char{0},queues={1}".format( + self._vhost_id, self._qemu_opt["queues"] + ) + self._qemu_opt["options"] += netdev # If MAC is not specified use auto-generated MAC address based on # template 52:54:00:00:<qemu_id>:<vhost_id>, e.g. vhost1 MAC of QEMU # with ID 1 is 52:54:00:00:01:01 if mac is None: - mac = '52:54:00:00:{0:02x}:{1:02x}'.\ - format(self._qemu_id, self._vhost_id) - extend_options = 'mq=on,csum=off,gso=off,guest_tso4=off,'\ - 'guest_tso6=off,guest_ecn=off,mrg_rxbuf=off' + mac = "52:54:00:00:{0:02x}:{1:02x}".format(self._qemu_id, self._vhost_id) + extend_options = ( + "mq=on,csum=off,gso=off,guest_tso4=off," + "guest_tso6=off,guest_ecn=off,mrg_rxbuf=off" + ) # Create Virtio network device. - device = ' -device virtio-net-pci,netdev=vhost{0},mac={1},{2}'.format( - self._vhost_id, mac, extend_options) - self._qemu_opt['options'] += device + device = " -device virtio-net-pci,netdev=vhost{0},mac={1},{2}".format( + self._vhost_id, mac, extend_options + ) + self._qemu_opt["options"] += device # Add interface MAC and socket to the node dict - if_data = {'mac_address': mac, 'socket': socket} - if_name = 'vhost{}'.format(self._vhost_id) - self._vm_info['interfaces'][if_name] = if_data + if_data = {"mac_address": mac, "socket": socket} + if_name = "vhost{}".format(self._vhost_id) + self._vm_info["interfaces"][if_name] = if_data # Add socket to the socket list self._socks.append(socket) @@ -250,41 +261,44 @@ class QemuUtils(object): response will contain the "error" keyword instead of "return". """ # To enter command mode, the qmp_capabilities command must be issued. - qmp_cmd = 'echo "{ \\"execute\\": \\"qmp_capabilities\\" }' \ - '{ \\"execute\\": \\"' + cmd + \ - '\\" }" | sudo -S socat - UNIX-CONNECT:' + self._qmp_sock + qmp_cmd = ( + 'echo "{ \\"execute\\": \\"qmp_capabilities\\" }' + '{ \\"execute\\": \\"' + + cmd + + '\\" }" | sudo -S socat - UNIX-CONNECT:' + + self._qmp_sock + ) (ret_code, stdout, stderr) = self._ssh.exec_command(qmp_cmd) if int(ret_code) != 0: - logging.debug('QMP execute failed {0}'.format(stderr)) - raise RuntimeError('QMP execute "{0}"' - ' failed on {1}'.format( - cmd, self._node['host'])) + logging.debug("QMP execute failed {0}".format(stderr)) + raise RuntimeError( + 'QMP execute "{0}"' " failed on {1}".format(cmd, self._node["host"]) + ) logging.debug(stdout) # Skip capabilities negotiation messages. out_list = stdout.splitlines() if len(out_list) < 3: - raise RuntimeError('Invalid QMP output on {0}'.format( - self._node['host'])) + raise RuntimeError("Invalid QMP output on {0}".format(self._node["host"])) return json.loads(out_list[2]) def _qemu_qga_flush(self): - """Flush the QGA parser state - """ - qga_cmd = '(printf "\xFF"; sleep 1) | ' \ - 'sudo -S socat - UNIX-CONNECT:' + \ - self._qga_sock + """Flush the QGA parser state""" + qga_cmd = ( + '(printf "\xFF"; sleep 1) | ' + "sudo -S socat - UNIX-CONNECT:" + self._qga_sock + ) # TODO: probably need something else (ret_code, stdout, stderr) = self._ssh.exec_command(qga_cmd) if int(ret_code) != 0: - logging.debug('QGA execute failed {0}'.format(stderr)) - raise RuntimeError('QGA execute "{0}" ' - 'failed on {1}'.format(qga_cmd, - self._node['host'])) + logging.debug("QGA execute failed {0}".format(stderr)) + raise RuntimeError( + 'QGA execute "{0}" ' "failed on {1}".format(qga_cmd, self._node["host"]) + ) logging.debug(stdout) if not stdout: return {} - return json.loads(stdout.split('\n', 1)[0]) + return json.loads(stdout.split("\n", 1)[0]) def _qemu_qga_exec(self, cmd): """Execute QGA command. @@ -294,20 +308,22 @@ class QemuUtils(object): :param cmd: QGA command to execute. :type cmd: str """ - qga_cmd = '(echo "{ \\"execute\\": \\"' + \ - cmd + \ - '\\" }"; sleep 1) | sudo -S socat - UNIX-CONNECT:' + \ - self._qga_sock + qga_cmd = ( + '(echo "{ \\"execute\\": \\"' + + cmd + + '\\" }"; sleep 1) | sudo -S socat - UNIX-CONNECT:' + + self._qga_sock + ) (ret_code, stdout, stderr) = self._ssh.exec_command(qga_cmd) if int(ret_code) != 0: - logging.debug('QGA execute failed {0}'.format(stderr)) - raise RuntimeError('QGA execute "{0}"' - ' failed on {1}'.format( - cmd, self._node['host'])) + logging.debug("QGA execute failed {0}".format(stderr)) + raise RuntimeError( + 'QGA execute "{0}"' " failed on {1}".format(cmd, self._node["host"]) + ) logging.debug(stdout) if not stdout: return {} - return json.loads(stdout.split('\n', 1)[0]) + return json.loads(stdout.split("\n", 1)[0]) def _wait_until_vm_boot(self, timeout=60): """Wait until QEMU VM is booted. @@ -320,65 +336,69 @@ class QemuUtils(object): start = time() while True: if time() - start > timeout: - raise RuntimeError('timeout, VM {0} not booted on {1}'.format( - self._qemu_opt['disk_image'], self._node['host'])) + raise RuntimeError( + "timeout, VM {0} not booted on {1}".format( + self._qemu_opt["disk_image"], self._node["host"] + ) + ) out = None try: self._qemu_qga_flush() - out = self._qemu_qga_exec('guest-ping') + out = self._qemu_qga_exec("guest-ping") except ValueError: - logging.debug( - 'QGA guest-ping unexpected output {}'.format(out)) + logging.debug("QGA guest-ping unexpected output {}".format(out)) # Empty output - VM not booted yet if not out: sleep(5) # Non-error return - VM booted - elif out.get('return') is not None: + elif out.get("return") is not None: break # Skip error and wait - elif out.get('error') is not None: + elif out.get("error") is not None: sleep(5) else: # If there is an unexpected output from QGA guest-info, try # again until timeout. - logging.debug( - 'QGA guest-ping unexpected output {}'.format(out)) + logging.debug("QGA guest-ping unexpected output {}".format(out)) logging.debug( - 'VM {0} booted on {1}'.format(self._qemu_opt['disk_image'], - self._node['host'])) + "VM {0} booted on {1}".format( + self._qemu_opt["disk_image"], self._node["host"] + ) + ) def _update_vm_interfaces(self): """Update interface names in VM node dict.""" # Send guest-network-get-interfaces command via QGA, output example: # {"return": [{"name": "eth0", "hardware-address": "52:54:00:00:04:01"}, # {"name": "eth1", "hardware-address": "52:54:00:00:04:02"}]} - out = self._qemu_qga_exec('guest-network-get-interfaces') - interfaces = out.get('return') + out = self._qemu_qga_exec("guest-network-get-interfaces") + interfaces = out.get("return") mac_name = {} if not interfaces: raise RuntimeError( - 'Get VM {0} interface list failed on {1}'.format( - self._qemu_opt['disk_image'], self._node['host'])) + "Get VM {0} interface list failed on {1}".format( + self._qemu_opt["disk_image"], self._node["host"] + ) + ) # Create MAC-name dict for interface in interfaces: - if 'hardware-address' not in interface: + if "hardware-address" not in interface: continue - mac_name[interface['hardware-address']] = interface['name'] + mac_name[interface["hardware-address"]] = interface["name"] # Match interface by MAC and save interface name - for interface in self._vm_info['interfaces'].values(): - mac = interface.get('mac_address') + for interface in self._vm_info["interfaces"].values(): + mac = interface.get("mac_address") if_name = mac_name.get(mac) if if_name is None: - logging.debug( - 'Interface name for MAC {} not found'.format(mac)) + logging.debug("Interface name for MAC {} not found".format(mac)) else: - interface['name'] = if_name + interface["name"] = if_name def _huge_page_check(self, allocate=False): """Huge page check.""" - huge_mnt = self._qemu_opt.get('huge_mnt') - mem_size = self._qemu_opt.get('mem_size') + huge_mnt = self._qemu_opt.get("huge_mnt") + mem_size = self._qemu_opt.get("mem_size") # Get huge pages information huge_size = self._get_huge_page_size() @@ -391,55 +411,55 @@ class QemuUtils(object): if allocate: mem_needed = abs((huge_free * huge_size) - (mem_size * 1024)) huge_to_allocate = ((mem_needed // huge_size) * 2) + huge_total - max_map_count = huge_to_allocate*4 + max_map_count = huge_to_allocate * 4 # Increase maximum number of memory map areas a # process may have - cmd = \ - 'echo "{0}" | sudo tee /proc/sys/vm/max_map_count'.format( - max_map_count) + cmd = 'echo "{0}" | sudo tee /proc/sys/vm/max_map_count'.format( + max_map_count + ) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) # Increase hugepage count - cmd = \ - 'echo "{0}" | sudo tee /proc/sys/vm/nr_hugepages'.format( - huge_to_allocate) + cmd = 'echo "{0}" | sudo tee /proc/sys/vm/nr_hugepages'.format( + huge_to_allocate + ) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) if int(ret_code) != 0: - logging.debug( - 'Mount huge pages failed {0}'.format(stderr)) + logging.debug("Mount huge pages failed {0}".format(stderr)) raise RuntimeError( - 'Mount huge pages failed on {0}'.format( - self._node['host'])) + "Mount huge pages failed on {0}".format(self._node["host"]) + ) # If we do not want to allocate dynamicaly end with error else: raise RuntimeError( - 'Not enough free huge pages: {0}, ' - '{1} MB'.format(huge_free, huge_free * huge_size) + "Not enough free huge pages: {0}, " + "{1} MB".format(huge_free, huge_free * huge_size) ) # Check if huge pages mount point exist has_huge_mnt = False - (_, output, _) = self._ssh.exec_command('cat /proc/mounts') + (_, output, _) = self._ssh.exec_command("cat /proc/mounts") for line in output.splitlines(): # Try to find something like: # none /mnt/huge hugetlbfs rw,relatime,pagesize=2048k 0 0 mount = line.split() - if mount[2] == 'hugetlbfs' and mount[1] == huge_mnt: + if mount[2] == "hugetlbfs" and mount[1] == huge_mnt: has_huge_mnt = True break # If huge page mount point not exist create one if not has_huge_mnt: - cmd = 'mkdir -p {0}'.format(huge_mnt) + cmd = "mkdir -p {0}".format(huge_mnt) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) if int(ret_code) != 0: - logging.debug('Create mount dir failed: {0}'.format(stderr)) - raise RuntimeError('Create mount dir failed on {0}'.format( - self._node['host'])) - cmd = 'mount -t hugetlbfs -o pagesize=2048k none {0}'.format( - huge_mnt) + logging.debug("Create mount dir failed: {0}".format(stderr)) + raise RuntimeError( + "Create mount dir failed on {0}".format(self._node["host"]) + ) + cmd = "mount -t hugetlbfs -o pagesize=2048k none {0}".format(huge_mnt) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd) if int(ret_code) != 0: - logging.debug('Mount huge pages failed {0}'.format(stderr)) - raise RuntimeError('Mount huge pages failed on {0}'.format( - self._node['host'])) + logging.debug("Mount huge pages failed {0}".format(stderr)) + raise RuntimeError( + "Mount huge pages failed on {0}".format(self._node["host"]) + ) def _get_huge_page_size(self): """Get default size of huge pages in system. @@ -456,11 +476,11 @@ class QemuUtils(object): try: huge_size = int(out) except ValueError: - logging.debug('Reading huge page size information failed') + logging.debug("Reading huge page size information failed") else: break else: - raise RuntimeError('Getting huge page size information failed.') + raise RuntimeError("Getting huge page size information failed.") return huge_size def _get_huge_page_free(self, huge_size): @@ -474,20 +494,21 @@ class QemuUtils(object): """ # TODO: add numa aware option # TODO: remove to dedicated library - cmd_huge_free = 'cat /sys/kernel/mm/hugepages/hugepages-{0}kB/'\ - 'free_hugepages'.format(huge_size) + cmd_huge_free = ( + "cat /sys/kernel/mm/hugepages/hugepages-{0}kB/" + "free_hugepages".format(huge_size) + ) for _ in range(3): (ret, out, _) = self._ssh.exec_command_sudo(cmd_huge_free) if ret == 0: try: huge_free = int(out) except ValueError: - logging.debug( - 'Reading free huge pages information failed') + logging.debug("Reading free huge pages information failed") else: break else: - raise RuntimeError('Getting free huge pages information failed.') + raise RuntimeError("Getting free huge pages information failed.") return huge_free def _get_huge_page_total(self, huge_size): @@ -501,20 +522,21 @@ class QemuUtils(object): """ # TODO: add numa aware option # TODO: remove to dedicated library - cmd_huge_total = 'cat /sys/kernel/mm/hugepages/hugepages-{0}kB/'\ - 'nr_hugepages'.format(huge_size) + cmd_huge_total = ( + "cat /sys/kernel/mm/hugepages/hugepages-{0}kB/" + "nr_hugepages".format(huge_size) + ) for _ in range(3): (ret, out, _) = self._ssh.exec_command_sudo(cmd_huge_total) if ret == 0: try: huge_total = int(out) except ValueError: - logging.debug( - 'Reading total huge pages information failed') + logging.debug("Reading total huge pages information failed") else: break else: - raise RuntimeError('Getting total huge pages information failed.') + raise RuntimeError("Getting total huge pages information failed.") return huge_total def qemu_start(self): @@ -526,45 +548,63 @@ class QemuUtils(object): .. warning:: Starts only one VM on the node. """ # SSH forwarding - ssh_fwd = '-net user,hostfwd=tcp::{0}-:22'.format( - self._qemu_opt.get('ssh_fwd_port')) + ssh_fwd = "-net user,hostfwd=tcp::{0}-:22".format( + self._qemu_opt.get("ssh_fwd_port") + ) # Memory and huge pages - mem = '-object memory-backend-file,id=mem,size={0}M,mem-path={1},' \ - 'share=on -m {0} -numa node,memdev=mem'.format( - self._qemu_opt.get('mem_size'), self._qemu_opt.get('huge_mnt')) + mem = ( + "-object memory-backend-file,id=mem,size={0}M,mem-path={1}," + "share=on -m {0} -numa node,memdev=mem".format( + self._qemu_opt.get("mem_size"), self._qemu_opt.get("huge_mnt") + ) + ) # By default check only if hugepages are available. # If 'huge_allocate' is set to true try to allocate as well. - self._huge_page_check(allocate=self._qemu_opt.get('huge_allocate')) + self._huge_page_check(allocate=self._qemu_opt.get("huge_allocate")) # Disk option - drive = '-drive file={0},format=raw,cache=none,if=virtio'.format( - self._qemu_opt.get('disk_image')) + drive = "-drive file={0},format=raw,cache=none,if=virtio".format( + self._qemu_opt.get("disk_image") + ) # Setup QMP via unix socket - qmp = '-qmp unix:{0},server,nowait'.format(self._qmp_sock) + qmp = "-qmp unix:{0},server,nowait".format(self._qmp_sock) # Setup serial console - serial = '-chardev socket,host=127.0.0.1,port={0},id=gnc0,server,' \ - 'nowait -device isa-serial,chardev=gnc0'.format( - self._qemu_opt.get('serial_port')) + serial = ( + "-chardev socket,host=127.0.0.1,port={0},id=gnc0,server," + "nowait -device isa-serial,chardev=gnc0".format( + self._qemu_opt.get("serial_port") + ) + ) # Setup QGA via chardev (unix socket) and isa-serial channel - qga = '-chardev socket,path={0},server,nowait,id=qga0 ' \ - '-device isa-serial,chardev=qga0'.format(self._qga_sock) + qga = ( + "-chardev socket,path={0},server,nowait,id=qga0 " + "-device isa-serial,chardev=qga0".format(self._qga_sock) + ) # Graphic setup - graphic = '-monitor none -display none -vga none' + graphic = "-monitor none -display none -vga none" # PID file - pid = '-pidfile {}'.format(self._pid_file) + pid = "-pidfile {}".format(self._pid_file) # Run QEMU - cmd = '{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}'.format( - self._qemu_bin, self._qemu_opt.get('smp'), mem, ssh_fwd, - self._qemu_opt.get('options'), - drive, qmp, serial, qga, graphic, pid) + cmd = "{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}".format( + self._qemu_bin, + self._qemu_opt.get("smp"), + mem, + ssh_fwd, + self._qemu_opt.get("options"), + drive, + qmp, + serial, + qga, + graphic, + pid, + ) (ret_code, _, stderr) = self._ssh.exec_command_sudo(cmd, timeout=300) if int(ret_code) != 0: - logging.debug('QEMU start failed {0}'.format(stderr)) - raise RuntimeError('QEMU start failed on {0}'.format( - self._node['host'])) - logging.debug('QEMU running') + logging.debug("QEMU start failed {0}".format(stderr)) + raise RuntimeError("QEMU start failed on {0}".format(self._node["host"])) + logging.debug("QEMU running") # Wait until VM boot try: self._wait_until_vm_boot() @@ -579,40 +619,43 @@ class QemuUtils(object): def qemu_quit(self): """Quit the QEMU emulator.""" - out = self._qemu_qmp_exec('quit') - err = out.get('error') + out = self._qemu_qmp_exec("quit") + err = out.get("error") if err is not None: - raise RuntimeError('QEMU quit failed on {0}, error: {1}'.format( - self._node['host'], json.dumps(err))) + raise RuntimeError( + "QEMU quit failed on {0}, error: {1}".format( + self._node["host"], json.dumps(err) + ) + ) def qemu_system_powerdown(self): """Power down the system (if supported).""" - out = self._qemu_qmp_exec('system_powerdown') - err = out.get('error') + out = self._qemu_qmp_exec("system_powerdown") + err = out.get("error") if err is not None: raise RuntimeError( - 'QEMU system powerdown failed on {0}, ' - 'error: {1}'.format(self._node['host'], json.dumps(err)) + "QEMU system powerdown failed on {0}, " + "error: {1}".format(self._node["host"], json.dumps(err)) ) def qemu_system_reset(self): """Reset the system.""" - out = self._qemu_qmp_exec('system_reset') - err = out.get('error') + out = self._qemu_qmp_exec("system_reset") + err = out.get("error") if err is not None: raise RuntimeError( - 'QEMU system reset failed on {0}, ' - 'error: {1}'.format(self._node['host'], json.dumps(err))) + "QEMU system reset failed on {0}, " + "error: {1}".format(self._node["host"], json.dumps(err)) + ) def qemu_kill(self): """Kill qemu process.""" # Note: in QEMU start phase there are 3 QEMU processes because we # daemonize QEMU - self._ssh.exec_command_sudo('chmod +r {}'.format(self._pid_file)) - self._ssh.exec_command_sudo('kill -SIGKILL $(cat {})' - .format(self._pid_file)) + self._ssh.exec_command_sudo("chmod +r {}".format(self._pid_file)) + self._ssh.exec_command_sudo("kill -SIGKILL $(cat {})".format(self._pid_file)) # Delete PID file - cmd = 'rm -f {}'.format(self._pid_file) + cmd = "rm -f {}".format(self._pid_file) self._ssh.exec_command_sudo(cmd) def qemu_kill_all(self, node=None): @@ -623,16 +666,16 @@ class QemuUtils(object): """ if node: self.qemu_set_node(node) - self._ssh.exec_command_sudo('pkill -SIGKILL qemu') + self._ssh.exec_command_sudo("pkill -SIGKILL qemu") def qemu_clear_socks(self): """Remove all sockets created by QEMU.""" # If serial console port still open kill process - cmd = 'fuser -k {}/tcp'.format(self._qemu_opt.get('serial_port')) + cmd = "fuser -k {}/tcp".format(self._qemu_opt.get("serial_port")) self._ssh.exec_command_sudo(cmd) # Delete all created sockets for sock in self._socks: - cmd = 'rm -f {}'.format(sock) + cmd = "rm -f {}".format(sock) self._ssh.exec_command_sudo(cmd) def qemu_system_status(self): @@ -659,15 +702,16 @@ class QemuUtils(object): :return: VM status. :rtype: str """ - out = self._qemu_qmp_exec('query-status') - ret = out.get('return') + out = self._qemu_qmp_exec("query-status") + ret = out.get("return") if ret is not None: - return ret.get('status') + return ret.get("status") else: - err = out.get('error') + err = out.get("error") raise RuntimeError( - 'QEMU query-status failed on {0}, ' - 'error: {1}'.format(self._node['host'], json.dumps(err))) + "QEMU query-status failed on {0}, " + "error: {1}".format(self._node["host"], json.dumps(err)) + ) @staticmethod def build_qemu(node, force_install=False, apply_patch=False): @@ -682,17 +726,23 @@ class QemuUtils(object): :raises: RuntimeError if building QEMU failed. """ - directory = ' --directory={0}'.format(Constants.QEMU_INSTALL_DIR) - version = ' --version={0}'.format(Constants.QEMU_INSTALL_VERSION) - force = ' --force' if force_install else '' - patch = ' --patch' if apply_patch else '' - - (ret_code, stdout, stderr) = VPPUtil. \ - exec_command( - "sudo -E sh -c '{0}/{1}/qemu_build.sh{2}{3}{4}{5}'". - format(Constants.REMOTE_FW_DIR, Constants.RESOURCES_LIB_SH, - version, directory, force, patch), 1000) + directory = " --directory={0}".format(Constants.QEMU_INSTALL_DIR) + version = " --version={0}".format(Constants.QEMU_INSTALL_VERSION) + force = " --force" if force_install else "" + patch = " --patch" if apply_patch else "" + + (ret_code, stdout, stderr) = VPPUtil.exec_command( + "sudo -E sh -c '{0}/{1}/qemu_build.sh{2}{3}{4}{5}'".format( + Constants.REMOTE_FW_DIR, + Constants.RESOURCES_LIB_SH, + version, + directory, + force, + patch, + ), + 1000, + ) if int(ret_code) != 0: - logging.debug('QEMU build failed {0}'.format(stdout + stderr)) - raise RuntimeError('QEMU build failed on {0}'.format(node['host'])) + logging.debug("QEMU build failed {0}".format(stdout + stderr)) + raise RuntimeError("QEMU build failed on {0}".format(node["host"])) diff --git a/extras/vpp_config/vpplib/VPPUtil.py b/extras/vpp_config/vpplib/VPPUtil.py index 97747a31ca5..711f1032d96 100644 --- a/extras/vpp_config/vpplib/VPPUtil.py +++ b/extras/vpp_config/vpplib/VPPUtil.py @@ -23,15 +23,53 @@ from collections import Counter import distro -ubuntu_pkgs = {'release': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api', - 'vpp-dbg', 'vpp-dev', 'vpp-ext-deps'], - 'master': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api', - 'vpp-dbg', 'vpp-dev', 'vpp-ext-deps']} - -centos_pkgs = {'release': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua', - 'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0', 'vpp-ext-deps'], - 'master': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua', - 'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0', 'vpp-ext-deps']} +ubuntu_pkgs = { + "release": [ + "vpp", + "vpp-plugin-core", + "vpp-plugin-dpdk", + "vpp-api-python", + "python3-vpp-api", + "vpp-dbg", + "vpp-dev", + "vpp-ext-deps", + ], + "master": [ + "vpp", + "vpp-plugin-core", + "vpp-plugin-dpdk", + "vpp-api-python", + "python3-vpp-api", + "vpp-dbg", + "vpp-dev", + "vpp-ext-deps", + ], +} + +centos_pkgs = { + "release": [ + "vpp", + "vpp-selinux-policy", + "vpp-plugins", + "vpp-api-lua", + "vpp-api-python", + "vpp-debuginfo", + "vpp-devel", + "libvpp0", + "vpp-ext-deps", + ], + "master": [ + "vpp", + "vpp-selinux-policy", + "vpp-plugins", + "vpp-api-lua", + "vpp-api-python", + "vpp-debuginfo", + "vpp-devel", + "libvpp0", + "vpp-ext-deps", + ], +} class VPPUtil(object): @@ -50,19 +88,23 @@ class VPPUtil(object): """ logging.info(" Local Command: {}".format(cmd)) - out = '' - err = '' - prc = subprocess.Popen(cmd, shell=True, bufsize=1, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + out = "" + err = "" + prc = subprocess.Popen( + cmd, + shell=True, + bufsize=1, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) with prc.stdout: lines = prc.stdout.readlines() for line in lines: if type(line) != str: line = line.decode() - logging.info(" {}".format(line.strip('\n'))) + logging.info(" {}".format(line.strip("\n"))) out += line with prc.stderr: @@ -70,7 +112,7 @@ class VPPUtil(object): for line in lines: if type(line) != str: line = line.decode() - logging.warning(" {}".format(line.strip('\n'))) + logging.warning(" {}".format(line.strip("\n"))) err += line ret = prc.wait() @@ -86,17 +128,17 @@ class VPPUtil(object): """ # Does a copy of the file exist, if not create one - ofile = filename + '.orig' - (ret, stdout, stderr) = self.exec_command('ls {}'.format(ofile)) + ofile = filename + ".orig" + (ret, stdout, stderr) = self.exec_command("ls {}".format(ofile)) if ret != 0: logging.debug(stderr) - if stdout.strip('\n') != ofile: - cmd = 'sudo cp {} {}'.format(filename, ofile) + if stdout.strip("\n") != ofile: + cmd = "sudo cp {} {}".format(filename, ofile) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: logging.debug(stderr) - def _install_vpp_ubuntu(self, node, branch, ubuntu_version='xenial'): + def _install_vpp_ubuntu(self, node, branch, ubuntu_version="xenial"): """ Install the VPP packages @@ -109,49 +151,49 @@ class VPPUtil(object): """ # Modify the sources list - sfile = '/etc/apt/sources.list.d/99fd.io.list' + sfile = "/etc/apt/sources.list.d/99fd.io.list" # Backup the sources list self._autoconfig_backup_file(sfile) - reps = 'deb [trusted=yes] https://packagecloud.io/fdio/' - reps += '{}/ubuntu {} main\n'.format(branch, ubuntu_version) + reps = "deb [trusted=yes] https://packagecloud.io/fdio/" + reps += "{}/ubuntu {} main\n".format(branch, ubuntu_version) - with open(sfile, 'w') as sfd: + with open(sfile, "w") as sfd: sfd.write(reps) sfd.close() # Add the key - key = requests.get( - 'https://packagecloud.io/fdio/{}/gpgkey'.format(branch)) + key = requests.get("https://packagecloud.io/fdio/{}/gpgkey".format(branch)) cmd = 'echo "{}" | apt-key add -'.format(key.content.decode(key.encoding)) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + raise RuntimeError( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) # Install the package - cmd = 'apt-get -y update' + cmd = "apt-get -y update" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} apt-get update failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + raise RuntimeError( + "{} apt-get update failed on node {} {}".format( + cmd, node["host"], stderr + ) + ) # Get the package list - pkgstr = '' + pkgstr = "" for ps in ubuntu_pkgs[branch]: - pkgstr += ps + ' ' + pkgstr += ps + " " - cmd = 'apt-get -y install {}'.format(pkgstr) + cmd = "apt-get -y install {}".format(pkgstr) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'.format( - cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) def _install_vpp_centos(self, node, branch): """ @@ -164,95 +206,82 @@ class VPPUtil(object): """ # Be sure the correct system packages are installed - cmd = 'yum -y update' + cmd = "yum -y update" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr)) - cmd = 'yum -y install pygpgme yum-utils' + cmd = "yum -y install pygpgme yum-utils" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr)) # Modify the sources list - sfile = '/etc/yum.repos.d/fdio-release.repo' + sfile = "/etc/yum.repos.d/fdio-release.repo" # Backup the sources list self._autoconfig_backup_file(sfile) # Remove the current file - cmd = 'rm {}'.format(sfile) + cmd = "rm {}".format(sfile) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr)) # Get the file contents - reps = '\n'.join([ - '[fdio_{}]'.format(branch), - 'name=fdio_{}'.format(branch), - 'baseurl=https://packagecloud.io/fdio/{}/el/7/$basearch'.format( - branch), - 'repo_gpgcheck=1', - 'gpgcheck=0', - 'enabled=1', - 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch), - 'sslverify=1', - 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt', - 'metadata_expire=300\n', - '[fdio_{}-source]'.format(branch), - 'name=fdio_release-{}'.format(branch), - 'baseurl=https://packagecloud.io/fdio/{}/el/7/SRPMS'.format( - branch), - 'repo_gpgcheck=1', - 'gpgcheck=0', - 'enabled=1', - 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch), - 'sslverify =1', - 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt', - 'metadata_expire=300\n' - ]) - with open(sfile, 'w') as sfd: + reps = "\n".join( + [ + "[fdio_{}]".format(branch), + "name=fdio_{}".format(branch), + "baseurl=https://packagecloud.io/fdio/{}/el/7/$basearch".format(branch), + "repo_gpgcheck=1", + "gpgcheck=0", + "enabled=1", + "gpgkey=https://packagecloud.io/fdio/{}/gpgkey".format(branch), + "sslverify=1", + "sslcacert=/etc/pki/tls/certs/ca-bundle.crt", + "metadata_expire=300\n", + "[fdio_{}-source]".format(branch), + "name=fdio_release-{}".format(branch), + "baseurl=https://packagecloud.io/fdio/{}/el/7/SRPMS".format(branch), + "repo_gpgcheck=1", + "gpgcheck=0", + "enabled=1", + "gpgkey=https://packagecloud.io/fdio/{}/gpgkey".format(branch), + "sslverify =1", + "sslcacert=/etc/pki/tls/certs/ca-bundle.crt", + "metadata_expire=300\n", + ] + ) + with open(sfile, "w") as sfd: sfd.write(reps) sfd.close() # Update the fdio repo - cmd = 'yum clean all' + cmd = "yum clean all" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr)) - cmd = "yum -q makecache -y --disablerepo='*' " \ - "--enablerepo='fdio_{}'".format(branch) + cmd = "yum -q makecache -y --disablerepo='*' " "--enablerepo='fdio_{}'".format( + branch + ) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr)) # Get the package list - pkgstr = '' + pkgstr = "" for ps in centos_pkgs[branch]: - pkgstr += ps + ' ' + pkgstr += ps + " " - cmd = 'yum -y install {}'.format(pkgstr) + cmd = "yum -y install {}".format(pkgstr) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'.format( - cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) def install_vpp(self, node, branch): """ @@ -266,10 +295,10 @@ class VPPUtil(object): """ distro = self.get_linux_distro() logging.info(" {}".format(distro[0])) - if distro[0] == 'Ubuntu': + if distro[0] == "Ubuntu": logging.info("Install Ubuntu") self._install_vpp_ubuntu(node, branch, ubuntu_version=distro[2]) - elif distro[0] == 'CentOS Linux': + elif distro[0] == "CentOS Linux": logging.info("Install CentOS") self._install_vpp_centos(node, branch) else: @@ -286,17 +315,18 @@ class VPPUtil(object): """ # get the package list - pkgstr = '' + pkgstr = "" pkgs = self.get_installed_vpp_pkgs() for pkg in pkgs: - pkgname = pkg['name'] - pkgstr += pkgname + ' ' + pkgname = pkg["name"] + pkgstr += pkgname + " " - cmd = 'dpkg --purge {}'.format(pkgstr) + cmd = "dpkg --purge {}".format(pkgstr) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'.format( - cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) def _uninstall_vpp_centos(self, node): """ @@ -306,18 +336,19 @@ class VPPUtil(object): :type node: dict """ - pkgstr = '' + pkgstr = "" pkgs = self.get_installed_vpp_pkgs() for pkg in pkgs: - pkgname = pkg['name'] - pkgstr += pkgname + ' ' + pkgname = pkg["name"] + pkgstr += pkgname + " " logging.info("Uninstalling {}".format(pkgstr)) - cmd = 'yum -y remove {}'.format(pkgstr) + cmd = "yum -y remove {}".format(pkgstr) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'.format( - cmd, node['host'], stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) def uninstall_vpp(self, node): """ @@ -330,10 +361,10 @@ class VPPUtil(object): # First stop VPP self.stop(node) distro = self.get_linux_distro() - if distro[0] == 'Ubuntu': + if distro[0] == "Ubuntu": logging.info("Uninstall Ubuntu") self._uninstall_vpp_ubuntu(node) - elif distro[0] == 'CentOS Linux': + elif distro[0] == "CentOS Linux": logging.info("Uninstall CentOS") self._uninstall_vpp_centos(node) else: @@ -352,21 +383,20 @@ class VPPUtil(object): :type additional_cmds: tuple """ def_setting_tb_displayed = { - 'IPv6 FIB': 'ip6 fib', - 'IPv4 FIB': 'ip fib', - 'Interface IP': 'int addr', - 'Interfaces': 'int', - 'ARP': 'ip arp', - 'Errors': 'err' + "IPv6 FIB": "ip6 fib", + "IPv4 FIB": "ip fib", + "Interface IP": "int addr", + "Interfaces": "int", + "ARP": "ip arp", + "Errors": "err", } if additional_cmds: for cmd in additional_cmds: - def_setting_tb_displayed['Custom Setting: {}'.format(cmd)] \ - = cmd + def_setting_tb_displayed["Custom Setting: {}".format(cmd)] = cmd for _, value in def_setting_tb_displayed.items(): - self.exec_command('vppctl sh {}'.format(value)) + self.exec_command("vppctl sh {}".format(value)) @staticmethod def get_vms(node): @@ -397,32 +427,32 @@ class VPPUtil(object): :rtype: dictionary """ interfaces = {} - cmd = 'vppctl show int addr' + cmd = "vppctl show int addr" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: return interfaces - lines = stdout.split('\n') + lines = stdout.split("\n") if len(lines[0]) != 0: - if lines[0].split(' ')[0] == 'FileNotFoundError': + if lines[0].split(" ")[0] == "FileNotFoundError": return interfaces - name = '' + name = "" for line in lines: if len(line) == 0: continue # If the first character is not whitespace # create a new interface - if len(re.findall(r'\s', line[0])) == 0: + if len(re.findall(r"\s", line[0])) == 0: spl = line.split() name = spl[0] - if name == 'local0': + if name == "local0": continue interfaces[name] = {} - interfaces[name]['state'] = spl[1].lstrip('(').rstrip('):\r') + interfaces[name]["state"] = spl[1].lstrip("(").rstrip("):\r") else: - interfaces[name]['address'] = line.lstrip(' ').rstrip('\r') + interfaces[name]["address"] = line.lstrip(" ").rstrip("\r") return interfaces @@ -439,14 +469,14 @@ class VPPUtil(object): """ interfaces = {} - cmd = 'vppctl show hard' + cmd = "vppctl show hard" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: return interfaces - lines = stdout.split('\n') + lines = stdout.split("\n") if len(lines[0]) != 0: - if lines[0].split(' ')[0] == 'FileNotFoundError': + if lines[0].split(" ")[0] == "FileNotFoundError": return interfaces for line in lines: @@ -455,46 +485,46 @@ class VPPUtil(object): # If the first character is not whitespace # create a new interface - if len(re.findall(r'\s', line[0])) == 0: + if len(re.findall(r"\s", line[0])) == 0: spl = line.split() name = spl[0] interfaces[name] = {} - interfaces[name]['index'] = spl[1] - interfaces[name]['state'] = spl[2] + interfaces[name]["index"] = spl[1] + interfaces[name]["state"] = spl[2] # Ethernet address - rfall = re.findall(r'Ethernet address', line) + rfall = re.findall(r"Ethernet address", line) if rfall: spl = line.split() - interfaces[name]['mac'] = spl[2] + interfaces[name]["mac"] = spl[2] # Carrier - rfall = re.findall(r'carrier', line) + rfall = re.findall(r"carrier", line) if rfall: - spl = line.split('carrier ') - interfaces[name]['carrier'] = spl[1] + spl = line.split("carrier ") + interfaces[name]["carrier"] = spl[1] # Socket - spl = '' - rfall = re.findall(r'numa \d+', line) + spl = "" + rfall = re.findall(r"numa \d+", line) if rfall: spl = rfall[0].split() - interfaces[name]['numa'] = rfall[0].split()[1] + interfaces[name]["numa"] = rfall[0].split()[1] # Queues and Descriptors - rfall = re.findall(r'rx\: queues \d+', line) + rfall = re.findall(r"rx\: queues \d+", line) if rfall: - interfaces[name]['rx queues'] = rfall[0].split()[2] - rdesc = re.findall(r'desc \d+', line) + interfaces[name]["rx queues"] = rfall[0].split()[2] + rdesc = re.findall(r"desc \d+", line) if rdesc: - interfaces[name]['rx descs'] = rdesc[0].split()[1] + interfaces[name]["rx descs"] = rdesc[0].split()[1] - rfall = re.findall(r'tx\: queues \d+', line) + rfall = re.findall(r"tx\: queues \d+", line) if rfall: - interfaces[name]['tx queues'] = rfall[0].split()[2] - rdesc = re.findall(r'desc \d+', line) + interfaces[name]["tx queues"] = rfall[0].split()[2] + rdesc = re.findall(r"desc \d+", line) if rdesc: - interfaces[name]['tx descs'] = rdesc[0].split()[1] + interfaces[name]["tx descs"] = rdesc[0].split()[1] return interfaces @@ -508,17 +538,17 @@ class VPPUtil(object): """ pkgs = [] - cmd = 'dpkg -l | grep vpp' + cmd = "dpkg -l | grep vpp" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: return pkgs - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: items = line.split() if len(items) < 2: continue - pkg = {'name': items[1], 'version': items[2]} + pkg = {"name": items[1], "version": items[2]} pkgs.append(pkg) return pkgs @@ -533,21 +563,21 @@ class VPPUtil(object): """ pkgs = [] - cmd = 'rpm -qa | grep vpp' + cmd = "rpm -qa | grep vpp" (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: return pkgs - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: if len(line) == 0: continue items = line.split() if len(items) < 2: - pkg = {'name': items[0]} + pkg = {"name": items[0]} else: - pkg = {'name': items[1], 'version': items[2]} + pkg = {"name": items[1], "version": items[2]} pkgs.append(pkg) @@ -563,9 +593,9 @@ class VPPUtil(object): """ distro = self.get_linux_distro() - if distro[0] == 'Ubuntu': + if distro[0] == "Ubuntu": pkgs = self._get_installed_vpp_pkgs_ubuntu() - elif distro[0] == 'CentOS Linux': + elif distro[0] == "CentOS Linux": pkgs = self._get_installed_vpp_pkgs_centos() else: pkgs = self._get_installed_vpp_pkgs_centos() @@ -594,7 +624,7 @@ class VPPUtil(object): numa_list = [] for if_key in iface_keys: try: - numa_list.append(node['interfaces'][if_key].get('numa_node')) + numa_list.append(node["interfaces"][if_key].get("numa_node")) except KeyError: pass @@ -617,12 +647,12 @@ class VPPUtil(object): :type node: dict """ - cmd = 'service vpp restart' + cmd = "service vpp restart" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) @staticmethod def start(node): @@ -634,12 +664,12 @@ class VPPUtil(object): :type node: dict """ - cmd = 'service vpp start' + cmd = "service vpp start" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) @staticmethod def stop(node): @@ -651,12 +681,12 @@ class VPPUtil(object): :type node: dict """ - cmd = 'service vpp stop' + cmd = "service vpp stop" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - logging.debug('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + logging.debug( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) # noinspection RegExpRedundantEscape @staticmethod @@ -676,11 +706,11 @@ class VPPUtil(object): if len(pkgs) == 0: return "Not Installed", errors - cmd = 'service vpp status' + cmd = "service vpp status" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) # Get the active status - state = re.findall(r'Active:[\w (\)]+', stdout)[0].split(' ') + state = re.findall(r"Active:[\w (\)]+", stdout)[0].split(" ") if len(state) > 2: statestr = "{} {}".format(state[1], state[2]) else: @@ -707,13 +737,10 @@ class VPPUtil(object): """ dist = distro.linux_distribution() - if dist[0] == 'Ubuntu' or \ - dist[0] == 'CentOS Linux' or \ - dist[:7] == 'Red Hat': + if dist[0] == "Ubuntu" or dist[0] == "CentOS Linux" or dist[:7] == "Red Hat": return dist else: - raise RuntimeError( - 'Linux Distribution {} is not supported'.format(dist[0])) + raise RuntimeError("Linux Distribution {} is not supported".format(dist[0])) @staticmethod def version(): @@ -726,21 +753,21 @@ class VPPUtil(object): """ version = {} - cmd = 'vppctl show version verbose' + cmd = "vppctl show version verbose" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: return version - lines = stdout.split('\n') + lines = stdout.split("\n") if len(lines[0]) != 0: - if lines[0].split(' ')[0] == 'FileNotFoundError': + if lines[0].split(" ")[0] == "FileNotFoundError": return version for line in lines: if len(line) == 0: continue - dct = line.split(':') - version[dct[0]] = dct[1].lstrip(' ') + dct = line.split(":") + version[dct[0]] = dct[1].lstrip(" ") return version @@ -755,38 +782,40 @@ class VPPUtil(object): """ ifaces = [] - cmd = 'vppctl show bridge' + cmd = "vppctl show bridge" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) - lines = stdout.split('\r\n') + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) + lines = stdout.split("\r\n") bridges = [] for line in lines: - if line == 'no bridge-domains in use': + if line == "no bridge-domains in use": print(line) return ifaces if len(line) == 0: continue - lspl = line.lstrip(' ').split() - if lspl[0] != 'BD-ID': + lspl = line.lstrip(" ").split() + if lspl[0] != "BD-ID": bridges.append(lspl[0]) for bridge in bridges: - cmd = 'vppctl show bridge {} detail'.format(bridge) + cmd = "vppctl show bridge {} detail".format(bridge) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format( + cmd, node["host"], stdout, stderr + ) + ) - lines = stdout.split('\r\n') + lines = stdout.split("\r\n") for line in lines: - iface = re.findall(r'[a-zA-z]+\d+/\d+/\d+', line) + iface = re.findall(r"[a-zA-z]+\d+/\d+/\d+", line) if len(iface): - ifcidx = {'name': iface[0], 'index': line.split()[1]} + ifcidx = {"name": iface[0], "index": line.split()[1]} ifaces.append(ifcidx) print(stdout) diff --git a/extras/vpp_config/vpplib/VppGrubUtil.py b/extras/vpp_config/vpplib/VppGrubUtil.py index f17efd8a868..976b20019c4 100644 --- a/extras/vpp_config/vpplib/VppGrubUtil.py +++ b/extras/vpp_config/vpplib/VppGrubUtil.py @@ -17,11 +17,11 @@ import re from vpplib.VPPUtil import VPPUtil -__all__ = ['VppGrubUtil'] +__all__ = ["VppGrubUtil"] class VppGrubUtil(object): - """ VPP Grub Utilities.""" + """VPP Grub Utilities.""" def _get_current_cmdline(self): """ @@ -32,14 +32,14 @@ class VppGrubUtil(object): """ # Get the memory information using /proc/meminfo - cmd = 'sudo cat /proc/cmdline' + cmd = "sudo cat /proc/cmdline" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} on node {} {} {}'. - format(cmd, self._node['host'], - stdout, stderr)) + raise RuntimeError( + "{} on node {} {} {}".format(cmd, self._node["host"], stdout, stderr) + ) - self._current_cmdline = stdout.strip('\n') + self._current_cmdline = stdout.strip("\n") def _get_default_cmdline(self): """ @@ -50,21 +50,24 @@ class VppGrubUtil(object): """ # Get the default grub cmdline - rootdir = self._node['rootdir'] - gfile = self._node['cpu']['grub_config_file'] - grubcmdline = self._node['cpu']['grubcmdline'] - cmd = 'cat {}'.format(rootdir + gfile) + rootdir = self._node["rootdir"] + gfile = self._node["cpu"]["grub_config_file"] + grubcmdline = self._node["cpu"]["grubcmdline"] + cmd = "cat {}".format(rootdir + gfile) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} Executing failed on node {} {}'. - format(cmd, self._node['host'], stderr)) + raise RuntimeError( + "{} Executing failed on node {} {}".format( + cmd, self._node["host"], stderr + ) + ) # Get the Default Linux command line, ignoring commented lines - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: - if line == '' or line[0] == '#': + if line == "" or line[0] == "#": continue - ldefault = re.findall(r'{}=.+'.format(grubcmdline), line) + ldefault = re.findall(r"{}=.+".format(grubcmdline), line) if ldefault: self._default_cmdline = ldefault[0] break @@ -96,9 +99,9 @@ class VppGrubUtil(object): :returns: The command line :rtype: string """ - grubcmdline = self._node['cpu']['grubcmdline'] + grubcmdline = self._node["cpu"]["grubcmdline"] cmdline = self._default_cmdline - value = cmdline.split('{}='.format(grubcmdline))[1] + value = cmdline.split("{}=".format(grubcmdline))[1] value = value.rstrip('"').lstrip('"') # jadfix intel_pstate=disable sometimes cause networks to @@ -111,43 +114,43 @@ class VppGrubUtil(object): # value = '{} intel_pstate=disable'.format(value) # Replace isolcpus with ours - isolcpus = re.findall(r'isolcpus=[\w+\-,]+', value) + isolcpus = re.findall(r"isolcpus=[\w+\-,]+", value) if not isolcpus: - if isolated_cpus != '': + if isolated_cpus != "": value = "{} isolcpus={}".format(value, isolated_cpus) else: - if isolated_cpus != '': - value = re.sub(r'isolcpus=[\w+\-,]+', - 'isolcpus={}'.format(isolated_cpus), - value) + if isolated_cpus != "": + value = re.sub( + r"isolcpus=[\w+\-,]+", "isolcpus={}".format(isolated_cpus), value + ) else: - value = re.sub(r'isolcpus=[\w+\-,]+', '', value) + value = re.sub(r"isolcpus=[\w+\-,]+", "", value) - nohz = re.findall(r'nohz_full=[\w+\-,]+', value) + nohz = re.findall(r"nohz_full=[\w+\-,]+", value) if not nohz: - if isolated_cpus != '': + if isolated_cpus != "": value = "{} nohz_full={}".format(value, isolated_cpus) else: - if isolated_cpus != '': - value = re.sub(r'nohz_full=[\w+\-,]+', - 'nohz_full={}'.format(isolated_cpus), - value) + if isolated_cpus != "": + value = re.sub( + r"nohz_full=[\w+\-,]+", "nohz_full={}".format(isolated_cpus), value + ) else: - value = re.sub(r'nohz_full=[\w+\-,]+', '', value) + value = re.sub(r"nohz_full=[\w+\-,]+", "", value) - rcu = re.findall(r'rcu_nocbs=[\w+\-,]+', value) + rcu = re.findall(r"rcu_nocbs=[\w+\-,]+", value) if not rcu: - if isolated_cpus != '': + if isolated_cpus != "": value = "{} rcu_nocbs={}".format(value, isolated_cpus) else: - if isolated_cpus != '': - value = re.sub(r'rcu_nocbs=[\w+\-,]+', - 'rcu_nocbs={}'.format(isolated_cpus), - value) + if isolated_cpus != "": + value = re.sub( + r"rcu_nocbs=[\w+\-,]+", "rcu_nocbs={}".format(isolated_cpus), value + ) else: - value = re.sub(r'rcu_nocbs=[\w+\-,]+', '', value) + value = re.sub(r"rcu_nocbs=[\w+\-,]+", "", value) - value = value.lstrip(' ').rstrip(' ') + value = value.lstrip(" ").rstrip(" ") cmdline = '{}="{}"'.format(grubcmdline, value) return cmdline @@ -167,69 +170,68 @@ class VppGrubUtil(object): if len(vpp_cmdline): # Update grub # Save the original file - rootdir = node['rootdir'] - grubcmdline = node['cpu']['grubcmdline'] - ofilename = rootdir + node['cpu']['grub_config_file'] + '.orig' - filename = rootdir + node['cpu']['grub_config_file'] + rootdir = node["rootdir"] + grubcmdline = node["cpu"]["grubcmdline"] + ofilename = rootdir + node["cpu"]["grub_config_file"] + ".orig" + filename = rootdir + node["cpu"]["grub_config_file"] # Write the output file # Does a copy of the original file exist, if not create one - (ret, stdout, stderr) = VPPUtil.exec_command( - 'ls {}'.format(ofilename)) + (ret, stdout, stderr) = VPPUtil.exec_command("ls {}".format(ofilename)) if ret != 0: - if stdout.strip('\n') != ofilename: - cmd = 'sudo cp {} {}'.format(filename, ofilename) + if stdout.strip("\n") != ofilename: + cmd = "sudo cp {} {}".format(filename, ofilename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'. - format(cmd, self._node['host'], - stderr)) + raise RuntimeError( + "{} failed on node {} {}".format( + cmd, self._node["host"], stderr + ) + ) # Get the contents of the current grub config file - cmd = 'cat {}'.format(filename) + cmd = "cat {}".format(filename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( - cmd, - self._node['host'], - stderr)) + raise RuntimeError( + "{} failed on node {} {}".format(cmd, self._node["host"], stderr) + ) # Write the new contents # Get the Default Linux command line, ignoring commented lines content = "" - lines = stdout.split('\n') + lines = stdout.split("\n") for line in lines: - if line == '': - content += line + '\n' + if line == "": + content += line + "\n" continue - if line[0] == '#': - content += line + '\n' + if line[0] == "#": + content += line + "\n" continue - ldefault = re.findall(r'{}=.+'.format(grubcmdline), line) + ldefault = re.findall(r"{}=.+".format(grubcmdline), line) if ldefault: - content += vpp_cmdline + '\n' + content += vpp_cmdline + "\n" else: - content += line + '\n' + content += line + "\n" content = content.replace(r"`", r"\`") - content = content.rstrip('\n') + content = content.rstrip("\n") cmd = "sudo cat > {0} << EOF\n{1}\n".format(filename, content) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( - cmd, - self._node['host'], - stderr)) + raise RuntimeError( + "{} failed on node {} {}".format(cmd, self._node["host"], stderr) + ) return vpp_cmdline def __init__(self, node): distro = VPPUtil.get_linux_distro() - if distro[0] == 'Ubuntu': - node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX_DEFAULT' + if distro[0] == "Ubuntu": + node["cpu"]["grubcmdline"] = "GRUB_CMDLINE_LINUX_DEFAULT" else: - node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX' + node["cpu"]["grubcmdline"] = "GRUB_CMDLINE_LINUX" self._node = node self._current_cmdline = "" diff --git a/extras/vpp_config/vpplib/VppHugePageUtil.py b/extras/vpp_config/vpplib/VppHugePageUtil.py index 3a632828883..48991090f04 100644 --- a/extras/vpp_config/vpplib/VppHugePageUtil.py +++ b/extras/vpp_config/vpplib/VppHugePageUtil.py @@ -33,6 +33,7 @@ class VppHugePageUtil(object): """ Huge Page Utilities """ + def hugepages_dryrun_apply(self): """ Apply the huge page configuration @@ -40,23 +41,23 @@ class VppHugePageUtil(object): """ node = self._node - hugepages = node['hugepages'] + hugepages = node["hugepages"] vpp_hugepage_config = VPP_HUGEPAGE_CONFIG.format( - nr_hugepages=hugepages['total'], - max_map_count=hugepages['max_map_count'], - shmmax=hugepages['shmax']) + nr_hugepages=hugepages["total"], + max_map_count=hugepages["max_map_count"], + shmmax=hugepages["shmax"], + ) - rootdir = node['rootdir'] - filename = rootdir + node['hugepages']['hugepage_config_file'] + rootdir = node["rootdir"] + filename = rootdir + node["hugepages"]["hugepage_config_file"] - cmd = 'echo "{0}" | sudo tee {1}'.\ - format(vpp_hugepage_config, filename) + cmd = 'echo "{0}" | sudo tee {1}'.format(vpp_hugepage_config, filename) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) def get_actual_huge_pages(self): """ @@ -68,25 +69,26 @@ class VppHugePageUtil(object): """ # Get the memory information using /proc/meminfo - cmd = 'sudo cat /proc/meminfo' + cmd = "sudo cat /proc/meminfo" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: raise RuntimeError( - '{} failed on node {} {} {}'.format( - cmd, self._node['host'], - stdout, stderr)) - - total = re.findall(r'HugePages_Total:\s+\w+', stdout) - free = re.findall(r'HugePages_Free:\s+\w+', stdout) - size = re.findall(r'Hugepagesize:\s+\w+\s+\w+', stdout) - memtotal = re.findall(r'MemTotal:\s+\w+\s+\w+', stdout) - memfree = re.findall(r'MemFree:\s+\w+\s+\w+', stdout) - - total = total[0].split(':')[1].lstrip() - free = free[0].split(':')[1].lstrip() - size = size[0].split(':')[1].lstrip() - memtotal = memtotal[0].split(':')[1].lstrip() - memfree = memfree[0].split(':')[1].lstrip() + "{} failed on node {} {} {}".format( + cmd, self._node["host"], stdout, stderr + ) + ) + + total = re.findall(r"HugePages_Total:\s+\w+", stdout) + free = re.findall(r"HugePages_Free:\s+\w+", stdout) + size = re.findall(r"Hugepagesize:\s+\w+\s+\w+", stdout) + memtotal = re.findall(r"MemTotal:\s+\w+\s+\w+", stdout) + memfree = re.findall(r"MemFree:\s+\w+\s+\w+", stdout) + + total = total[0].split(":")[1].lstrip() + free = free[0].split(":")[1].lstrip() + size = size[0].split(":")[1].lstrip() + memtotal = memtotal[0].split(":")[1].lstrip() + memfree = memfree[0].split(":")[1].lstrip() return total, free, size, memtotal, memfree def show_huge_pages(self): @@ -96,17 +98,13 @@ class VppHugePageUtil(object): """ node = self._node - hugepages = node['hugepages'] - print (" {:30}: {}".format("Total System Memory", - hugepages['memtotal'])) - print (" {:30}: {}".format("Total Free Memory", - hugepages['memfree'])) - print (" {:30}: {}".format("Actual Huge Page Total", - hugepages['actual_total'])) - print (" {:30}: {}".format("Configured Huge Page Total", - hugepages['total'])) - print (" {:30}: {}".format("Huge Pages Free", hugepages['free'])) - print (" {:30}: {}".format("Huge Page Size", hugepages['size'])) + hugepages = node["hugepages"] + print(" {:30}: {}".format("Total System Memory", hugepages["memtotal"])) + print(" {:30}: {}".format("Total Free Memory", hugepages["memfree"])) + print(" {:30}: {}".format("Actual Huge Page Total", hugepages["actual_total"])) + print(" {:30}: {}".format("Configured Huge Page Total", hugepages["total"])) + print(" {:30}: {}".format("Huge Pages Free", hugepages["free"])) + print(" {:30}: {}".format("Huge Page Size", hugepages["size"])) def get_huge_page_config(self): """ @@ -115,7 +113,7 @@ class VppHugePageUtil(object): :returns: The map max count and shmmax """ - total = self._node['hugepages']['total'] + total = self._node["hugepages"]["total"] max_map_count = int(total) * 2 + 1024 shmmax = int(total) * 2 * 1024 * 1024 return max_map_count, shmmax diff --git a/extras/vpp_config/vpplib/VppPCIUtil.py b/extras/vpp_config/vpplib/VppPCIUtil.py index ceda46f97b9..032a262c21c 100644 --- a/extras/vpp_config/vpplib/VppPCIUtil.py +++ b/extras/vpp_config/vpplib/VppPCIUtil.py @@ -23,7 +23,7 @@ from vpplib.VPPUtil import VPPUtil DPDK_SCRIPT = "/vpp/vpp-config/scripts/dpdk-devbind.py" # PCI Device id regular expresssion -PCI_DEV_ID_REGEX = '[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+.[0-9A-Fa-f]+' +PCI_DEV_ID_REGEX = "[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+.[0-9A-Fa-f]+" class VppPCIUtil(object): @@ -45,51 +45,47 @@ class VppPCIUtil(object): devices = {} ids = re.findall(PCI_DEV_ID_REGEX, device_string) - descriptions = re.findall(r'\'([\s\S]*?)\'', device_string) - unused = re.findall(r'unused=\w+|unused=', device_string) + descriptions = re.findall(r"\'([\s\S]*?)\'", device_string) + unused = re.findall(r"unused=\w+|unused=", device_string) for i, j in enumerate(ids): - device = {'description': descriptions[i]} + device = {"description": descriptions[i]} if unused: - device['unused'] = unused[i].split('=')[1].split(',') + device["unused"] = unused[i].split("=")[1].split(",") - cmd = 'ls /sys/bus/pci/devices/{}/driver/module/drivers'. \ - format(ids[i]) + cmd = "ls /sys/bus/pci/devices/{}/driver/module/drivers".format(ids[i]) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret == 0: - device['driver'] = stdout.split(':')[1].rstrip('\n') + device["driver"] = stdout.split(":")[1].rstrip("\n") - cmd = 'cat /sys/bus/pci/devices/{}/numa_node'.format(ids[i]) + cmd = "cat /sys/bus/pci/devices/{}/numa_node".format(ids[i]) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed {} {}'. - format(cmd, stderr, stdout)) - numa_node = stdout.rstrip('\n') - if numa_node == '-1': - device['numa_node'] = '0' + raise RuntimeError("{} failed {} {}".format(cmd, stderr, stdout)) + numa_node = stdout.rstrip("\n") + if numa_node == "-1": + device["numa_node"] = "0" else: - device['numa_node'] = numa_node + device["numa_node"] = numa_node interfaces = [] - device['interfaces'] = [] - cmd = 'ls /sys/bus/pci/devices/{}/net'.format(ids[i]) + device["interfaces"] = [] + cmd = "ls /sys/bus/pci/devices/{}/net".format(ids[i]) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret == 0: - interfaces = stdout.rstrip('\n').split() - device['interfaces'] = interfaces + interfaces = stdout.rstrip("\n").split() + device["interfaces"] = interfaces l2_addrs = [] for intf in interfaces: - cmd = 'cat /sys/bus/pci/devices/{}/net/{}/address'.format( - ids[i], intf) + cmd = "cat /sys/bus/pci/devices/{}/net/{}/address".format(ids[i], intf) (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed {} {}'. - format(cmd, stderr, stdout)) + raise RuntimeError("{} failed {} {}".format(cmd, stderr, stdout)) - l2_addrs.append(stdout.rstrip('\n')) + l2_addrs.append(stdout.rstrip("\n")) - device['l2addr'] = l2_addrs + device["l2addr"] = l2_addrs devices[ids[i]] = device @@ -112,66 +108,62 @@ class VppPCIUtil(object): """ node = self._node - rootdir = node['rootdir'] + rootdir = node["rootdir"] dpdk_script = rootdir + DPDK_SCRIPT - cmd = dpdk_script + ' --status' + cmd = dpdk_script + " --status" (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + raise RuntimeError( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) # Get the network devices using the DPDK # First get everything after using DPDK - stda = stdout.split('Network devices using DPDK-compatible driver')[1] + stda = stdout.split("Network devices using DPDK-compatible driver")[1] # Then get everything before using kernel driver - using_dpdk = stda.split('Network devices using kernel driver')[0] + using_dpdk = stda.split("Network devices using kernel driver")[0] self._dpdk_devices = self._create_device_list(using_dpdk) # Get the network devices using the kernel - stda = stdout.split('Network devices using kernel driver')[1] - using_kernel = stda.split('Other network devices')[0] + stda = stdout.split("Network devices using kernel driver")[1] + using_kernel = stda.split("Other network devices")[0] self._kernel_devices = self._create_device_list(using_kernel) # Get the other network devices - stda = stdout.split('Other network devices')[1] - other = stda.split('Crypto devices using DPDK-compatible driver')[0] + stda = stdout.split("Other network devices")[1] + other = stda.split("Crypto devices using DPDK-compatible driver")[0] self._other_devices = self._create_device_list(other) # Get the crypto devices using the DPDK - stda = stdout.split('Crypto devices using DPDK-compatible driver')[1] - crypto_using_dpdk = stda.split('Crypto devices using kernel driver')[0] - self._crypto_dpdk_devices = self._create_device_list( - crypto_using_dpdk) + stda = stdout.split("Crypto devices using DPDK-compatible driver")[1] + crypto_using_dpdk = stda.split("Crypto devices using kernel driver")[0] + self._crypto_dpdk_devices = self._create_device_list(crypto_using_dpdk) # Get the network devices using the kernel - stda = stdout.split('Crypto devices using kernel driver')[1] - crypto_using_kernel = stda.split('Other crypto devices')[0] - self._crypto_kernel_devices = self._create_device_list( - crypto_using_kernel) + stda = stdout.split("Crypto devices using kernel driver")[1] + crypto_using_kernel = stda.split("Other crypto devices")[0] + self._crypto_kernel_devices = self._create_device_list(crypto_using_kernel) # Get the other network devices - crypto_other = stdout.split('Other crypto devices')[1] + crypto_other = stdout.split("Other crypto devices")[1] self._crypto_other_devices = self._create_device_list(crypto_other) # Get the devices used by the kernel for devk in self._kernel_devices.items(): dvid = devk[0] device = devk[1] - for i in device['interfaces']: + for i in device["interfaces"]: cmd = "ip addr show " + i (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) - lstate = re.findall(r'state \w+', stdout)[0].split(' ')[1] + raise RuntimeError( + "{} failed on node {} {}".format(cmd, node["host"], stderr) + ) + lstate = re.findall(r"state \w+", stdout)[0].split(" ")[1] # Take care of the links that are UP - if lstate == 'UP': - device['linkup'] = True + if lstate == "UP": + device["linkup"] = True self._link_up_devices[dvid] = device for devl in self._link_up_devices.items(): @@ -234,18 +226,18 @@ class VppPCIUtil(object): """ - name = 'port' + str(len(interfaces)) + name = "port" + str(len(interfaces)) interfaces[name] = {} - interfaces[name]['pci_address'] = device_id - interfaces[name]['numa_node'] = device['numa_node'] - if 'l2addr' in device: - l2_addrs = device['l2addr'] + interfaces[name]["pci_address"] = device_id + interfaces[name]["numa_node"] = device["numa_node"] + if "l2addr" in device: + l2_addrs = device["l2addr"] for i, j in enumerate(l2_addrs): if i > 0: - mname = 'mac_address' + str(i + 1) + mname = "mac_address" + str(i + 1) interfaces[name][mname] = l2_addrs[i] else: - interfaces[name]['mac_address'] = l2_addrs[i] + interfaces[name]["mac_address"] = l2_addrs[i] @staticmethod def show_vpp_devices(devices, show_interfaces=True, show_header=True): @@ -261,34 +253,33 @@ class VppPCIUtil(object): """ if show_interfaces: - header = "{:15} {:25} {:50}".format("PCI ID", - "Kernel Interface(s)", - "Description") + header = "{:15} {:25} {:50}".format( + "PCI ID", "Kernel Interface(s)", "Description" + ) else: - header = "{:15} {:50}".format("PCI ID", - "Description") - dashseparator = ("-" * (len(header) - 2)) + header = "{:15} {:50}".format("PCI ID", "Description") + dashseparator = "-" * (len(header) - 2) if show_header is True: - print (header) - print (dashseparator) + print(header) + print(dashseparator) for dit in devices.items(): dvid = dit[0] device = dit[1] if show_interfaces: - interfaces = device['interfaces'] - interface = '' + interfaces = device["interfaces"] + interface = "" for i, j in enumerate(interfaces): if i > 0: - interface += ',' + interfaces[i] + interface += "," + interfaces[i] else: interface = interfaces[i] - print ("{:15} {:25} {:50}".format( - dvid, interface, device['description'])) + print( + "{:15} {:25} {:50}".format(dvid, interface, device["description"]) + ) else: - print ("{:15} {:50}".format( - dvid, device['description'])) + print("{:15} {:50}".format(dvid, device["description"])) @staticmethod def unbind_vpp_device(node, device_id): @@ -301,14 +292,14 @@ class VppPCIUtil(object): :type device_id: string """ - rootdir = node['rootdir'] + rootdir = node["rootdir"] dpdk_script = rootdir + DPDK_SCRIPT - cmd = dpdk_script + ' -u ' + ' ' + device_id + cmd = dpdk_script + " -u " + " " + device_id (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'.format( - cmd, node['host'], - stdout, stderr)) + raise RuntimeError( + "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr) + ) @staticmethod def bind_vpp_device(node, driver, device_id): @@ -324,14 +315,14 @@ class VppPCIUtil(object): :returns ret: Command return code """ - rootdir = node['rootdir'] + rootdir = node["rootdir"] dpdk_script = rootdir + DPDK_SCRIPT - cmd = dpdk_script + ' -b ' + driver + ' ' + device_id + cmd = dpdk_script + " -b " + driver + " " + device_id (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - logging.error('{} failed on node {}'.format( - cmd, node['host'], stdout, stderr)) - logging.error('{} {}'.format( - stdout, stderr)) + logging.error( + "{} failed on node {}".format(cmd, node["host"], stdout, stderr) + ) + logging.error("{} {}".format(stdout, stderr)) return ret diff --git a/extras/vpp_config/vpplib/constants.py b/extras/vpp_config/vpplib/constants.py index 051a21cf023..63428b0c4d4 100644 --- a/extras/vpp_config/vpplib/constants.py +++ b/extras/vpp_config/vpplib/constants.py @@ -18,31 +18,31 @@ class Constants(object): """Constants used in CSIT.""" # OpenVPP testing directory location at topology nodes - REMOTE_FW_DIR = '/tmp/openvpp-testing' + REMOTE_FW_DIR = "/tmp/openvpp-testing" # shell scripts location - RESOURCES_LIB_SH = 'resources/libraries/bash' + RESOURCES_LIB_SH = "resources/libraries/bash" # vat templates location - RESOURCES_TPL_VAT = 'resources/templates/vat' + RESOURCES_TPL_VAT = "resources/templates/vat" # OpenVPP VAT binary name - VAT_BIN_NAME = 'vpp_api_test' + VAT_BIN_NAME = "vpp_api_test" # QEMU version to install - QEMU_INSTALL_VERSION = 'qemu-2.5.0' + QEMU_INSTALL_VERSION = "qemu-2.5.0" # QEMU install directory - QEMU_INSTALL_DIR = '/opt/qemu-2.5.0' + QEMU_INSTALL_DIR = "/opt/qemu-2.5.0" # Honeycomb directory location at topology nodes: - REMOTE_HC_DIR = '/opt/honeycomb' + REMOTE_HC_DIR = "/opt/honeycomb" # Honeycomb persistence files location - REMOTE_HC_PERSIST = '/var/lib/honeycomb/persist' + REMOTE_HC_PERSIST = "/var/lib/honeycomb/persist" # Honeycomb templates location - RESOURCES_TPL_HC = 'resources/templates/honeycomb' + RESOURCES_TPL_HC = "resources/templates/honeycomb" # ODL Client Restconf listener port ODL_PORT = 8181 |