IP Multicast FIB (mfib)
[vpp.git] / test / vpp_ip_route.py
1 """
2   IP Routes
3
4   object abstractions for representing IP routes in VPP
5 """
6
7 import socket
8
9 # from vnet/vnet/mpls/mpls_types.h
10 MPLS_IETF_MAX_LABEL = 0xfffff
11 MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
12
13
14 class RoutePath(object):
15
16     def __init__(
17             self,
18             nh_addr,
19             nh_sw_if_index,
20             nh_table_id=0,
21             labels=[],
22             nh_via_label=MPLS_LABEL_INVALID,
23             is_ip6=0):
24         self.nh_itf = nh_sw_if_index
25         self.nh_table_id = nh_table_id
26         self.nh_via_label = nh_via_label
27         self.nh_labels = labels
28         if is_ip6:
29             self.nh_addr = socket.inet_pton(socket.AF_INET6, nh_addr)
30         else:
31             self.nh_addr = socket.inet_pton(socket.AF_INET, nh_addr)
32
33
34 class MRoutePath(RoutePath):
35
36     def __init__(self, nh_sw_if_index, flags):
37         super(MRoutePath, self).__init__("0.0.0.0",
38                                          nh_sw_if_index)
39         self.nh_i_flags = flags
40
41
42 class IpRoute:
43     """
44     IP Route
45     """
46
47     def __init__(self, test, dest_addr,
48                  dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0):
49         self._test = test
50         self.paths = paths
51         self.dest_addr_len = dest_addr_len
52         self.table_id = table_id
53         self.is_ip6 = is_ip6
54         self.is_local = is_local
55         if is_ip6:
56             self.dest_addr = socket.inet_pton(socket.AF_INET6, dest_addr)
57         else:
58             self.dest_addr = socket.inet_pton(socket.AF_INET, dest_addr)
59
60     def add_vpp_config(self):
61         if self.is_local:
62             self._test.vapi.ip_add_del_route(
63                 self.dest_addr,
64                 self.dest_addr_len,
65                 socket.inet_pton(socket.AF_INET6, "::"),
66                 0xffffffff,
67                 is_local=1,
68                 table_id=self.table_id,
69                 is_ipv6=self.is_ip6)
70         else:
71             for path in self.paths:
72                 self._test.vapi.ip_add_del_route(
73                     self.dest_addr,
74                     self.dest_addr_len,
75                     path.nh_addr,
76                     path.nh_itf,
77                     table_id=self.table_id,
78                     next_hop_out_label_stack=path.nh_labels,
79                     next_hop_n_out_labels=len(
80                         path.nh_labels),
81                     next_hop_via_label=path.nh_via_label,
82                     is_ipv6=self.is_ip6)
83
84     def remove_vpp_config(self):
85         if self.is_local:
86             self._test.vapi.ip_add_del_route(
87                 self.dest_addr,
88                 self.dest_addr_len,
89                 socket.inet_pton(socket.AF_INET6, "::"),
90                 0xffffffff,
91                 is_local=1,
92                 is_add=0,
93                 table_id=self.table_id,
94                 is_ipv6=self.is_ip6)
95         else:
96             for path in self.paths:
97                 self._test.vapi.ip_add_del_route(self.dest_addr,
98                                                  self.dest_addr_len,
99                                                  path.nh_addr,
100                                                  path.nh_itf,
101                                                  table_id=self.table_id,
102                                                  is_add=0)
103
104
105 class IpMRoute:
106     """
107     IP Multicast Route
108     """
109
110     def __init__(self, test, src_addr, grp_addr,
111                  grp_addr_len, e_flags, paths, table_id=0, is_ip6=0):
112         self._test = test
113         self.paths = paths
114         self.grp_addr_len = grp_addr_len
115         self.table_id = table_id
116         self.e_flags = e_flags
117         self.is_ip6 = is_ip6
118
119         if is_ip6:
120             self.grp_addr = socket.inet_pton(socket.AF_INET6, grp_addr)
121             self.src_addr = socket.inet_pton(socket.AF_INET6, src_addr)
122         else:
123             self.grp_addr = socket.inet_pton(socket.AF_INET, grp_addr)
124             self.src_addr = socket.inet_pton(socket.AF_INET, src_addr)
125
126     def add_vpp_config(self):
127         for path in self.paths:
128             self._test.vapi.ip_mroute_add_del(self.src_addr,
129                                               self.grp_addr,
130                                               self.grp_addr_len,
131                                               self.e_flags,
132                                               path.nh_itf,
133                                               path.nh_i_flags,
134                                               table_id=self.table_id,
135                                               is_ipv6=self.is_ip6)
136
137     def remove_vpp_config(self):
138         for path in self.paths:
139             self._test.vapi.ip_mroute_add_del(self.src_addr,
140                                               self.grp_addr,
141                                               self.grp_addr_len,
142                                               self.e_flags,
143                                               path.nh_itf,
144                                               path.nh_i_flags,
145                                               table_id=self.table_id,
146                                               is_add=0,
147                                               is_ipv6=self.is_ip6)
148
149     def update_entry_flags(self, flags):
150         self.e_flags = flags
151         self._test.vapi.ip_mroute_add_del(self.src_addr,
152                                           self.grp_addr,
153                                           self.grp_addr_len,
154                                           self.e_flags,
155                                           0xffffffff,
156                                           0,
157                                           table_id=self.table_id,
158                                           is_ipv6=self.is_ip6)
159
160     def update_path_flags(self, itf, flags):
161         for path in self.paths:
162             if path.nh_itf == itf:
163                 path.nh_i_flags = flags
164                 break
165         self._test.vapi.ip_mroute_add_del(self.src_addr,
166                                           self.grp_addr,
167                                           self.grp_addr_len,
168                                           self.e_flags,
169                                           path.nh_itf,
170                                           path.nh_i_flags,
171                                           table_id=self.table_id,
172                                           is_ipv6=self.is_ip6)
173
174
175 class MFibSignal:
176     def __init__(self, test, route, interface, packet):
177         self.route = route
178         self.interface = interface
179         self.packet = packet
180         self.test = test
181
182     def compare(self, signal):
183         self.test.assertEqual(self.interface, signal.sw_if_index)
184         self.test.assertEqual(self.route.table_id, signal.table_id)
185         self.test.assertEqual(self.route.grp_addr_len,
186                               signal.grp_address_len)
187         for i in range(self.route.grp_addr_len / 8):
188             self.test.assertEqual(self.route.grp_addr[i],
189                                   signal.grp_address[i])
190         if (self.route.grp_addr_len > 32):
191             for i in range(4):
192                 self.test.assertEqual(self.route.src_addr[i],
193                                       signal.src_address[i])
194
195
196 class MplsIpBind:
197     """
198     MPLS to IP Binding
199     """
200
201     def __init__(self, test, local_label, dest_addr, dest_addr_len):
202         self._test = test
203         self.dest_addr = socket.inet_pton(socket.AF_INET, dest_addr)
204         self.dest_addr_len = dest_addr_len
205         self.local_label = local_label
206
207     def add_vpp_config(self):
208         self._test.vapi.mpls_ip_bind_unbind(self.local_label,
209                                             self.dest_addr,
210                                             self.dest_addr_len)
211
212     def remove_vpp_config(self):
213         self._test.vapi.mpls_ip_bind_unbind(self.local_label,
214                                             self.dest_addr,
215                                             self.dest_addr_len,
216                                             is_bind=0)
217
218
219 class MplsRoute:
220     """
221     MPLS Route
222     """
223
224     def __init__(self, test, local_label, eos_bit, paths, table_id=0):
225         self._test = test
226         self.paths = paths
227         self.local_label = local_label
228         self.eos_bit = eos_bit
229         self.table_id = table_id
230
231     def add_vpp_config(self):
232         for path in self.paths:
233             self._test.vapi.mpls_route_add_del(
234                 self.local_label,
235                 self.eos_bit,
236                 1,
237                 path.nh_addr,
238                 path.nh_itf,
239                 table_id=self.table_id,
240                 next_hop_out_label_stack=path.nh_labels,
241                 next_hop_n_out_labels=len(
242                     path.nh_labels),
243                 next_hop_via_label=path.nh_via_label,
244                 next_hop_table_id=path.nh_table_id)
245
246     def remove_vpp_config(self):
247         for path in self.paths:
248             self._test.vapi.mpls_route_add_del(self.local_label,
249                                                self.eos_bit,
250                                                1,
251                                                path.nh_addr,
252                                                path.nh_itf,
253                                                table_id=self.table_id,
254                                                is_add=0)