Remove the unused VRF ID parameter from the IP neighbour Add/Del API
[vpp.git] / test / vpp_interface.py
1 from abc import abstractmethod, ABCMeta
2 import socket
3
4 from util import Host
5 from vpp_neighbor import VppNeighbor
6
7
8 class VppInterface(object):
9     """Generic VPP interface."""
10     __metaclass__ = ABCMeta
11
12     @property
13     def sw_if_index(self):
14         """Interface index assigned by VPP."""
15         return self._sw_if_index
16
17     @property
18     def remote_mac(self):
19         """MAC-address of the remote interface "connected" to this interface"""
20         return self._remote_hosts[0].mac
21
22     @property
23     def local_mac(self):
24         """MAC-address of the VPP interface."""
25         return self._local_mac
26
27     @property
28     def local_ip4(self):
29         """Local IPv4 address on VPP interface (string)."""
30         return self._local_ip4
31
32     @property
33     def local_ip4n(self):
34         """Local IPv4 address - raw, suitable as API parameter."""
35         return socket.inet_pton(socket.AF_INET, self._local_ip4)
36
37     @property
38     def remote_ip4(self):
39         """IPv4 address of remote peer "connected" to this interface."""
40         return self._remote_hosts[0].ip4
41
42     @property
43     def remote_ip4n(self):
44         """IPv4 address of remote peer - raw, suitable as API parameter."""
45         return socket.inet_pton(socket.AF_INET, self.remote_ip4)
46
47     @property
48     def local_ip6(self):
49         """Local IPv6 address on VPP interface (string)."""
50         return self._local_ip6
51
52     @property
53     def local_ip6n(self):
54         """Local IPv6 address - raw, suitable as API parameter."""
55         return socket.inet_pton(socket.AF_INET6, self.local_ip6)
56
57     @property
58     def remote_ip6(self):
59         """IPv6 address of remote peer "connected" to this interface."""
60         return self._remote_hosts[0].ip6
61
62     @property
63     def remote_ip6n(self):
64         """IPv6 address of remote peer - raw, suitable as API parameter"""
65         return socket.inet_pton(socket.AF_INET6, self.remote_ip6)
66
67     @property
68     def name(self):
69         """Name of the interface."""
70         return self._name
71
72     @property
73     def dump(self):
74         """RAW result of sw_interface_dump for this interface."""
75         return self._dump
76
77     @property
78     def test(self):
79         """Test case creating this interface."""
80         return self._test
81
82     @property
83     def remote_hosts(self):
84         """Remote hosts list"""
85         return self._remote_hosts
86
87     @remote_hosts.setter
88     def remote_hosts(self, value):
89         """
90         :param list value: List of remote hosts.
91         """
92         self._remote_hosts = value
93         self._hosts_by_mac = {}
94         self._hosts_by_ip4 = {}
95         self._hosts_by_ip6 = {}
96         for host in self._remote_hosts:
97             self._hosts_by_mac[host.mac] = host
98             self._hosts_by_ip4[host.ip4] = host
99             self._hosts_by_ip6[host.ip6] = host
100
101     def host_by_mac(self, mac):
102         """
103         :param mac: MAC address to find host by.
104         :return: Host object assigned to interface.
105         """
106         return self._hosts_by_mac[mac]
107
108     def host_by_ip4(self, ip):
109         """
110         :param ip: IPv4 address to find host by.
111         :return: Host object assigned to interface.
112         """
113         return self._hosts_by_ip4[ip]
114
115     def host_by_ip6(self, ip):
116         """
117         :param ip: IPv6 address to find host by.
118         :return: Host object assigned to interface.
119         """
120         return self._hosts_by_ip6[ip]
121
122     def generate_remote_hosts(self, count=1):
123         """Generate and add remote hosts for the interface.
124
125         :param int count: Number of generated remote hosts.
126         """
127         self._remote_hosts = []
128         self._hosts_by_mac = {}
129         self._hosts_by_ip4 = {}
130         self._hosts_by_ip6 = {}
131         for i in range(
132                 2, count + 2):  # 0: network address, 1: local vpp address
133             mac = "02:%02x:00:00:ff:%02x" % (self.sw_if_index, i)
134             ip4 = "172.16.%u.%u" % (self.sw_if_index, i)
135             ip6 = "fd01:%x::%x" % (self.sw_if_index, i)
136             host = Host(mac, ip4, ip6)
137             self._remote_hosts.append(host)
138             self._hosts_by_mac[mac] = host
139             self._hosts_by_ip4[ip4] = host
140             self._hosts_by_ip6[ip6] = host
141
142     @abstractmethod
143     def __init__(self, test):
144         self._test = test
145
146         self._remote_hosts = []
147         self._hosts_by_mac = {}
148         self._hosts_by_ip4 = {}
149         self._hosts_by_ip6 = {}
150
151         self.generate_remote_hosts()
152
153         self._local_ip4 = "172.16.%u.1" % self.sw_if_index
154         self._local_ip4n = socket.inet_pton(socket.AF_INET, self.local_ip4)
155         self.local_ip4_prefix_len = 24
156         self.has_ip4_config = False
157         self.ip4_table_id = 0
158
159         self._local_ip6 = "fd01:%x::1" % self.sw_if_index
160         self._local_ip6n = socket.inet_pton(socket.AF_INET6, self.local_ip6)
161         self.local_ip6_prefix_len = 64
162         self.has_ip6_config = False
163         self.ip6_table_id = 0
164
165         r = self.test.vapi.sw_interface_dump()
166         for intf in r:
167             if intf.sw_if_index == self.sw_if_index:
168                 self._name = intf.interface_name.split(b'\0', 1)[0]
169                 self._local_mac = \
170                     ':'.join(intf.l2_address.encode('hex')[i:i + 2]
171                              for i in range(0, 12, 2))
172                 self._dump = intf
173                 break
174         else:
175             raise Exception(
176                 "Could not find interface with sw_if_index %d "
177                 "in interface dump %s" %
178                 (self.sw_if_index, repr(r)))
179
180     def config_ip4(self):
181         """Configure IPv4 address on the VPP interface."""
182         self.test.vapi.sw_interface_add_del_address(
183             self.sw_if_index, self.local_ip4n, self.local_ip4_prefix_len)
184         self.has_ip4_config = True
185
186     def unconfig_ip4(self):
187         """Remove IPv4 address on the VPP interface."""
188         try:
189             if self.has_ip4_config:
190                 self.test.vapi.sw_interface_add_del_address(
191                     self.sw_if_index,
192                     self.local_ip4n,
193                     self.local_ip4_prefix_len,
194                     is_add=0)
195         except AttributeError:
196             self.has_ip4_config = False
197         self.has_ip4_config = False
198
199     def configure_ipv4_neighbors(self):
200         """For every remote host assign neighbor's MAC to IPv4 addresses.
201
202         :param vrf_id: The FIB table / VRF ID. (Default value = 0)
203         """
204         for host in self._remote_hosts:
205             macn = host.mac.replace(":", "").decode('hex')
206             ipn = host.ip4n
207             self.test.vapi.ip_neighbor_add_del(
208                 self.sw_if_index, macn, ipn)
209
210     def config_ip6(self):
211         """Configure IPv6 address on the VPP interface."""
212         self.test.vapi.sw_interface_add_del_address(
213             self.sw_if_index, self._local_ip6n, self.local_ip6_prefix_len,
214             is_ipv6=1)
215         self.has_ip6_config = True
216
217     def unconfig_ip6(self):
218         """Remove IPv6 address on the VPP interface."""
219         try:
220             if self.has_ip6_config:
221                 self.test.vapi.sw_interface_add_del_address(
222                     self.sw_if_index,
223                     self.local_ip6n,
224                     self.local_ip6_prefix_len,
225                     is_ipv6=1, is_add=0)
226         except AttributeError:
227             self.has_ip6_config = False
228         self.has_ip6_config = False
229
230     def configure_ipv6_neighbors(self):
231         """For every remote host assign neighbor's MAC to IPv6 addresses.
232
233         :param vrf_id: The FIB table / VRF ID. (Default value = 0)
234         """
235         for host in self._remote_hosts:
236             macn = host.mac.replace(":", "").decode('hex')
237             ipn = host.ip6n
238             self.test.vapi.ip_neighbor_add_del(
239                 self.sw_if_index, macn, ipn, is_ipv6=1)
240
241     def unconfig(self):
242         """Unconfigure IPv6 and IPv4 address on the VPP interface."""
243         self.unconfig_ip4()
244         self.unconfig_ip6()
245
246     def set_table_ip4(self, table_id):
247         """Set the interface in a IPv4 Table.
248
249         .. note:: Must be called before configuring IP4 addresses.
250         """
251         self.ip4_table_id = table_id
252         self.test.vapi.sw_interface_set_table(
253             self.sw_if_index, 0, self.ip4_table_id)
254
255     def set_table_ip6(self, table_id):
256         """Set the interface in a IPv6 Table.
257
258         .. note:: Must be called before configuring IP6 addresses.
259         """
260         self.ip6_table_id = table_id
261         self.test.vapi.sw_interface_set_table(
262             self.sw_if_index, 1, self.ip6_table_id)
263
264     def disable_ipv6_ra(self):
265         """Configure IPv6 RA suppress on the VPP interface."""
266         self.test.vapi.sw_interface_ra_suppress(self.sw_if_index)
267
268     def ip6_ra_config(self, no=0, suppress=0, send_unicast=0):
269         """Configure IPv6 RA suppress on the VPP interface."""
270         self.test.vapi.ip6_sw_interface_ra_config(self.sw_if_index,
271                                                   no,
272                                                   suppress,
273                                                   send_unicast)
274
275     def admin_up(self):
276         """Put interface ADMIN-UP."""
277         self.test.vapi.sw_interface_set_flags(self.sw_if_index,
278                                               admin_up_down=1)
279
280     def admin_down(self):
281         """Put interface ADMIN-down."""
282         self.test.vapi.sw_interface_set_flags(self.sw_if_index,
283                                               admin_up_down=0)
284
285     def ip6_enable(self):
286         """IPv6 Enable interface"""
287         self.test.vapi.ip6_sw_interface_enable_disable(self.sw_if_index,
288                                                        enable=1)
289
290     def ip6_disable(self):
291         """Put interface ADMIN-DOWN."""
292         self.test.vapi.ip6_sw_interface_enable_disable(self.sw_if_index,
293                                                        enable=0)
294
295     def add_sub_if(self, sub_if):
296         """Register a sub-interface with this interface.
297
298         :param sub_if: sub-interface
299         """
300         if not hasattr(self, 'sub_if'):
301             self.sub_if = sub_if
302         else:
303             if isinstance(self.sub_if, list):
304                 self.sub_if.append(sub_if)
305             else:
306                 self.sub_if = sub_if
307
308     def enable_mpls(self):
309         """Enable MPLS on the VPP interface."""
310         self.test.vapi.sw_interface_enable_disable_mpls(
311             self.sw_if_index)
312
313     def is_ip4_entry_in_fib_dump(self, dump):
314         for i in dump:
315             if i.address == self.local_ip4n and \
316                i.address_length == self.local_ip4_prefix_len and \
317                i.table_id == self.ip4_table_id:
318                 return True
319         return False
320
321     def set_unnumbered(self, ip_sw_if_index):
322         """ Set the interface to unnumbered via ip_sw_if_index """
323         self.test.vapi.sw_interface_set_unnumbered(
324             self.sw_if_index,
325             ip_sw_if_index)
326
327     def set_proxy_arp(self, enable=1):
328         """ Set the interface to enable/disable Proxy ARP """
329         self.test.vapi.proxy_arp_intfc_enable_disable(
330             self.sw_if_index,
331             enable)