diff options
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 |