X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Fvpp_ip_route.py;h=d871f7a0b114583c18c7e0712224741e6bf11e1d;hb=59f71132edffcfa1b94c400736575bd55bdbd7d7;hp=864a39aeb3479ab81d5690cc32fe4eca1f7ad73e;hpb=c2ac2357fb0ff598ca1cb650a5766a552e017833;p=vpp.git diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py index 864a39aeb34..d871f7a0b11 100644 --- a/test/vpp_ip_route.py +++ b/test/vpp_ip_route.py @@ -6,9 +6,9 @@ from vpp_object import VppObject from socket import inet_pton, inet_ntop, AF_INET, AF_INET6 -from vpp_ip import DpoProto, VppIpPrefix, INVALID_INDEX, VppIpAddressUnion, \ +from vpp_ip import DpoProto, INVALID_INDEX, VppIpAddressUnion, \ VppIpMPrefix -from ipaddress import ip_address, IPv4Network, IPv6Network +from ipaddress import ip_network, ip_address, IPv4Network, IPv6Network # from vnet/vnet/mpls/mpls_types.h MPLS_IETF_MAX_LABEL = 0xfffff @@ -64,6 +64,7 @@ class FibPathFlags: FIB_PATH_FLAG_NONE = 0 FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED = 1 FIB_PATH_FLAG_RESOLVE_VIA_HOST = 2 + FIB_PATH_FLAG_POP_PW_CW = 4 class MplsLspMode: @@ -71,6 +72,13 @@ class MplsLspMode: UNIFORM = 1 +def mk_network(addr, len): + if ip_address(text_type(addr)).version == 4: + return IPv4Network("%s/%d" % (addr, len), strict=False) + else: + return IPv6Network("%s/%d" % (addr, len), strict=False) + + def ip_to_dpo_proto(addr): if addr.version == 6: return DpoProto.DPO_PROTO_IP6 @@ -79,25 +87,49 @@ def ip_to_dpo_proto(addr): def address_proto(ip_addr): - if ip_addr.ip_addr.version is 4: + if ip_addr.ip_addr.version == 4: return FibPathProto.FIB_PATH_NH_PROTO_IP4 else: return FibPathProto.FIB_PATH_NH_PROTO_IP6 -def find_route(test, addr, len, table_id=0): - ip_addr = ip_address(text_type(addr)) +def find_route(test, addr, len, table_id=0, sw_if_index=None): + prefix = mk_network(addr, len) - if 4 is ip_addr.version: + if 4 == prefix.version: routes = test.vapi.ip_route_dump(table_id, False) - prefix = IPv4Network("%s/%d" % (text_type(addr), len), strict=False) else: routes = test.vapi.ip_route_dump(table_id, True) - prefix = IPv6Network("%s/%d" % (text_type(addr), len), strict=False) for e in routes: if table_id == e.route.table_id \ - and prefix == e.route.prefix: + and str(e.route.prefix) == str(prefix): + if not sw_if_index: + return True + else: + # should be only one path if the user is looking + # for the interface the route is reachable through + if e.route.n_paths != 1: + return False + else: + return (e.route.paths[0].sw_if_index == sw_if_index) + + return False + + +def find_route_in_dump(dump, route, table): + for r in dump: + if table.table_id == r.route.table_id \ + and route.prefix == r.route.prefix: + if len(route.paths) == r.route.n_paths: + return True + return False + + +def find_mroute_in_dump(dump, route, table): + for r in dump: + if table.table_id == r.route.table_id \ + and route.prefix == r.route.prefix: return True return False @@ -108,7 +140,7 @@ def find_mroute(test, grp_addr, src_addr, grp_addr_len, text_type(grp_addr), grp_addr_len) - if 4 is ip_mprefix.version: + if 4 == ip_mprefix.version: routes = test.vapi.ip_mroute_dump(table_id, False) else: routes = test.vapi.ip_mroute_dump(table_id, True) @@ -137,22 +169,16 @@ def find_mpls_route(test, table_id, label, eos_bit, paths=None): return False -def fib_interface_ip_prefix(test, address, length, sw_if_index): - ip_addr = ip_address(text_type(address)) +def fib_interface_ip_prefix(test, addr, len, sw_if_index): + # can't use python net here since we need the host bits in the prefix + prefix = "%s/%d" % (addr, len) + addrs = test.vapi.ip_address_dump( + sw_if_index, + is_ipv6=(6 == ip_address(addr).version)) - if 4 is ip_addr.version: - addrs = test.vapi.ip_address_dump(sw_if_index) - prefix = IPv4Network("%s/%d" % (text_type(address), length), - strict=False) - else: - addrs = test.vapi.ip_address_dump(sw_if_index, is_ipv6=1) - prefix = IPv6Network("%s/%d" % (text_type(address), length), - strict=False) - - # TODO: refactor this to VppIpPrefix.__eq__ for a in addrs: if a.sw_if_index == sw_if_index and \ - a.prefix == prefix: + str(a.prefix) == prefix: return True return False @@ -168,13 +194,36 @@ class VppIpTable(VppObject): self.is_ip6 = is_ip6 def add_vpp_config(self): - self._test.vapi.ip_table_add_del(is_ipv6=self.is_ip6, is_add=1, - table_id=self.table_id) + self._test.vapi.ip_table_add_del(is_add=1, + table={'is_ip6': self.is_ip6, + 'table_id': self.table_id}) self._test.registry.register(self, self._test.logger) + return self def remove_vpp_config(self): - self._test.vapi.ip_table_add_del(is_ipv6=self.is_ip6, is_add=0, - table_id=self.table_id) + self._test.vapi.ip_table_add_del(is_add=0, + table={'is_ip6': self.is_ip6, + 'table_id': self.table_id}) + + def replace_begin(self): + self._test.vapi.ip_table_replace_begin( + table={'is_ip6': self.is_ip6, + 'table_id': self.table_id}) + + def replace_end(self): + self._test.vapi.ip_table_replace_end( + table={'is_ip6': self.is_ip6, + 'table_id': self.table_id}) + + def flush(self): + self._test.vapi.ip_table_flush(table={'is_ip6': self.is_ip6, + 'table_id': self.table_id}) + + def dump(self): + return self._test.vapi.ip_route_dump(self.table_id, self.is_ip6) + + def mdump(self): + return self._test.vapi.ip_mroute_dump(self.table_id, self.is_ip6) def query_vpp_config(self): if self.table_id == 0: @@ -194,32 +243,64 @@ class VppIpTable(VppObject): class VppIpInterfaceAddress(VppObject): - def __init__(self, test, intf, addr, len): + def __init__(self, test, intf, addr, len, bind=None): self._test = test self.intf = intf - self.prefix = VppIpPrefix(addr, len) + self.addr = addr + self.len = len + self.prefix = "%s/%d" % (addr, len) + self.host_len = ip_network(self.prefix, strict=False).max_prefixlen + self.table_id = 0 + if bind: + self.table_id = bind.table.table_id def add_vpp_config(self): self._test.vapi.sw_interface_add_del_address( - sw_if_index=self.intf.sw_if_index, address=self.prefix.bytes, - address_length=self.prefix.length, is_ipv6=self.prefix.is_ip6, + sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=1) self._test.registry.register(self, self._test.logger) + return self def remove_vpp_config(self): self._test.vapi.sw_interface_add_del_address( - sw_if_index=self.intf.sw_if_index, address=self.prefix.bytes, - address_length=self.prefix.length, is_ipv6=self.prefix.is_ip6, + sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=0) def query_vpp_config(self): - return fib_interface_ip_prefix(self._test, - self.prefix.address, - self.prefix.length, - self.intf.sw_if_index) + # search for the IP address mapping and the two expected + # FIB entries + v = ip_address(self.addr).version + + if ((v == 4 and self.len < 31) or (v == 6 and self.len < 127)): + return (fib_interface_ip_prefix(self._test, + self.addr, + self.len, + self.intf.sw_if_index) & + find_route(self._test, + self.addr, + self.len, + table_id=self.table_id, + sw_if_index=self.intf.sw_if_index) & + find_route(self._test, + self.addr, + self.host_len, + table_id=self.table_id, + sw_if_index=self.intf.sw_if_index)) + else: + return (fib_interface_ip_prefix(self._test, + self.addr, + self.len, + self.intf.sw_if_index) & + find_route(self._test, + self.addr, + self.host_len, + table_id=self.table_id, + sw_if_index=self.intf.sw_if_index)) def object_id(self): - return "interface-ip-%s-%s" % (self.intf, self.prefix) + return "interface-ip-%s-%d-%s" % (self.intf, + self.table_id, + self.prefix) class VppIpInterfaceBind(VppObject): @@ -235,6 +316,7 @@ class VppIpInterfaceBind(VppObject): else: self.intf.set_table_ip4(self.table.table_id) self._test.registry.register(self, self._test.logger) + return self def remove_vpp_config(self): if 0 == self.table.table_id: @@ -425,7 +507,7 @@ class VppIpRoute(VppObject): self._test = test self.paths = paths self.table_id = table_id - self.prefix = VppIpPrefix(dest_addr, dest_addr_len) + self.prefix = mk_network(dest_addr, dest_addr_len) self.register = register self.stats_index = None self.modified = False @@ -448,7 +530,7 @@ class VppIpRoute(VppObject): self.modified = True self._test.vapi.ip_route_add_del(route={'table_id': self.table_id, - 'prefix': self.prefix.encode(), + 'prefix': self.prefix, 'n_paths': len( self.encoded_paths), 'paths': self.encoded_paths, @@ -459,7 +541,7 @@ class VppIpRoute(VppObject): def add_vpp_config(self): r = self._test.vapi.ip_route_add_del( route={'table_id': self.table_id, - 'prefix': self.prefix.encode(), + 'prefix': self.prefix, 'n_paths': len(self.encoded_paths), 'paths': self.encoded_paths, }, @@ -468,6 +550,7 @@ class VppIpRoute(VppObject): self.stats_index = r.stats_index if self.register: self._test.registry.register(self, self._test.logger) + return self def remove_vpp_config(self): # there's no need to issue different deletes for modified routes @@ -477,7 +560,7 @@ class VppIpRoute(VppObject): if self.modified: self._test.vapi.ip_route_add_del( route={'table_id': self.table_id, - 'prefix': self.prefix.encode(), + 'prefix': self.prefix, 'n_paths': len( self.encoded_paths), 'paths': self.encoded_paths}, @@ -486,23 +569,22 @@ class VppIpRoute(VppObject): else: self._test.vapi.ip_route_add_del( route={'table_id': self.table_id, - 'prefix': self.prefix.encode(), + 'prefix': self.prefix, 'n_paths': 0}, is_add=0, is_multipath=0) def query_vpp_config(self): return find_route(self._test, - self.prefix.address, - self.prefix.len, + self.prefix.network_address, + self.prefix.prefixlen, self.table_id) def object_id(self): - return ("%s:table-%d-%s/%d" % ( - 'ip6-route' if self.prefix.addr.version == 6 else 'ip-route', + return ("%s:table-%d-%s" % ( + 'ip6-route' if self.prefix.version == 6 else 'ip-route', self.table_id, - self.prefix.address, - self.prefix.len)) + self.prefix)) def get_stats_to(self): c = self._test.statistics.get_counter("/net/route/to") @@ -541,6 +623,7 @@ class VppIpMRoute(VppObject): is_add=1) self.stats_index = r.stats_index self._test.registry.register(self, self._test.logger) + return self def remove_vpp_config(self): self._test.vapi.ip_mroute_add_del(self.table_id, @@ -628,18 +711,18 @@ class VppMplsIpBind(VppObject): self.local_label = local_label self.table_id = table_id self.ip_table_id = ip_table_id - self.prefix = VppIpPrefix(dest_addr, dest_addr_len) + self.prefix = mk_network(dest_addr, dest_addr_len) def add_vpp_config(self): self._test.vapi.mpls_ip_bind_unbind(self.local_label, - self.prefix.encode(), + self.prefix, table_id=self.table_id, ip_table_id=self.ip_table_id) self._test.registry.register(self, self._test.logger) def remove_vpp_config(self): self._test.vapi.mpls_ip_bind_unbind(self.local_label, - self.prefix.encode(), + self.prefix, table_id=self.table_id, ip_table_id=self.ip_table_id, is_bind=0)