"""
from vpp_object import VppObject
-from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
from vpp_ip import DpoProto, INVALID_INDEX, VppIpAddressUnion, \
VppIpMPrefix
from ipaddress import ip_network, ip_address, IPv4Network, IPv6Network
+from vpp_papi_exceptions import UnexpectedApiReturnValueError
# from vnet/vnet/mpls/mpls_types.h
MPLS_IETF_MAX_LABEL = 0xfffff
text_type = str
-class MRouteItfFlags:
- MFIB_ITF_FLAG_NONE = 0
- MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
- MFIB_ITF_FLAG_ACCEPT = 2
- MFIB_ITF_FLAG_FORWARD = 4
- MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
- MFIB_ITF_FLAG_INTERNAL_COPY = 16
-
-
-class MRouteEntryFlags:
- MFIB_ENTRY_FLAG_NONE = 0
- MFIB_ENTRY_FLAG_SIGNAL = 1
- MFIB_ENTRY_FLAG_DROP = 2
- MFIB_ENTRY_FLAG_CONNECTED = 4
- MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
-
-
class FibPathProto:
FIB_PATH_NH_PROTO_IP4 = 0
FIB_PATH_NH_PROTO_IP6 = 1
def __init__(self,
test,
table_id,
- is_ip6=0):
+ is_ip6=0,
+ register=True):
self._test = test
self.table_id = table_id
self.is_ip6 = is_ip6
+ self.register = register
def add_vpp_config(self):
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)
+ if self.register:
+ self._test.registry.register(self, self._test.logger)
return self
def remove_vpp_config(self):
def query_vpp_config(self):
if 0 == self.table.table_id:
return False
- return self._test.vapi.sw_interface_get_table(
- self.intf.sw_if_index,
- self.table.is_ip6).vrf_id == self.table.table_id
+ try:
+ return self._test.vapi.sw_interface_get_table(
+ self.intf.sw_if_index,
+ self.table.is_ip6).vrf_id == self.table.table_id
+ except UnexpectedApiReturnValueError as e:
+ if e.retval == -2: # INVALID_SW_IF_INDEX
+ return False
+ raise
def object_id(self):
return "interface-bind-%s-%s" % (self.intf, self.table)
-class VppMplsLabel(object):
+class VppMplsLabel:
def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
self.value = value
self.mode = mode
return not (self == other)
-class VppFibPathNextHop(object):
+class VppFibPathNextHop:
def __init__(self, addr,
via_label=MPLS_LABEL_INVALID,
next_hop_id=INVALID_INDEX):
self.obj_id == other.obj_id)
-class VppRoutePath(object):
+class VppRoutePath:
def __init__(
self,
return c[0][self.stats_index]
+class VppIpRouteV2(VppObject):
+ """
+ IP Route V2
+ """
+
+ def __init__(self, test, dest_addr,
+ dest_addr_len, paths, table_id=0,
+ register=True, src=0):
+ self._test = test
+ self.paths = paths
+ self.table_id = table_id
+ self.prefix = mk_network(dest_addr, dest_addr_len)
+ self.register = register
+ self.stats_index = None
+ self.modified = False
+ self.src = src
+
+ self.encoded_paths = []
+ for path in self.paths:
+ self.encoded_paths.append(path.encode())
+
+ def __eq__(self, other):
+ if self.table_id == other.table_id and \
+ self.prefix == other.prefix:
+ return True
+ return False
+
+ def modify(self, paths):
+ self.paths = paths
+ self.encoded_paths = []
+ for path in self.paths:
+ self.encoded_paths.append(path.encode())
+ self.modified = True
+
+ self._test.vapi.ip_route_add_del_v2(route={'table_id': self.table_id,
+ 'prefix': self.prefix,
+ 'src': self.src,
+ 'n_paths': len(
+ self.encoded_paths),
+ 'paths': self.encoded_paths,
+ },
+ is_add=1,
+ is_multipath=0)
+
+ def add_vpp_config(self):
+ r = self._test.vapi.ip_route_add_del_v2(
+ route={'table_id': self.table_id,
+ 'prefix': self.prefix,
+ 'n_paths': len(self.encoded_paths),
+ 'paths': self.encoded_paths,
+ 'src': self.src,
+ },
+ is_add=1,
+ is_multipath=0)
+ 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
+ # we do this only to test the two different ways to delete routes
+ # eiter by passing all the paths to remove and mutlipath=1 or
+ # passing no paths and multipath=0
+ if self.modified:
+ self._test.vapi.ip_route_add_del_v2(
+ route={'table_id': self.table_id,
+ 'prefix': self.prefix,
+ 'src': self.src,
+ 'n_paths': len(
+ self.encoded_paths),
+ 'paths': self.encoded_paths},
+ is_add=0,
+ is_multipath=1)
+ else:
+ self._test.vapi.ip_route_add_del_v2(
+ route={'table_id': self.table_id,
+ 'prefix': self.prefix,
+ 'src': self.src,
+ 'n_paths': 0},
+ is_add=0,
+ is_multipath=0)
+
+ def query_vpp_config(self):
+ return find_route(self._test,
+ self.prefix.network_address,
+ self.prefix.prefixlen,
+ self.table_id)
+
+ def object_id(self):
+ return ("%s:table-%d-%s" % (
+ 'ip6-route' if self.prefix.version == 6 else 'ip-route',
+ self.table_id,
+ self.prefix))
+
+ def get_stats_to(self):
+ c = self._test.statistics.get_counter("/net/route/to")
+ return c[0][self.stats_index]
+
+ def get_stats_via(self):
+ c = self._test.statistics.get_counter("/net/route/via")
+ return c[0][self.stats_index]
+
+
class VppIpMRoute(VppObject):
"""
IP Multicast Route
for p in range(len(self.paths)):
if self.paths[p].nh_itf == itf:
self.paths[p].nh_i_flags = flags
- self.encoded_paths[p] = self.paths[p].encode()
- break
+ self.encoded_paths[p] = self.paths[p].encode()
+ break
self._test.vapi.ip_mroute_add_del(
route=self.encode(
return c[0][self.stats_index]
-class VppMFibSignal(object):
+class VppMFibSignal:
def __init__(self, test, route, interface, packet):
self.route = route
self.interface = interface