blob: 568191c6f3513f1769887e65780e6ae0dc31a287 [file] [log] [blame]
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001#!/usr/bin/env python
2
3import unittest
Neale Rannsbc27d1b2018-02-05 01:13:38 -08004
juraj.linkes23c9a2e2018-12-21 10:17:03 +01005from framework import VppTestCase, VppTestRunner
Neale Rannsbc27d1b2018-02-05 01:13:38 -08006from vpp_object import VppObject
Neale Ranns25b04942018-04-04 09:34:50 -07007from vpp_neighbor import VppNeighbor
Neale Ranns93cc3ee2018-10-10 07:22:51 -07008from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \
9 VppIpInterfaceAddress, VppIpInterfaceBind, find_route
10from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
11 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port
12from vpp_vxlan_gbp_tunnel import *
Neale Rannsc29c0af2018-11-07 04:21:12 -080013from vpp_sub_interface import VppDot1QSubint
Neale Rannsc0a93142018-09-05 15:42:26 -070014
15from vpp_ip import *
Neale Rannsb4743802018-09-05 09:13:57 -070016from vpp_papi_provider import L2_PORT_TYPE
Ole Troan8006c6a2018-12-17 12:02:26 +010017from vpp_papi import VppEnum, MACAddress
Neale Rannsbc27d1b2018-02-05 01:13:38 -080018
19from scapy.packet import Raw
Neale Rannsc29c0af2018-11-07 04:21:12 -080020from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Rannsbc27d1b2018-02-05 01:13:38 -080021from scapy.layers.inet import IP, UDP
Neale Ranns25b04942018-04-04 09:34:50 -070022from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
Klement Sekerab9ef2732018-06-24 22:49:33 +020023 ICMPv6ND_NA
Neale Ranns25b04942018-04-04 09:34:50 -070024from scapy.utils6 import in6_getnsma, in6_getnsmac
Neale Ranns93cc3ee2018-10-10 07:22:51 -070025from scapy.layers.vxlan import VXLAN
Neale Ranns1c17e2e2018-12-20 12:03:59 -080026from scapy.data import ETH_P_IP, ETH_P_IPV6
Neale Rannsbc27d1b2018-02-05 01:13:38 -080027
28from socket import AF_INET, AF_INET6
Neale Ranns25b04942018-04-04 09:34:50 -070029from scapy.utils import inet_pton, inet_ntop
Neale Rannsc29c0af2018-11-07 04:21:12 -080030from vpp_papi_provider import L2_VTR_OP
Neale Rannsbc27d1b2018-02-05 01:13:38 -080031
32
Neale Ranns93cc3ee2018-10-10 07:22:51 -070033def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None):
34 if ip:
35 vip = VppIpAddress(ip)
36 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010037 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070038
39 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070040
Neale Rannsc0a93142018-09-05 15:42:26 -070041 for ep in eps:
Neale Ranns93cc3ee2018-10-10 07:22:51 -070042 if sw_if_index:
43 if ep.endpoint.sw_if_index != sw_if_index:
44 continue
45 if ip:
46 for eip in ep.endpoint.ips:
47 if vip == eip:
48 return True
49 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010050 if vmac.packed == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070051 return True
52 return False
53
54
Neale Ranns93cc3ee2018-10-10 07:22:51 -070055def find_gbp_vxlan(test, vni):
56 ts = test.vapi.gbp_vxlan_tunnel_dump()
57 for t in ts:
58 if t.tunnel.vni == vni:
59 return True
60 return False
61
62
Neale Rannsbc27d1b2018-02-05 01:13:38 -080063class VppGbpEndpoint(VppObject):
64 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020065 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080066 """
67
Neale Ranns25b04942018-04-04 09:34:50 -070068 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -070069 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +010070 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -070071
72 @property
73 def mac(self):
74 return self.itf.remote_mac
75
Neale Rannsc0a93142018-09-05 15:42:26 -070076 @property
77 def ip4(self):
78 return self._ip4
79
80 @property
81 def fip4(self):
82 return self._fip4
83
84 @property
85 def ip6(self):
86 return self._ip6
87
88 @property
89 def fip6(self):
90 return self._fip6
91
92 @property
93 def ips(self):
94 return [self.ip4, self.ip6]
95
96 @property
97 def fips(self):
98 return [self.fip4, self.fip6]
99
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700100 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
101 flags=0,
102 tun_src="0.0.0.0",
103 tun_dst="0.0.0.0",
104 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800105 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700106 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800107 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700108 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700109
110 self._ip4 = VppIpAddress(ip4)
111 self._fip4 = VppIpAddress(fip4)
112 self._ip6 = VppIpAddress(ip6)
113 self._fip6 = VppIpAddress(fip6)
114
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700115 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100116 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700117 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100118 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700119
120 self.flags = flags
121 self.tun_src = VppIpAddress(tun_src)
122 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800123
124 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700125 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700126 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700127 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100128 self.vmac.packed,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700129 self.epg.epg,
130 self.flags,
131 self.tun_src.encode(),
132 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700133 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800134 self._test.registry.register(self, self._test.logger)
135
136 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700137 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800138
139 def __str__(self):
140 return self.object_id()
141
142 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700143 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
144 self.itf.sw_if_index,
145 self.ip4.address,
146 self.epg.epg)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800147
148 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700149 return find_gbp_endpoint(self._test,
150 self.itf.sw_if_index,
151 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700152
153
154class VppGbpRecirc(VppObject):
155 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200156 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700157 """
158
159 def __init__(self, test, epg, recirc, is_ext=False):
160 self._test = test
161 self.recirc = recirc
162 self.epg = epg
163 self.is_ext = is_ext
164
165 def add_vpp_config(self):
166 self._test.vapi.gbp_recirc_add_del(
167 1,
168 self.recirc.sw_if_index,
169 self.epg.epg,
170 self.is_ext)
171 self._test.registry.register(self, self._test.logger)
172
173 def remove_vpp_config(self):
174 self._test.vapi.gbp_recirc_add_del(
175 0,
176 self.recirc.sw_if_index,
177 self.epg.epg,
178 self.is_ext)
179
180 def __str__(self):
181 return self.object_id()
182
183 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700184 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700185
186 def query_vpp_config(self):
187 rs = self._test.vapi.gbp_recirc_dump()
188 for r in rs:
189 if r.recirc.sw_if_index == self.recirc.sw_if_index:
190 return True
191 return False
192
193
Neale Rannsb6a47952018-11-21 05:44:35 -0800194class VppGbpExtItf(VppObject):
195 """
196 GBP ExtItfulation Interface
197 """
198
199 def __init__(self, test, itf, bd, rd):
200 self._test = test
201 self.itf = itf
202 self.bd = bd
203 self.rd = rd
204
205 def add_vpp_config(self):
206 self._test.vapi.gbp_ext_itf_add_del(
207 1,
208 self.itf.sw_if_index,
209 self.bd.bd_id,
210 self.rd.rd_id)
211 self._test.registry.register(self, self._test.logger)
212
213 def remove_vpp_config(self):
214 self._test.vapi.gbp_ext_itf_add_del(
215 0,
216 self.itf.sw_if_index,
217 self.bd.bd_id,
218 self.rd.rd_id)
219
220 def __str__(self):
221 return self.object_id()
222
223 def object_id(self):
224 return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index)
225
226 def query_vpp_config(self):
227 rs = self._test.vapi.gbp_ext_itf_dump()
228 for r in rs:
229 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
230 return True
231 return False
232
233
Neale Ranns25b04942018-04-04 09:34:50 -0700234class VppGbpSubnet(VppObject):
235 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200236 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700237 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700238 def __init__(self, test, rd, address, address_len,
239 type, sw_if_index=None, epg=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700240 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700241 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200242 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700243 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700244 self.sw_if_index = sw_if_index
245 self.epg = epg
246
247 def add_vpp_config(self):
248 self._test.vapi.gbp_subnet_add_del(
249 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700250 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200251 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700252 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700253 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Rannsc0a93142018-09-05 15:42:26 -0700254 epg_id=self.epg if self.epg else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700255 self._test.registry.register(self, self._test.logger)
256
257 def remove_vpp_config(self):
258 self._test.vapi.gbp_subnet_add_del(
259 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700260 self.rd_id,
261 self.prefix.encode(),
262 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700263
264 def __str__(self):
265 return self.object_id()
266
267 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700268 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700269
270 def query_vpp_config(self):
271 ss = self._test.vapi.gbp_subnet_dump()
272 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700273 if s.subnet.rd_id == self.rd_id and \
274 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200275 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700276 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700277 return False
278
279
280class VppGbpEndpointGroup(VppObject):
281 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200282 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700283 """
284
285 def __init__(self, test, epg, rd, bd, uplink,
286 bvi, bvi_ip4, bvi_ip6=None):
287 self._test = test
288 self.uplink = uplink
289 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700290 self.bvi_ip4 = VppIpAddress(bvi_ip4)
291 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns25b04942018-04-04 09:34:50 -0700292 self.epg = epg
293 self.bd = bd
294 self.rd = rd
295
296 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700297 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700298 self.epg,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700299 self.bd.bd.bd_id,
300 self.rd.rd_id,
301 self.uplink.sw_if_index if self.uplink else INDEX_INVALID)
Neale Ranns25b04942018-04-04 09:34:50 -0700302 self._test.registry.register(self, self._test.logger)
303
304 def remove_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700305 self._test.vapi.gbp_endpoint_group_del(
306 self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700307
308 def __str__(self):
309 return self.object_id()
310
311 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700312 return "gbp-endpoint-group:[%d]" % (self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700313
314 def query_vpp_config(self):
315 epgs = self._test.vapi.gbp_endpoint_group_dump()
316 for epg in epgs:
317 if epg.epg.epg_id == self.epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800318 return True
319 return False
320
321
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700322class VppGbpBridgeDomain(VppObject):
323 """
324 GBP Bridge Domain
325 """
326
Neale Rannsc29c0af2018-11-07 04:21:12 -0800327 def __init__(self, test, bd, bvi, uu_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700328 self._test = test
329 self.bvi = bvi
330 self.uu_flood = uu_flood
331 self.bd = bd
332
Neale Rannsc29c0af2018-11-07 04:21:12 -0800333 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
334 if (learn):
335 self.learn = e.GBP_BD_API_FLAG_NONE
336 else:
337 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
338
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700339 def add_vpp_config(self):
340 self._test.vapi.gbp_bridge_domain_add(
341 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800342 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700343 self.bvi.sw_if_index,
344 self.uu_flood.sw_if_index if self.uu_flood else INDEX_INVALID)
345 self._test.registry.register(self, self._test.logger)
346
347 def remove_vpp_config(self):
348 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
349
350 def __str__(self):
351 return self.object_id()
352
353 def object_id(self):
354 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
355
356 def query_vpp_config(self):
357 bds = self._test.vapi.gbp_bridge_domain_dump()
358 for bd in bds:
359 if bd.bd.bd_id == self.bd.bd_id:
360 return True
361 return False
362
363
364class VppGbpRouteDomain(VppObject):
365 """
366 GBP Route Domain
367 """
368
369 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
370 self._test = test
371 self.rd_id = rd_id
372 self.t4 = t4
373 self.t6 = t6
374 self.ip4_uu = ip4_uu
375 self.ip6_uu = ip6_uu
376
377 def add_vpp_config(self):
378 self._test.vapi.gbp_route_domain_add(
379 self.rd_id,
380 self.t4.table_id,
381 self.t6.table_id,
382 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
383 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
384 self._test.registry.register(self, self._test.logger)
385
386 def remove_vpp_config(self):
387 self._test.vapi.gbp_route_domain_del(self.rd_id)
388
389 def __str__(self):
390 return self.object_id()
391
392 def object_id(self):
393 return "gbp-route-domain:[%d]" % (self.rd_id)
394
395 def query_vpp_config(self):
396 rds = self._test.vapi.gbp_route_domain_dump()
397 for rd in rds:
398 if rd.rd.rd_id == self.rd_id:
399 return True
400 return False
401
402
Neale Ranns13a08cc2018-11-07 09:25:54 -0800403class VppGbpContractNextHop():
404 def __init__(self, mac, bd, ip, rd):
405 self.mac = mac
406 self.ip = ip
407 self.bd = bd
408 self.rd = rd
409
410 def encode(self):
411 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100412 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800413 'bd_id': self.bd.bd.bd_id,
414 'rd_id': self.rd.rd_id}
415
416
417class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100418 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800419 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100420 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800421 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800422
423 def encode(self):
424 nhs = []
425 for nh in self.nhs:
426 nhs.append(nh.encode())
427 while len(nhs) < 8:
428 nhs.append({})
429 return {'action': self.action,
430 'nh_set': {
431 'hash_mode': self.hash_mode,
432 'n_nhs': len(self.nhs),
433 'nhs': nhs}}
434
435
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800436class VppGbpContract(VppObject):
437 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200438 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800439 """
440
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800441 def __init__(self, test, src_epg, dst_epg, acl_index,
442 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800443 self._test = test
444 self.acl_index = acl_index
445 self.src_epg = src_epg
446 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800447 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800448 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800449
450 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800451 rules = []
452 for r in self.rules:
453 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800454 self._test.vapi.gbp_contract_add_del(
455 1,
456 self.src_epg,
457 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800458 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800459 rules,
460 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800461 self._test.registry.register(self, self._test.logger)
462
463 def remove_vpp_config(self):
464 self._test.vapi.gbp_contract_add_del(
465 0,
466 self.src_epg,
467 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800468 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800469 [], [])
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800470
471 def __str__(self):
472 return self.object_id()
473
474 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700475 return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800476 self.dst_epg,
477 self.acl_index)
478
479 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700480 cs = self._test.vapi.gbp_contract_dump()
481 for c in cs:
482 if c.contract.src_epg == self.src_epg \
483 and c.contract.dst_epg == self.dst_epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800484 return True
485 return False
486
487
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700488class VppGbpVxlanTunnel(VppInterface):
489 """
490 GBP VXLAN tunnel
491 """
492
493 def __init__(self, test, vni, bd_rd_id, mode):
494 super(VppGbpVxlanTunnel, self).__init__(test)
495 self._test = test
496 self.vni = vni
497 self.bd_rd_id = bd_rd_id
498 self.mode = mode
499
500 def add_vpp_config(self):
501 r = self._test.vapi.gbp_vxlan_tunnel_add(
502 self.vni,
503 self.bd_rd_id,
504 self.mode)
505 self.set_sw_if_index(r.sw_if_index)
506 self._test.registry.register(self, self._test.logger)
507
508 def remove_vpp_config(self):
509 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
510
511 def __str__(self):
512 return self.object_id()
513
514 def object_id(self):
515 return "gbp-vxlan:%d" % (self.vni)
516
517 def query_vpp_config(self):
518 return find_gbp_vxlan(self._test, self.vni)
519
520
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200521class VppGbpAcl(VppObject):
522 """
523 GBP Acl
524 """
525
526 def __init__(self, test):
527 self._test = test
528 self.acl_index = 4294967295
529
530 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
531 s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
532 sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
533 dport_from=0, dport_to=65535):
534 if proto == -1 or proto == 0:
535 sport_to = 0
536 dport_to = sport_to
537 elif proto == 1 or proto == 58:
538 sport_to = 255
539 dport_to = sport_to
540 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
541 'srcport_or_icmptype_first': sport_from,
542 'srcport_or_icmptype_last': sport_to,
543 'src_ip_prefix_len': s_prefix,
544 'src_ip_addr': s_ip,
545 'dstport_or_icmpcode_first': dport_from,
546 'dstport_or_icmpcode_last': dport_to,
547 'dst_ip_prefix_len': d_prefix,
548 'dst_ip_addr': d_ip})
549 return rule
550
551 def add_vpp_config(self, rules):
552
553 reply = self._test.vapi.acl_add_replace(self.acl_index,
554 r=rules,
555 tag='GBPTest')
556 self.acl_index = reply.acl_index
557 return self.acl_index
558
559 def remove_vpp_config(self):
560 self._test.vapi.acl_del(self.acl_index)
561
562 def __str__(self):
563 return self.object_id()
564
565 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700566 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200567
568 def query_vpp_config(self):
569 cs = self._test.vapi.acl_dump()
570 for c in cs:
571 if c.acl_index == self.acl_index:
572 return True
573 return False
574
575
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800576class TestGBP(VppTestCase):
577 """ GBP Test Case """
578
579 def setUp(self):
580 super(TestGBP, self).setUp()
581
Neale Ranns25b04942018-04-04 09:34:50 -0700582 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700583 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700584
Ole Troan8006c6a2018-12-17 12:02:26 +0100585 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800586
587 for i in self.pg_interfaces:
588 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700589 for i in self.lo_interfaces:
590 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800591
592 def tearDown(self):
593 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700594 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800595
596 super(TestGBP, self).tearDown()
597
Neale Ranns25b04942018-04-04 09:34:50 -0700598 def send_and_expect_bridged(self, src, tx, dst):
599 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800600
Neale Ranns25b04942018-04-04 09:34:50 -0700601 for r in rx:
602 self.assertEqual(r[Ether].src, tx[0][Ether].src)
603 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
604 self.assertEqual(r[IP].src, tx[0][IP].src)
605 self.assertEqual(r[IP].dst, tx[0][IP].dst)
606 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800607
Neale Ranns25b04942018-04-04 09:34:50 -0700608 def send_and_expect_bridged6(self, src, tx, dst):
609 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800610
Neale Ranns25b04942018-04-04 09:34:50 -0700611 for r in rx:
612 self.assertEqual(r[Ether].src, tx[0][Ether].src)
613 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
614 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
615 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
616 return rx
617
618 def send_and_expect_routed(self, src, tx, dst, src_mac):
619 rx = self.send_and_expect(src, tx, dst)
620
621 for r in rx:
622 self.assertEqual(r[Ether].src, src_mac)
623 self.assertEqual(r[Ether].dst, dst.remote_mac)
624 self.assertEqual(r[IP].src, tx[0][IP].src)
625 self.assertEqual(r[IP].dst, tx[0][IP].dst)
626 return rx
627
628 def send_and_expect_natted(self, src, tx, dst, src_ip):
629 rx = self.send_and_expect(src, tx, dst)
630
631 for r in rx:
632 self.assertEqual(r[Ether].src, tx[0][Ether].src)
633 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
634 self.assertEqual(r[IP].src, src_ip)
635 self.assertEqual(r[IP].dst, tx[0][IP].dst)
636 return rx
637
Neale Ranns4a6d0232018-04-24 07:45:33 -0700638 def send_and_expect_natted6(self, src, tx, dst, src_ip):
639 rx = self.send_and_expect(src, tx, dst)
640
641 for r in rx:
642 self.assertEqual(r[Ether].src, tx[0][Ether].src)
643 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
644 self.assertEqual(r[IPv6].src, src_ip)
645 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
646 return rx
647
Neale Ranns25b04942018-04-04 09:34:50 -0700648 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
649 rx = self.send_and_expect(src, tx, dst)
650
651 for r in rx:
652 self.assertEqual(r[Ether].src, tx[0][Ether].src)
653 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
654 self.assertEqual(r[IP].dst, dst_ip)
655 self.assertEqual(r[IP].src, tx[0][IP].src)
656 return rx
657
Neale Ranns4a6d0232018-04-24 07:45:33 -0700658 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
659 rx = self.send_and_expect(src, tx, dst)
660
661 for r in rx:
662 self.assertEqual(r[Ether].src, tx[0][Ether].src)
663 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
664 self.assertEqual(r[IPv6].dst, dst_ip)
665 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
666 return rx
667
Neale Ranns25b04942018-04-04 09:34:50 -0700668 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
669 rx = self.send_and_expect(src, tx, dst)
670
671 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100672 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700673 self.assertEqual(r[Ether].dst, dst.remote_mac)
674 self.assertEqual(r[IP].dst, dst_ip)
675 self.assertEqual(r[IP].src, src_ip)
676 return rx
677
Neale Ranns4a6d0232018-04-24 07:45:33 -0700678 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
679 rx = self.send_and_expect(src, tx, dst)
680
681 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100682 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700683 self.assertEqual(r[Ether].dst, dst.remote_mac)
684 self.assertEqual(r[IPv6].dst, dst_ip)
685 self.assertEqual(r[IPv6].src, src_ip)
686 return rx
687
Neale Ranns25b04942018-04-04 09:34:50 -0700688 def test_gbp(self):
689 """ Group Based Policy """
690
Neale Rannsb6a47952018-11-21 05:44:35 -0800691 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
692
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800693 #
Neale Ranns25b04942018-04-04 09:34:50 -0700694 # Bridge Domains
695 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700696 bd1 = VppBridgeDomain(self, 1)
697 bd2 = VppBridgeDomain(self, 2)
698 bd20 = VppBridgeDomain(self, 20)
699
700 bd1.add_vpp_config()
701 bd2.add_vpp_config()
702 bd20.add_vpp_config()
703
704 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
705 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
706 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
707
708 gbd1.add_vpp_config()
709 gbd2.add_vpp_config()
710 gbd20.add_vpp_config()
711
712 #
713 # Route Domains
714 #
715 gt4 = VppIpTable(self, 0)
716 gt4.add_vpp_config()
717 gt6 = VppIpTable(self, 0, is_ip6=True)
718 gt6.add_vpp_config()
719 nt4 = VppIpTable(self, 20)
720 nt4.add_vpp_config()
721 nt6 = VppIpTable(self, 20, is_ip6=True)
722 nt6.add_vpp_config()
723
724 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
725 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
726
727 rd0.add_vpp_config()
728 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700729
730 #
731 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700732 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
733 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700734 epgs = [VppGbpEndpointGroup(self, 220, rd0, gbd1, self.pg4,
Neale Rannsc0a93142018-09-05 15:42:26 -0700735 self.loop0,
736 "10.0.0.128",
737 "2001:10::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700738 VppGbpEndpointGroup(self, 221, rd0, gbd1, self.pg5,
Neale Rannsc0a93142018-09-05 15:42:26 -0700739 self.loop0,
740 "10.0.1.128",
741 "2001:10:1::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700742 VppGbpEndpointGroup(self, 222, rd0, gbd2, self.pg6,
Neale Rannsc0a93142018-09-05 15:42:26 -0700743 self.loop1,
744 "10.0.2.128",
745 "2001:10:2::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700746 VppGbpEndpointGroup(self, 333, rd20, gbd20, self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -0700747 self.loop2,
748 "11.0.0.128",
749 "3001::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700750 VppGbpEndpointGroup(self, 444, rd20, gbd20, self.pg8,
Neale Rannsc0a93142018-09-05 15:42:26 -0700751 self.loop2,
752 "11.0.0.129",
753 "3001::129")]
754 recircs = [VppGbpRecirc(self, epgs[0],
755 self.loop3),
756 VppGbpRecirc(self, epgs[1],
757 self.loop4),
758 VppGbpRecirc(self, epgs[2],
759 self.loop5),
760 VppGbpRecirc(self, epgs[3],
761 self.loop6, is_ext=True),
762 VppGbpRecirc(self, epgs[4],
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700763 self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700764
765 epg_nat = epgs[3]
766 recirc_nat = recircs[3]
767
768 #
769 # 4 end-points, 2 in the same subnet, 3 in the same BD
770 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700771 eps = [VppGbpEndpoint(self, self.pg0,
772 epgs[0], recircs[0],
773 "10.0.0.1", "11.0.0.1",
774 "2001:10::1", "3001::1"),
775 VppGbpEndpoint(self, self.pg1,
776 epgs[0], recircs[0],
777 "10.0.0.2", "11.0.0.2",
778 "2001:10::2", "3001::2"),
779 VppGbpEndpoint(self, self.pg2,
780 epgs[1], recircs[1],
781 "10.0.1.1", "11.0.0.3",
782 "2001:10:1::1", "3001::3"),
783 VppGbpEndpoint(self, self.pg3,
784 epgs[2], recircs[2],
785 "10.0.2.1", "11.0.0.4",
786 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700787
788 #
789 # Config related to each of the EPGs
790 #
791 for epg in epgs:
792 # IP config on the BVI interfaces
793 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700794 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
795 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
796 self.vapi.sw_interface_set_mac_address(
797 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100798 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700799
800 # The BVIs are NAT inside interfaces
801 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
802 is_inside=1,
803 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700804 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
805 is_inside=1,
806 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700807
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700808 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
809 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
810 if_ip4.add_vpp_config()
811 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700812
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700813 # EPG uplink interfaces in the RD
814 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
815 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700816
817 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700818 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100819 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700820 epg.bvi_ip4)
821 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100822 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700823 epg.bvi_ip6)
824 epg.bd_arp_ip4.add_vpp_config()
825 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700826
827 # EPG in VPP
828 epg.add_vpp_config()
829
830 for recirc in recircs:
831 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700832 VppIpInterfaceBind(self, recirc.recirc,
833 recirc.epg.rd.t4).add_vpp_config()
834 VppIpInterfaceBind(self, recirc.recirc,
835 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700836
Neale Ranns4a6d0232018-04-24 07:45:33 -0700837 self.vapi.nat44_interface_add_del_feature(
838 recirc.recirc.sw_if_index,
839 is_inside=0,
840 is_add=1)
841 self.vapi.nat66_add_del_interface(
842 recirc.recirc.sw_if_index,
843 is_inside=0,
844 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700845
846 recirc.add_vpp_config()
847
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700848 for recirc in recircs:
849 self.assertTrue(find_bridge_domain_port(self,
850 recirc.epg.bd.bd.bd_id,
851 recirc.recirc.sw_if_index))
852
Neale Ranns25b04942018-04-04 09:34:50 -0700853 for ep in eps:
854 self.pg_enable_capture(self.pg_interfaces)
855 self.pg_start()
856 #
857 # routes to the endpoints. We need these since there are no
858 # adj-fibs due to the fact the the BVI address has /32 and
859 # the subnet is not attached.
860 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700861 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700862 # Add static mappings for each EP from the 10/8 to 11/8 network
863 if ip.af == AF_INET:
864 self.vapi.nat44_add_del_static_mapping(ip.bytes,
865 fip.bytes,
866 vrf_id=0,
867 addr_only=1)
868 else:
869 self.vapi.nat66_add_del_static_mapping(ip.bytes,
870 fip.bytes,
871 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700872
Neale Ranns25b04942018-04-04 09:34:50 -0700873 # VPP EP create ...
874 ep.add_vpp_config()
875
Neale Rannsc0a93142018-09-05 15:42:26 -0700876 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700877
Neale Rannsc0a93142018-09-05 15:42:26 -0700878 # ... results in a Gratuitous ARP/ND on the EPG's uplink
879 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
880
881 for ii, ip in enumerate(ep.ips):
882 p = rx[ii]
883
884 if ip.is_ip6:
885 self.assertTrue(p.haslayer(ICMPv6ND_NA))
886 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
887 else:
888 self.assertTrue(p.haslayer(ARP))
889 self.assertEqual(p[ARP].psrc, ip.address)
890 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700891
892 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700893 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700894 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
895 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700896
Neale Rannsc0a93142018-09-05 15:42:26 -0700897 # floating IPs route via EPG recirc
898 r = VppIpRoute(self, fip.address, fip.length,
899 [VppRoutePath(fip.address,
900 ep.recirc.recirc.sw_if_index,
901 is_dvr=1,
902 proto=fip.dpo_proto)],
903 table_id=20,
904 is_ip6=fip.is_ip6)
905 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700906
907 # L2 FIB entries in the NAT EPG BD to bridge the packets from
908 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700909 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
910 ep.recirc.recirc, bvi_mac=0)
911 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700912
913 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700914 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700915 #
916 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
917 src=self.pg0.remote_mac) /
918 ARP(op="who-has",
919 hwdst="ff:ff:ff:ff:ff:ff",
920 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700921 pdst="10.0.0.88",
922 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700923
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700924 self.vapi.cli("clear trace")
925 self.pg0.add_stream(pkt_arp)
926
927 self.pg_enable_capture(self.pg_interfaces)
928 self.pg_start()
929
930 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700931
932 #
933 # ARP/ND packets get a response
934 #
935 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
936 src=self.pg0.remote_mac) /
937 ARP(op="who-has",
938 hwdst="ff:ff:ff:ff:ff:ff",
939 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700940 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700941 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700942
943 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
944
Neale Rannsc0a93142018-09-05 15:42:26 -0700945 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700946 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700947 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
948 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700949 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700950 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700951 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
952 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
953
954 #
955 # broadcast packets are flooded
956 #
957 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
958 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700959 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700960 UDP(sport=1234, dport=1234) /
961 Raw('\xa5' * 100))
962
963 self.vapi.cli("clear trace")
964 self.pg0.add_stream(pkt_bcast)
965
966 self.pg_enable_capture(self.pg_interfaces)
967 self.pg_start()
968
969 rxd = eps[1].itf.get_capture(1)
970 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
971 rxd = epgs[0].uplink.get_capture(1)
972 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
973
974 #
975 # packets to non-local L3 destinations dropped
976 #
977 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100978 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700979 IP(src=eps[0].ip4.address,
980 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700981 UDP(sport=1234, dport=1234) /
982 Raw('\xa5' * 100))
983 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100984 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700985 IP(src=eps[0].ip4.address,
986 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700987 UDP(sport=1234, dport=1234) /
988 Raw('\xa5' * 100))
989
990 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
991
992 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100993 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700994 IPv6(src=eps[0].ip6.address,
995 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700996 UDP(sport=1234, dport=1234) /
997 Raw('\xa5' * 100))
998 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
999
1000 #
1001 # Add the subnet routes
1002 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001003 s41 = VppGbpSubnet(
1004 self, rd0, "10.0.0.0", 24,
1005 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1006 s42 = VppGbpSubnet(
1007 self, rd0, "10.0.1.0", 24,
1008 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1009 s43 = VppGbpSubnet(
1010 self, rd0, "10.0.2.0", 24,
1011 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1012 s61 = VppGbpSubnet(
1013 self, rd0, "2001:10::1", 64,
1014 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1015 s62 = VppGbpSubnet(
1016 self, rd0, "2001:10:1::1", 64,
1017 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1018 s63 = VppGbpSubnet(
1019 self, rd0, "2001:10:2::1", 64,
1020 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001021 s41.add_vpp_config()
1022 s42.add_vpp_config()
1023 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001024 s61.add_vpp_config()
1025 s62.add_vpp_config()
1026 s63.add_vpp_config()
1027
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001028 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001029 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001030 eps[0].epg.uplink)
1031 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001032 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001033 eps[0].epg.uplink)
1034 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001035 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001036 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001037
1038 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1039 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1040 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1041 self.logger.info(self.vapi.cli("sh gbp recirc"))
1042 self.logger.info(self.vapi.cli("sh int"))
1043 self.logger.info(self.vapi.cli("sh int addr"))
1044 self.logger.info(self.vapi.cli("sh int feat loop6"))
1045 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1046 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001047 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001048
1049 #
1050 # Packet destined to unknown unicast is sent on the epg uplink ...
1051 #
1052 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1053 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001054 IP(src=eps[0].ip4.address,
1055 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001056 UDP(sport=1234, dport=1234) /
1057 Raw('\xa5' * 100))
1058
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001059 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001060 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001061 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001062 # ... and nowhere else
1063 self.pg1.get_capture(0, timeout=0.1)
1064 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1065
1066 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1067 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001068 IP(src=eps[0].ip4.address,
1069 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001070 UDP(sport=1234, dport=1234) /
1071 Raw('\xa5' * 100))
1072
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001073 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001074 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001075 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001076
1077 #
1078 # Packets from the uplink are forwarded in the absence of a contract
1079 #
1080 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1081 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001082 IP(src=eps[0].ip4.address,
1083 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001084 UDP(sport=1234, dport=1234) /
1085 Raw('\xa5' * 100))
1086
1087 self.send_and_expect_bridged(self.pg4,
1088 pkt_intra_epg_220_from_uplink * 65,
1089 self.pg0)
1090
1091 #
1092 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001093 # can communicate
1094 #
1095 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001096 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001097 IP(src=eps[0].ip4.address,
1098 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001099 UDP(sport=1234, dport=1234) /
1100 Raw('\xa5' * 100))
1101
Neale Ranns25b04942018-04-04 09:34:50 -07001102 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001103
1104 #
1105 # in the abscense of policy, endpoints in the different EPG
1106 # cannot communicate
1107 #
1108 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001109 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001110 IP(src=eps[0].ip4.address,
1111 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001112 UDP(sport=1234, dport=1234) /
1113 Raw('\xa5' * 100))
1114 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001115 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001116 IP(src=eps[2].ip4.address,
1117 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001118 UDP(sport=1234, dport=1234) /
1119 Raw('\xa5' * 100))
1120 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001121 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001122 IP(src=eps[0].ip4.address,
1123 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001124 UDP(sport=1234, dport=1234) /
1125 Raw('\xa5' * 100))
1126
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001127 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001128 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001129 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001130 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001131
1132 #
1133 # A uni-directional contract from EPG 220 -> 221
1134 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001135 acl = VppGbpAcl(self)
1136 rule = acl.create_rule(permit_deny=1, proto=17)
1137 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1138 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001139 c1 = VppGbpContract(
1140 self, 220, 221, acl_index,
1141 [VppGbpContractRule(
1142 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1143 []),
1144 VppGbpContractRule(
1145 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001146 [])],
1147 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001148 c1.add_vpp_config()
1149
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001150 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001151 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001152 eps[2].itf)
1153 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001154 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001155
1156 #
1157 # contract for the return direction
1158 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001159 c2 = VppGbpContract(
1160 self, 221, 220, acl_index,
1161 [VppGbpContractRule(
1162 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1163 []),
1164 VppGbpContractRule(
1165 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001166 [])],
1167 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001168 c2.add_vpp_config()
1169
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001170 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001171 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001172 eps[2].itf)
1173 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001174 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001175 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001176
1177 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001178 # the contract does not allow non-IP
1179 #
1180 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1181 dst=self.pg2.remote_mac) /
1182 ARP())
1183 self.send_and_assert_no_replies(eps[0].itf,
1184 pkt_non_ip_inter_epg_220_to_221 * 17)
1185
1186 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001187 # check that inter group is still disabled for the groups
1188 # not in the contract.
1189 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001190 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001191 pkt_inter_epg_220_to_222 * 65)
1192
Neale Ranns25b04942018-04-04 09:34:50 -07001193 #
1194 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1195 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001196 c3 = VppGbpContract(
1197 self, 220, 222, acl_index,
1198 [VppGbpContractRule(
1199 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1200 []),
1201 VppGbpContractRule(
1202 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001203 [])],
1204 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001205 c3.add_vpp_config()
1206
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001207 self.logger.info(self.vapi.cli("sh gbp contract"))
1208
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001209 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001210 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001211 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001212 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001213
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001214 #
1215 # remove both contracts, traffic stops in both directions
1216 #
1217 c2.remove_vpp_config()
1218 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001219 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001220 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001221
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001222 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001223 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001224 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001225 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001226 self.send_and_expect_bridged(eps[0].itf,
1227 pkt_intra_epg * 65,
1228 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001229
1230 #
Neale Ranns25b04942018-04-04 09:34:50 -07001231 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001232 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001233
Neale Ranns25b04942018-04-04 09:34:50 -07001234 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001235 se1 = VppGbpSubnet(
1236 self, rd0, "0.0.0.0", 0,
1237 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1238 sw_if_index=recirc_nat.recirc.sw_if_index,
1239 epg=epg_nat.epg)
1240 se2 = VppGbpSubnet(
1241 self, rd0, "11.0.0.0", 8,
1242 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1243 sw_if_index=recirc_nat.recirc.sw_if_index,
1244 epg=epg_nat.epg)
1245 se16 = VppGbpSubnet(
1246 self, rd0, "::", 0,
1247 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1248 sw_if_index=recirc_nat.recirc.sw_if_index,
1249 epg=epg_nat.epg)
Neale Ranns25b04942018-04-04 09:34:50 -07001250 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001251 se3 = VppGbpSubnet(
1252 self, rd20, "0.0.0.0", 0,
1253 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1254 sw_if_index=epg_nat.uplink.sw_if_index,
1255 epg=epg_nat.epg)
1256 se36 = VppGbpSubnet(
1257 self, rd20, "::", 0,
1258 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1259 sw_if_index=epg_nat.uplink.sw_if_index,
1260 epg=epg_nat.epg)
1261 se4 = VppGbpSubnet(
1262 self, rd20, "11.0.0.0", 8,
1263 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1264 sw_if_index=epg_nat.uplink.sw_if_index,
1265 epg=epg_nat.epg)
1266 se1.add_vpp_config()
1267 se2.add_vpp_config()
1268 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001269 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001270 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001271 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001272
Neale Ranns25b04942018-04-04 09:34:50 -07001273 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1274 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001275 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1276 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001277 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001278
Neale Ranns4a6d0232018-04-24 07:45:33 -07001279 #
1280 # From an EP to an outside addess: IN2OUT
1281 #
Neale Ranns25b04942018-04-04 09:34:50 -07001282 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001283 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001284 IP(src=eps[0].ip4.address,
1285 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001286 UDP(sport=1234, dport=1234) /
1287 Raw('\xa5' * 100))
1288
1289 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001290 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001291 pkt_inter_epg_220_to_global * 65)
1292
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001293 acl2 = VppGbpAcl(self)
1294 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1295 sport_to=1234, dport_from=1234, dport_to=1234)
1296 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1297 sport_from=1234, sport_to=1234,
1298 dport_from=1234, dport_to=1234)
1299
1300 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001301 c4 = VppGbpContract(
1302 self, 220, 333, acl_index2,
1303 [VppGbpContractRule(
1304 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1305 []),
1306 VppGbpContractRule(
1307 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001308 [])],
1309 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001310 c4.add_vpp_config()
1311
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001312 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001313 pkt_inter_epg_220_to_global * 65,
1314 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001315 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001316
Neale Ranns4a6d0232018-04-24 07:45:33 -07001317 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001318 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001319 IPv6(src=eps[0].ip6.address,
1320 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001321 UDP(sport=1234, dport=1234) /
1322 Raw('\xa5' * 100))
1323
1324 self.send_and_expect_natted6(self.pg0,
1325 pkt_inter_epg_220_to_global * 65,
1326 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001327 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001328
1329 #
1330 # From a global address to an EP: OUT2IN
1331 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001332 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001333 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001334 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001335 src="1.1.1.1") /
1336 UDP(sport=1234, dport=1234) /
1337 Raw('\xa5' * 100))
1338
1339 self.send_and_assert_no_replies(self.pg7,
1340 pkt_inter_epg_220_from_global * 65)
1341
Neale Ranns13a08cc2018-11-07 09:25:54 -08001342 c5 = VppGbpContract(
1343 self, 333, 220, acl_index2,
1344 [VppGbpContractRule(
1345 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1346 []),
1347 VppGbpContractRule(
1348 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001349 [])],
1350 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001351 c5.add_vpp_config()
1352
1353 self.send_and_expect_unnatted(self.pg7,
1354 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001355 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001356 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001357
Ole Troan8006c6a2018-12-17 12:02:26 +01001358 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001359 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001360 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001361 src="6001::1") /
1362 UDP(sport=1234, dport=1234) /
1363 Raw('\xa5' * 100))
1364
1365 self.send_and_expect_unnatted6(self.pg7,
1366 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001367 eps[0].itf,
1368 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001369
1370 #
1371 # From a local VM to another local VM using resp. public addresses:
1372 # IN2OUT2IN
1373 #
Neale Ranns25b04942018-04-04 09:34:50 -07001374 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001375 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001376 IP(src=eps[0].ip4.address,
1377 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001378 UDP(sport=1234, dport=1234) /
1379 Raw('\xa5' * 100))
1380
Neale Ranns4a6d0232018-04-24 07:45:33 -07001381 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001382 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001383 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001384 eps[0].fip4.address,
1385 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001386
Neale Rannsc0a93142018-09-05 15:42:26 -07001387 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001388 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001389 IPv6(src=eps[0].ip6.address,
1390 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001391 UDP(sport=1234, dport=1234) /
1392 Raw('\xa5' * 100))
1393
Neale Rannsc0a93142018-09-05 15:42:26 -07001394 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001395 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001396 eps[1].itf,
1397 eps[0].fip6.address,
1398 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001399
1400 #
Neale Ranns25b04942018-04-04 09:34:50 -07001401 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001402 #
Neale Ranns25b04942018-04-04 09:34:50 -07001403 for ep in eps:
1404 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001405 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1406 ep.fip4.bytes,
1407 vrf_id=0,
1408 addr_only=1,
1409 is_add=0)
1410 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1411 ep.fip6.bytes,
1412 vrf_id=0,
1413 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001414
Neale Ranns25b04942018-04-04 09:34:50 -07001415 for epg in epgs:
1416 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001417 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001418 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1419 is_inside=1,
1420 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001421 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1422 is_inside=1,
1423 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001424
Neale Ranns25b04942018-04-04 09:34:50 -07001425 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001426 self.vapi.nat44_interface_add_del_feature(
1427 recirc.recirc.sw_if_index,
1428 is_inside=0,
1429 is_add=0)
1430 self.vapi.nat66_add_del_interface(
1431 recirc.recirc.sw_if_index,
1432 is_inside=0,
1433 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001434
Neale Ranns774356a2018-11-29 12:02:16 +00001435 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1436 n_tries=100, s_time=1):
1437 while (n_tries):
1438 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1439 return True
1440 n_tries = n_tries - 1
1441 self.sleep(s_time)
1442 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1443 return False
1444
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001445 def test_gbp_learn_l2(self):
1446 """ GBP L2 Endpoint Learning """
1447
Neale Rannsb6a47952018-11-21 05:44:35 -08001448 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001449 learnt = [{'mac': '00:00:11:11:11:01',
1450 'ip': '10.0.0.1',
1451 'ip6': '2001:10::2'},
1452 {'mac': '00:00:11:11:11:02',
1453 'ip': '10.0.0.2',
1454 'ip6': '2001:10::3'}]
1455
1456 #
1457 # lower the inactive threshold so these tests pass in a
1458 # reasonable amount of time
1459 #
Neale Ranns00a469d2018-12-20 06:12:19 -08001460 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001461
1462 #
1463 # IP tables
1464 #
1465 gt4 = VppIpTable(self, 1)
1466 gt4.add_vpp_config()
1467 gt6 = VppIpTable(self, 1, is_ip6=True)
1468 gt6.add_vpp_config()
1469
1470 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1471 rd1.add_vpp_config()
1472
1473 #
1474 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1475 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1476 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1477 #
1478 self.pg2.config_ip4()
1479 self.pg2.resolve_arp()
1480 self.pg2.generate_remote_hosts(4)
1481 self.pg2.configure_ipv4_neighbors()
1482 self.pg3.config_ip4()
1483 self.pg3.resolve_arp()
1484 self.pg4.config_ip4()
1485 self.pg4.resolve_arp()
1486
1487 #
1488 # a GBP bridge domain with a BVI and a UU-flood interface
1489 #
1490 bd1 = VppBridgeDomain(self, 1)
1491 bd1.add_vpp_config()
1492 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
1493 gbd1.add_vpp_config()
1494
1495 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1496 self.logger.info(self.vapi.cli("sh gbp bridge"))
1497
1498 # ... and has a /32 applied
1499 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1500 ip_addr.add_vpp_config()
1501
1502 #
1503 # The Endpoint-group in which we are learning endpoints
1504 #
1505 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1506 None, self.loop0,
1507 "10.0.0.128",
1508 "2001:10::128")
1509 epg_220.add_vpp_config()
1510 epg_330 = VppGbpEndpointGroup(self, 330, rd1, gbd1,
1511 None, self.loop1,
1512 "10.0.1.128",
1513 "2001:11::128")
1514 epg_330.add_vpp_config()
1515
1516 #
1517 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1518 # leanring enabled
1519 #
1520 vx_tun_l2_1 = VppGbpVxlanTunnel(
1521 self, 99, bd1.bd_id,
1522 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1523 vx_tun_l2_1.add_vpp_config()
1524
1525 #
1526 # A static endpoint that the learnt endpoints are trying to
1527 # talk to
1528 #
1529 ep = VppGbpEndpoint(self, self.pg0,
1530 epg_220, None,
1531 "10.0.0.127", "11.0.0.127",
1532 "2001:10::1", "3001::1")
1533 ep.add_vpp_config()
1534
1535 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1536
1537 # a packet with an sclass from an unknwon EPG
1538 p = (Ether(src=self.pg2.remote_mac,
1539 dst=self.pg2.local_mac) /
1540 IP(src=self.pg2.remote_hosts[0].ip4,
1541 dst=self.pg2.local_ip4) /
1542 UDP(sport=1234, dport=48879) /
1543 VXLAN(vni=99, gpid=88, flags=0x88) /
1544 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1545 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1546 UDP(sport=1234, dport=1234) /
1547 Raw('\xa5' * 100))
1548
1549 self.send_and_assert_no_replies(self.pg2, p)
1550
1551 #
1552 # we should not have learnt a new tunnel endpoint, since
1553 # the EPG was not learnt.
1554 #
1555 self.assertEqual(INDEX_INVALID,
1556 find_vxlan_gbp_tunnel(self,
1557 self.pg2.local_ip4,
1558 self.pg2.remote_hosts[0].ip4,
1559 99))
1560
1561 # epg is not learnt, becasue the EPG is unknwon
1562 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1563
1564 for ii, l in enumerate(learnt):
1565 # a packet with an sclass from a knwon EPG
1566 # arriving on an unknown TEP
1567 p = (Ether(src=self.pg2.remote_mac,
1568 dst=self.pg2.local_mac) /
1569 IP(src=self.pg2.remote_hosts[1].ip4,
1570 dst=self.pg2.local_ip4) /
1571 UDP(sport=1234, dport=48879) /
1572 VXLAN(vni=99, gpid=220, flags=0x88) /
1573 Ether(src=l['mac'], dst=ep.mac) /
1574 IP(src=l['ip'], dst=ep.ip4.address) /
1575 UDP(sport=1234, dport=1234) /
1576 Raw('\xa5' * 100))
1577
1578 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1579
1580 # the new TEP
1581 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1582 self,
1583 self.pg2.local_ip4,
1584 self.pg2.remote_hosts[1].ip4,
1585 99)
1586 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1587
1588 #
1589 # the EP is learnt via the learnt TEP
1590 # both from its MAC and its IP
1591 #
1592 self.assertTrue(find_gbp_endpoint(self,
1593 vx_tun_l2_1.sw_if_index,
1594 mac=l['mac']))
1595 self.assertTrue(find_gbp_endpoint(self,
1596 vx_tun_l2_1.sw_if_index,
1597 ip=l['ip']))
1598
1599 self.logger.info(self.vapi.cli("show gbp endpoint"))
1600 self.logger.info(self.vapi.cli("show gbp vxlan"))
1601 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1602
1603 #
1604 # If we sleep for the threshold time, the learnt endpoints should
1605 # age out
1606 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001607 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001608 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1609 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001610
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001611 #
1612 # repeat. the do not learn bit is set so the EPs are not learnt
1613 #
1614 for l in learnt:
1615 # a packet with an sclass from a knwon EPG
1616 p = (Ether(src=self.pg2.remote_mac,
1617 dst=self.pg2.local_mac) /
1618 IP(src=self.pg2.remote_hosts[1].ip4,
1619 dst=self.pg2.local_ip4) /
1620 UDP(sport=1234, dport=48879) /
1621 VXLAN(vni=99, gpid=220, flags=0x88, gpflags="D") /
1622 Ether(src=l['mac'], dst=ep.mac) /
1623 IP(src=l['ip'], dst=ep.ip4.address) /
1624 UDP(sport=1234, dport=1234) /
1625 Raw('\xa5' * 100))
1626
1627 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1628
1629 for l in learnt:
1630 self.assertFalse(find_gbp_endpoint(self,
1631 vx_tun_l2_1.sw_if_index,
1632 mac=l['mac']))
1633
1634 #
1635 # repeat
1636 #
1637 for l in learnt:
1638 # a packet with an sclass from a knwon EPG
1639 p = (Ether(src=self.pg2.remote_mac,
1640 dst=self.pg2.local_mac) /
1641 IP(src=self.pg2.remote_hosts[1].ip4,
1642 dst=self.pg2.local_ip4) /
1643 UDP(sport=1234, dport=48879) /
1644 VXLAN(vni=99, gpid=220, flags=0x88) /
1645 Ether(src=l['mac'], dst=ep.mac) /
1646 IP(src=l['ip'], dst=ep.ip4.address) /
1647 UDP(sport=1234, dport=1234) /
1648 Raw('\xa5' * 100))
1649
1650 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1651
1652 self.assertTrue(find_gbp_endpoint(self,
1653 vx_tun_l2_1.sw_if_index,
1654 mac=l['mac']))
1655
1656 #
1657 # Static EP replies to dynamics
1658 #
1659 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1660 for l in learnt:
1661 p = (Ether(src=ep.mac, dst=l['mac']) /
1662 IP(dst=l['ip'], src=ep.ip4.address) /
1663 UDP(sport=1234, dport=1234) /
1664 Raw('\xa5' * 100))
1665
1666 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1667
1668 for rx in rxs:
1669 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1670 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1671 self.assertEqual(rx[UDP].dport, 48879)
1672 # the UDP source port is a random value for hashing
1673 self.assertEqual(rx[VXLAN].gpid, 220)
1674 self.assertEqual(rx[VXLAN].vni, 99)
1675 self.assertTrue(rx[VXLAN].flags.G)
1676 self.assertTrue(rx[VXLAN].flags.Instance)
1677 self.assertTrue(rx[VXLAN].gpflags.A)
1678 self.assertFalse(rx[VXLAN].gpflags.D)
1679
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001680 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001681 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1682 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001683
1684 #
1685 # repeat in the other EPG
1686 # there's no contract between 220 and 330, but the A-bit is set
1687 # so the packet is cleared for delivery
1688 #
1689 for l in learnt:
1690 # a packet with an sclass from a knwon EPG
1691 p = (Ether(src=self.pg2.remote_mac,
1692 dst=self.pg2.local_mac) /
1693 IP(src=self.pg2.remote_hosts[1].ip4,
1694 dst=self.pg2.local_ip4) /
1695 UDP(sport=1234, dport=48879) /
1696 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1697 Ether(src=l['mac'], dst=ep.mac) /
1698 IP(src=l['ip'], dst=ep.ip4.address) /
1699 UDP(sport=1234, dport=1234) /
1700 Raw('\xa5' * 100))
1701
1702 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1703
1704 self.assertTrue(find_gbp_endpoint(self,
1705 vx_tun_l2_1.sw_if_index,
1706 mac=l['mac']))
1707
1708 #
1709 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001710 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001711 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001712 p = (Ether(src=ep.mac, dst=l['mac']) /
1713 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1714 UDP(sport=1234, dport=1234) /
1715 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001716
Neale Ranns13a08cc2018-11-07 09:25:54 -08001717 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001718
1719 #
1720 # refresh the entries after the check for no replies above
1721 #
1722 for l in learnt:
1723 # a packet with an sclass from a knwon EPG
1724 p = (Ether(src=self.pg2.remote_mac,
1725 dst=self.pg2.local_mac) /
1726 IP(src=self.pg2.remote_hosts[1].ip4,
1727 dst=self.pg2.local_ip4) /
1728 UDP(sport=1234, dport=48879) /
1729 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1730 Ether(src=l['mac'], dst=ep.mac) /
1731 IP(src=l['ip'], dst=ep.ip4.address) /
1732 UDP(sport=1234, dport=1234) /
1733 Raw('\xa5' * 100))
1734
1735 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1736
1737 self.assertTrue(find_gbp_endpoint(self,
1738 vx_tun_l2_1.sw_if_index,
1739 mac=l['mac']))
1740
1741 #
1742 # Add the contract so they can talk
1743 #
1744 acl = VppGbpAcl(self)
1745 rule = acl.create_rule(permit_deny=1, proto=17)
1746 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1747 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001748 c1 = VppGbpContract(
1749 self, 220, 330, acl_index,
1750 [VppGbpContractRule(
1751 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1752 []),
1753 VppGbpContractRule(
1754 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001755 [])],
1756 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001757 c1.add_vpp_config()
1758
1759 for l in learnt:
1760 p = (Ether(src=ep.mac, dst=l['mac']) /
1761 IP(dst=l['ip'], src=ep.ip4.address) /
1762 UDP(sport=1234, dport=1234) /
1763 Raw('\xa5' * 100))
1764
1765 self.send_and_expect(self.pg0, [p], self.pg2)
1766
1767 #
1768 # send UU packets from the local EP
1769 #
1770 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1771 self.logger.info(self.vapi.cli("sh gbp bridge"))
1772 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1773 IP(dst="10.0.0.133", src=ep.ip4.address) /
1774 UDP(sport=1234, dport=1234) /
1775 Raw('\xa5' * 100))
1776 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_flood)
1777
1778 #
1779 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1780 #
1781 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1782 "239.1.1.1", 88,
1783 mcast_itf=self.pg4)
1784 tun_bm.add_vpp_config()
1785 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
1786 port_type=L2_PORT_TYPE.NORMAL)
1787 bp_bm.add_vpp_config()
1788
1789 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1790
1791 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1792 IP(dst="10.0.0.133", src=ep.ip4.address) /
1793 UDP(sport=1234, dport=1234) /
1794 Raw('\xa5' * 100))
1795 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1796
1797 #
1798 # Check v6 Endpoints
1799 #
1800 for l in learnt:
1801 # a packet with an sclass from a knwon EPG
1802 p = (Ether(src=self.pg2.remote_mac,
1803 dst=self.pg2.local_mac) /
1804 IP(src=self.pg2.remote_hosts[1].ip4,
1805 dst=self.pg2.local_ip4) /
1806 UDP(sport=1234, dport=48879) /
1807 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1808 Ether(src=l['mac'], dst=ep.mac) /
1809 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1810 UDP(sport=1234, dport=1234) /
1811 Raw('\xa5' * 100))
1812
1813 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1814
1815 self.assertTrue(find_gbp_endpoint(self,
1816 vx_tun_l2_1.sw_if_index,
1817 mac=l['mac']))
1818
1819 #
1820 # L3 Endpoint Learning
1821 # - configured on the bridge's BVI
1822 #
1823
1824 #
1825 # clean up
1826 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001827 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001828 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1829 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001830
1831 self.pg2.unconfig_ip4()
1832 self.pg3.unconfig_ip4()
1833 self.pg4.unconfig_ip4()
1834
1835 self.logger.info(self.vapi.cli("sh int"))
1836 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1837
Neale Rannsc29c0af2018-11-07 04:21:12 -08001838 def test_gbp_learn_vlan_l2(self):
1839 """ GBP L2 Endpoint w/ VLANs"""
1840
Neale Rannsb6a47952018-11-21 05:44:35 -08001841 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001842 learnt = [{'mac': '00:00:11:11:11:01',
1843 'ip': '10.0.0.1',
1844 'ip6': '2001:10::2'},
1845 {'mac': '00:00:11:11:11:02',
1846 'ip': '10.0.0.2',
1847 'ip6': '2001:10::3'}]
1848
1849 #
1850 # lower the inactive threshold so these tests pass in a
1851 # reasonable amount of time
1852 #
Neale Ranns00a469d2018-12-20 06:12:19 -08001853 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001854
1855 #
1856 # IP tables
1857 #
1858 gt4 = VppIpTable(self, 1)
1859 gt4.add_vpp_config()
1860 gt6 = VppIpTable(self, 1, is_ip6=True)
1861 gt6.add_vpp_config()
1862
1863 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1864 rd1.add_vpp_config()
1865
1866 #
1867 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1868 #
1869 self.pg2.config_ip4()
1870 self.pg2.resolve_arp()
1871 self.pg2.generate_remote_hosts(4)
1872 self.pg2.configure_ipv4_neighbors()
1873 self.pg3.config_ip4()
1874 self.pg3.resolve_arp()
1875
1876 #
1877 # The EP will be on a vlan sub-interface
1878 #
1879 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1880 vlan_11.admin_up()
1881 self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index,
1882 L2_VTR_OP.L2_POP_1,
1883 11)
1884
1885 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1886 self.pg3.remote_ip4, 116)
1887 bd_uu_fwd.add_vpp_config()
1888
1889 #
1890 # a GBP bridge domain with a BVI and a UU-flood interface
1891 # The BD is marked as do not learn, so no endpoints are ever
1892 # learnt in this BD.
1893 #
1894 bd1 = VppBridgeDomain(self, 1)
1895 bd1.add_vpp_config()
1896 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1897 learn=False)
1898 gbd1.add_vpp_config()
1899
1900 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1901 self.logger.info(self.vapi.cli("sh gbp bridge"))
1902
1903 # ... and has a /32 applied
1904 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1905 ip_addr.add_vpp_config()
1906
1907 #
1908 # The Endpoint-group in which we are learning endpoints
1909 #
1910 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1911 None, self.loop0,
1912 "10.0.0.128",
1913 "2001:10::128")
1914 epg_220.add_vpp_config()
1915
1916 #
1917 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1918 # leanring enabled
1919 #
1920 vx_tun_l2_1 = VppGbpVxlanTunnel(
1921 self, 99, bd1.bd_id,
1922 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1923 vx_tun_l2_1.add_vpp_config()
1924
1925 #
1926 # A static endpoint that the learnt endpoints are trying to
1927 # talk to
1928 #
1929 ep = VppGbpEndpoint(self, vlan_11,
1930 epg_220, None,
1931 "10.0.0.127", "11.0.0.127",
1932 "2001:10::1", "3001::1")
1933 ep.add_vpp_config()
1934
1935 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1936
1937 #
1938 # Send to the static EP
1939 #
1940 for ii, l in enumerate(learnt):
1941 # a packet with an sclass from a knwon EPG
1942 # arriving on an unknown TEP
1943 p = (Ether(src=self.pg2.remote_mac,
1944 dst=self.pg2.local_mac) /
1945 IP(src=self.pg2.remote_hosts[1].ip4,
1946 dst=self.pg2.local_ip4) /
1947 UDP(sport=1234, dport=48879) /
1948 VXLAN(vni=99, gpid=220, flags=0x88) /
1949 Ether(src=l['mac'], dst=ep.mac) /
1950 IP(src=l['ip'], dst=ep.ip4.address) /
1951 UDP(sport=1234, dport=1234) /
1952 Raw('\xa5' * 100))
1953
1954 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
1955
1956 #
1957 # packet to EP has the EP's vlan tag
1958 #
1959 for rx in rxs:
1960 self.assertEqual(rx[Dot1Q].vlan, 11)
1961
1962 #
1963 # the EP is not learnt since the BD setting prevents it
1964 # also no TEP too
1965 #
1966 self.assertFalse(find_gbp_endpoint(self,
1967 vx_tun_l2_1.sw_if_index,
1968 mac=l['mac']))
1969 self.assertEqual(INDEX_INVALID,
1970 find_vxlan_gbp_tunnel(
1971 self,
1972 self.pg2.local_ip4,
1973 self.pg2.remote_hosts[1].ip4,
1974 99))
1975
1976 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1977
1978 #
1979 # static to remotes
1980 # we didn't learn the remotes so they are sent to the UU-fwd
1981 #
1982 for l in learnt:
1983 p = (Ether(src=ep.mac, dst=l['mac']) /
1984 Dot1Q(vlan=11) /
1985 IP(dst=l['ip'], src=ep.ip4.address) /
1986 UDP(sport=1234, dport=1234) /
1987 Raw('\xa5' * 100))
1988
1989 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
1990
1991 for rx in rxs:
1992 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
1993 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
1994 self.assertEqual(rx[UDP].dport, 48879)
1995 # the UDP source port is a random value for hashing
1996 self.assertEqual(rx[VXLAN].gpid, 220)
1997 self.assertEqual(rx[VXLAN].vni, 116)
1998 self.assertTrue(rx[VXLAN].flags.G)
1999 self.assertTrue(rx[VXLAN].flags.Instance)
2000 self.assertFalse(rx[VXLAN].gpflags.A)
2001 self.assertFalse(rx[VXLAN].gpflags.D)
2002
2003 self.pg2.unconfig_ip4()
2004 self.pg3.unconfig_ip4()
2005
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002006 def test_gbp_learn_l3(self):
2007 """ GBP L3 Endpoint Learning """
2008
Neale Ranns13a08cc2018-11-07 09:25:54 -08002009 self.vapi.cli("set logging class gbp debug")
2010
Neale Rannsb6a47952018-11-21 05:44:35 -08002011 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002012 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2013 routed_src_mac = "00:22:bd:f8:19:ff"
2014
2015 learnt = [{'mac': '00:00:11:11:11:02',
2016 'ip': '10.0.1.2',
2017 'ip6': '2001:10::2'},
2018 {'mac': '00:00:11:11:11:03',
2019 'ip': '10.0.1.3',
2020 'ip6': '2001:10::3'}]
2021
2022 #
2023 # lower the inactive threshold so these tests pass in a
2024 # reasonable amount of time
2025 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002026 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002027
2028 #
2029 # IP tables
2030 #
2031 t4 = VppIpTable(self, 1)
2032 t4.add_vpp_config()
2033 t6 = VppIpTable(self, 1, True)
2034 t6.add_vpp_config()
2035
2036 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2037 self.pg4.remote_ip4, 114)
2038 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2039 self.pg4.remote_ip4, 116)
2040 tun_ip4_uu.add_vpp_config()
2041 tun_ip6_uu.add_vpp_config()
2042
2043 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2044 rd1.add_vpp_config()
2045
Ole Troan8006c6a2018-12-17 12:02:26 +01002046 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002047
2048 #
2049 # Bind the BVI to the RD
2050 #
2051 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2052 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2053
2054 #
2055 # Pg2 hosts the vxlan tunnel
2056 # hosts on pg2 to act as TEPs
2057 # pg3 is BD uu-fwd
2058 # pg4 is RD uu-fwd
2059 #
2060 self.pg2.config_ip4()
2061 self.pg2.resolve_arp()
2062 self.pg2.generate_remote_hosts(4)
2063 self.pg2.configure_ipv4_neighbors()
2064 self.pg3.config_ip4()
2065 self.pg3.resolve_arp()
2066 self.pg4.config_ip4()
2067 self.pg4.resolve_arp()
2068
2069 #
2070 # a GBP bridge domain with a BVI and a UU-flood interface
2071 #
2072 bd1 = VppBridgeDomain(self, 1)
2073 bd1.add_vpp_config()
2074 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2075 gbd1.add_vpp_config()
2076
2077 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2078 self.logger.info(self.vapi.cli("sh gbp bridge"))
2079 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002080
2081 # ... and has a /32 and /128 applied
2082 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2083 ip4_addr.add_vpp_config()
2084 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2085 ip6_addr.add_vpp_config()
2086
2087 #
2088 # The Endpoint-group in which we are learning endpoints
2089 #
2090 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2091 None, self.loop0,
2092 "10.0.0.128",
2093 "2001:10::128")
2094 epg_220.add_vpp_config()
2095
2096 #
2097 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2098 # leanring enabled
2099 #
2100 vx_tun_l3 = VppGbpVxlanTunnel(
2101 self, 101, rd1.rd_id,
2102 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2103 vx_tun_l3.add_vpp_config()
2104
2105 #
2106 # A static endpoint that the learnt endpoints are trying to
2107 # talk to
2108 #
2109 ep = VppGbpEndpoint(self, self.pg0,
2110 epg_220, None,
2111 "10.0.0.127", "11.0.0.127",
2112 "2001:10::1", "3001::1")
2113 ep.add_vpp_config()
2114
2115 #
2116 # learn some remote IPv4 EPs
2117 #
2118 for ii, l in enumerate(learnt):
2119 # a packet with an sclass from a knwon EPG
2120 # arriving on an unknown TEP
2121 p = (Ether(src=self.pg2.remote_mac,
2122 dst=self.pg2.local_mac) /
2123 IP(src=self.pg2.remote_hosts[1].ip4,
2124 dst=self.pg2.local_ip4) /
2125 UDP(sport=1234, dport=48879) /
2126 VXLAN(vni=101, gpid=220, flags=0x88) /
2127 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2128 IP(src=l['ip'], dst=ep.ip4.address) /
2129 UDP(sport=1234, dport=1234) /
2130 Raw('\xa5' * 100))
2131
2132 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2133
2134 # the new TEP
2135 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2136 self,
2137 self.pg2.local_ip4,
2138 self.pg2.remote_hosts[1].ip4,
2139 vx_tun_l3.vni)
2140 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2141
2142 # endpoint learnt via the parent GBP-vxlan interface
2143 self.assertTrue(find_gbp_endpoint(self,
2144 vx_tun_l3._sw_if_index,
2145 ip=l['ip']))
2146
2147 #
2148 # Static IPv4 EP replies to learnt
2149 #
2150 for l in learnt:
2151 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2152 IP(dst=l['ip'], src=ep.ip4.address) /
2153 UDP(sport=1234, dport=1234) /
2154 Raw('\xa5' * 100))
2155
2156 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2157
2158 for rx in rxs:
2159 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2160 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2161 self.assertEqual(rx[UDP].dport, 48879)
2162 # the UDP source port is a random value for hashing
2163 self.assertEqual(rx[VXLAN].gpid, 220)
2164 self.assertEqual(rx[VXLAN].vni, 101)
2165 self.assertTrue(rx[VXLAN].flags.G)
2166 self.assertTrue(rx[VXLAN].flags.Instance)
2167 self.assertTrue(rx[VXLAN].gpflags.A)
2168 self.assertFalse(rx[VXLAN].gpflags.D)
2169
2170 inner = rx[VXLAN].payload
2171
2172 self.assertEqual(inner[Ether].src, routed_src_mac)
2173 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2174 self.assertEqual(inner[IP].src, ep.ip4.address)
2175 self.assertEqual(inner[IP].dst, l['ip'])
2176
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002177 for l in learnt:
2178 self.assertFalse(find_gbp_endpoint(self,
2179 tep1_sw_if_index,
2180 ip=l['ip']))
2181
2182 #
2183 # learn some remote IPv6 EPs
2184 #
2185 for ii, l in enumerate(learnt):
2186 # a packet with an sclass from a knwon EPG
2187 # arriving on an unknown TEP
2188 p = (Ether(src=self.pg2.remote_mac,
2189 dst=self.pg2.local_mac) /
2190 IP(src=self.pg2.remote_hosts[1].ip4,
2191 dst=self.pg2.local_ip4) /
2192 UDP(sport=1234, dport=48879) /
2193 VXLAN(vni=101, gpid=220, flags=0x88) /
2194 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2195 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2196 UDP(sport=1234, dport=1234) /
2197 Raw('\xa5' * 100))
2198
2199 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2200
2201 # the new TEP
2202 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2203 self,
2204 self.pg2.local_ip4,
2205 self.pg2.remote_hosts[1].ip4,
2206 vx_tun_l3.vni)
2207 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2208
2209 self.logger.info(self.vapi.cli("show gbp bridge"))
2210 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2211 self.logger.info(self.vapi.cli("show gbp vxlan"))
2212 self.logger.info(self.vapi.cli("show int addr"))
2213
2214 # endpoint learnt via the TEP
2215 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2216
2217 self.logger.info(self.vapi.cli("show gbp endpoint"))
2218 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2219
2220 #
2221 # Static EP replies to learnt
2222 #
2223 for l in learnt:
2224 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2225 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2226 UDP(sport=1234, dport=1234) /
2227 Raw('\xa5' * 100))
2228
2229 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2230
2231 for rx in rxs:
2232 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2233 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2234 self.assertEqual(rx[UDP].dport, 48879)
2235 # the UDP source port is a random value for hashing
2236 self.assertEqual(rx[VXLAN].gpid, 220)
2237 self.assertEqual(rx[VXLAN].vni, 101)
2238 self.assertTrue(rx[VXLAN].flags.G)
2239 self.assertTrue(rx[VXLAN].flags.Instance)
2240 self.assertTrue(rx[VXLAN].gpflags.A)
2241 self.assertFalse(rx[VXLAN].gpflags.D)
2242
2243 inner = rx[VXLAN].payload
2244
2245 self.assertEqual(inner[Ether].src, routed_src_mac)
2246 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2247 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2248 self.assertEqual(inner[IPv6].dst, l['ip6'])
2249
2250 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002251 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002252 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002253
2254 #
2255 # Static sends to unknown EP with no route
2256 #
2257 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2258 IP(dst="10.0.0.99", src=ep.ip4.address) /
2259 UDP(sport=1234, dport=1234) /
2260 Raw('\xa5' * 100))
2261
2262 self.send_and_assert_no_replies(self.pg0, [p])
2263
2264 #
2265 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002266 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002267 #
2268 se_10_24 = VppGbpSubnet(
2269 self, rd1, "10.0.0.0", 24,
2270 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2271 se_10_24.add_vpp_config()
2272
2273 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2274 IP(dst="10.0.0.99", src=ep.ip4.address) /
2275 UDP(sport=1234, dport=1234) /
2276 Raw('\xa5' * 100))
2277
2278 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2279 for rx in rxs:
2280 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2281 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2282 self.assertEqual(rx[UDP].dport, 48879)
2283 # the UDP source port is a random value for hashing
2284 self.assertEqual(rx[VXLAN].gpid, 220)
2285 self.assertEqual(rx[VXLAN].vni, 114)
2286 self.assertTrue(rx[VXLAN].flags.G)
2287 self.assertTrue(rx[VXLAN].flags.Instance)
2288 # policy is not applied to packets sent to the uu-fwd interfaces
2289 self.assertFalse(rx[VXLAN].gpflags.A)
2290 self.assertFalse(rx[VXLAN].gpflags.D)
2291
2292 #
2293 # learn some remote IPv4 EPs
2294 #
2295 for ii, l in enumerate(learnt):
2296 # a packet with an sclass from a knwon EPG
2297 # arriving on an unknown TEP
2298 p = (Ether(src=self.pg2.remote_mac,
2299 dst=self.pg2.local_mac) /
2300 IP(src=self.pg2.remote_hosts[1].ip4,
2301 dst=self.pg2.local_ip4) /
2302 UDP(sport=1234, dport=48879) /
2303 VXLAN(vni=101, gpid=220, flags=0x88) /
2304 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2305 IP(src=l['ip'], dst=ep.ip4.address) /
2306 UDP(sport=1234, dport=1234) /
2307 Raw('\xa5' * 100))
2308
2309 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2310
2311 # the new TEP
2312 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2313 self,
2314 self.pg2.local_ip4,
2315 self.pg2.remote_hosts[1].ip4,
2316 vx_tun_l3.vni)
2317 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2318
2319 # endpoint learnt via the parent GBP-vxlan interface
2320 self.assertTrue(find_gbp_endpoint(self,
2321 vx_tun_l3._sw_if_index,
2322 ip=l['ip']))
2323
2324 #
2325 # Add a remote endpoint from the API
2326 #
2327 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2328 epg_220, None,
2329 "10.0.0.88", "11.0.0.88",
2330 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002331 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002332 self.pg2.local_ip4,
2333 self.pg2.remote_hosts[1].ip4,
2334 mac=None)
2335 rep_88.add_vpp_config()
2336
2337 #
2338 # Add a remote endpoint from the API that matches an existing one
2339 #
2340 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2341 epg_220, None,
2342 learnt[0]['ip'], "11.0.0.101",
2343 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002344 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002345 self.pg2.local_ip4,
2346 self.pg2.remote_hosts[1].ip4,
2347 mac=None)
2348 rep_2.add_vpp_config()
2349
2350 #
2351 # Add a route to the leanred EP's v4 subnet
2352 # packets should be send on the v4/v6 uu=fwd interface resp.
2353 #
2354 se_10_1_24 = VppGbpSubnet(
2355 self, rd1, "10.0.1.0", 24,
2356 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2357 se_10_1_24.add_vpp_config()
2358
2359 self.logger.info(self.vapi.cli("show gbp endpoint"))
2360
2361 ips = ["10.0.0.88", learnt[0]['ip']]
2362 for ip in ips:
2363 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2364 IP(dst=ip, src=ep.ip4.address) /
2365 UDP(sport=1234, dport=1234) /
2366 Raw('\xa5' * 100))
2367
2368 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2369
2370 for rx in rxs:
2371 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2372 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2373 self.assertEqual(rx[UDP].dport, 48879)
2374 # the UDP source port is a random value for hashing
2375 self.assertEqual(rx[VXLAN].gpid, 220)
2376 self.assertEqual(rx[VXLAN].vni, 101)
2377 self.assertTrue(rx[VXLAN].flags.G)
2378 self.assertTrue(rx[VXLAN].flags.Instance)
2379 self.assertTrue(rx[VXLAN].gpflags.A)
2380 self.assertFalse(rx[VXLAN].gpflags.D)
2381
2382 inner = rx[VXLAN].payload
2383
2384 self.assertEqual(inner[Ether].src, routed_src_mac)
2385 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2386 self.assertEqual(inner[IP].src, ep.ip4.address)
2387 self.assertEqual(inner[IP].dst, ip)
2388
2389 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002390 # remove the API remote EPs, only API sourced is gone, the DP
2391 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002392 #
2393 rep_88.remove_vpp_config()
2394 rep_2.remove_vpp_config()
2395
Neale Ranns00a469d2018-12-20 06:12:19 -08002396 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2397
2398 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2399 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2400 UDP(sport=1234, dport=1234) /
2401 Raw('\xa5' * 100))
2402 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002403
Neale Ranns13a08cc2018-11-07 09:25:54 -08002404 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002405
Neale Ranns13a08cc2018-11-07 09:25:54 -08002406 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2407 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2408 UDP(sport=1234, dport=1234) /
2409 Raw('\xa5' * 100))
2410 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002411
Neale Ranns13a08cc2018-11-07 09:25:54 -08002412 #
2413 # to appease the testcase we cannot have the registered EP stll
2414 # present (because it's DP learnt) when the TC ends so wait until
2415 # it is removed
2416 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002417 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2418 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002419
2420 #
2421 # shutdown with learnt endpoint present
2422 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002423 p = (Ether(src=self.pg2.remote_mac,
2424 dst=self.pg2.local_mac) /
2425 IP(src=self.pg2.remote_hosts[1].ip4,
2426 dst=self.pg2.local_ip4) /
2427 UDP(sport=1234, dport=48879) /
2428 VXLAN(vni=101, gpid=220, flags=0x88) /
2429 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2430 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2431 UDP(sport=1234, dport=1234) /
2432 Raw('\xa5' * 100))
2433
2434 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2435
2436 # endpoint learnt via the parent GBP-vxlan interface
2437 self.assertTrue(find_gbp_endpoint(self,
2438 vx_tun_l3._sw_if_index,
2439 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002440
2441 #
2442 # TODO
2443 # remote endpoint becomes local
2444 #
2445 self.pg2.unconfig_ip4()
2446 self.pg3.unconfig_ip4()
2447 self.pg4.unconfig_ip4()
2448
Neale Ranns13a08cc2018-11-07 09:25:54 -08002449 def test_gbp_redirect(self):
2450 """ GBP Endpoint Redirect """
2451
2452 self.vapi.cli("set logging class gbp debug")
2453
Neale Rannsb6a47952018-11-21 05:44:35 -08002454 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002455 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2456 routed_src_mac = "00:22:bd:f8:19:ff"
2457
2458 learnt = [{'mac': '00:00:11:11:11:02',
2459 'ip': '10.0.1.2',
2460 'ip6': '2001:10::2'},
2461 {'mac': '00:00:11:11:11:03',
2462 'ip': '10.0.1.3',
2463 'ip6': '2001:10::3'}]
2464
2465 #
2466 # lower the inactive threshold so these tests pass in a
2467 # reasonable amount of time
2468 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002469 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002470
2471 #
2472 # IP tables
2473 #
2474 t4 = VppIpTable(self, 1)
2475 t4.add_vpp_config()
2476 t6 = VppIpTable(self, 1, True)
2477 t6.add_vpp_config()
2478
2479 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2480 rd1.add_vpp_config()
2481
Ole Troan8006c6a2018-12-17 12:02:26 +01002482 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002483
2484 #
2485 # Bind the BVI to the RD
2486 #
2487 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2488 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2489
2490 #
2491 # Pg7 hosts a BD's UU-fwd
2492 #
2493 self.pg7.config_ip4()
2494 self.pg7.resolve_arp()
2495
2496 #
2497 # a GBP bridge domains for the EPs
2498 #
2499 bd1 = VppBridgeDomain(self, 1)
2500 bd1.add_vpp_config()
2501 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2502 gbd1.add_vpp_config()
2503
2504 bd2 = VppBridgeDomain(self, 2)
2505 bd2.add_vpp_config()
2506 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2507 gbd2.add_vpp_config()
2508
2509 # ... and has a /32 and /128 applied
2510 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2511 ip4_addr.add_vpp_config()
2512 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2513 ip6_addr.add_vpp_config()
2514 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2515 ip4_addr.add_vpp_config()
2516 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2517 ip6_addr.add_vpp_config()
2518
2519 #
2520 # The Endpoint-groups in which we are learning endpoints
2521 #
2522 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2523 None, gbd1.bvi,
2524 "10.0.0.128",
2525 "2001:10::128")
2526 epg_220.add_vpp_config()
2527 epg_221 = VppGbpEndpointGroup(self, 221, rd1, gbd2,
2528 None, gbd2.bvi,
2529 "10.0.1.128",
2530 "2001:11::128")
2531 epg_221.add_vpp_config()
2532 epg_222 = VppGbpEndpointGroup(self, 222, rd1, gbd1,
2533 None, gbd1.bvi,
2534 "10.0.2.128",
2535 "2001:12::128")
2536 epg_222.add_vpp_config()
2537
2538 #
2539 # a GBP bridge domains for the SEPs
2540 #
2541 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2542 self.pg7.remote_ip4, 116)
2543 bd_uu1.add_vpp_config()
2544 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2545 self.pg7.remote_ip4, 117)
2546 bd_uu2.add_vpp_config()
2547
2548 bd3 = VppBridgeDomain(self, 3)
2549 bd3.add_vpp_config()
2550 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2551 gbd3.add_vpp_config()
2552 bd4 = VppBridgeDomain(self, 4)
2553 bd4.add_vpp_config()
2554 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2555 gbd4.add_vpp_config()
2556
2557 #
2558 # EPGs in which the service endpoints exist
2559 #
2560 epg_320 = VppGbpEndpointGroup(self, 320, rd1, gbd3,
2561 None, gbd1.bvi,
2562 "12.0.0.128",
2563 "4001:10::128")
2564 epg_320.add_vpp_config()
2565 epg_321 = VppGbpEndpointGroup(self, 321, rd1, gbd4,
2566 None, gbd2.bvi,
2567 "12.0.1.128",
2568 "4001:11::128")
2569 epg_321.add_vpp_config()
2570
2571 #
2572 # three local endpoints
2573 #
2574 ep1 = VppGbpEndpoint(self, self.pg0,
2575 epg_220, None,
2576 "10.0.0.1", "11.0.0.1",
2577 "2001:10::1", "3001:10::1")
2578 ep1.add_vpp_config()
2579 ep2 = VppGbpEndpoint(self, self.pg1,
2580 epg_221, None,
2581 "10.0.1.1", "11.0.1.1",
2582 "2001:11::1", "3001:11::1")
2583 ep2.add_vpp_config()
2584 ep3 = VppGbpEndpoint(self, self.pg2,
2585 epg_222, None,
2586 "10.0.2.2", "11.0.2.2",
2587 "2001:12::1", "3001:12::1")
2588 ep3.add_vpp_config()
2589
2590 #
2591 # service endpoints
2592 #
2593 sep1 = VppGbpEndpoint(self, self.pg3,
2594 epg_320, None,
2595 "12.0.0.1", "13.0.0.1",
2596 "4001:10::1", "5001:10::1")
2597 sep1.add_vpp_config()
2598 sep2 = VppGbpEndpoint(self, self.pg4,
2599 epg_320, None,
2600 "12.0.0.2", "13.0.0.2",
2601 "4001:10::2", "5001:10::2")
2602 sep2.add_vpp_config()
2603 sep3 = VppGbpEndpoint(self, self.pg5,
2604 epg_321, None,
2605 "12.0.1.1", "13.0.1.1",
2606 "4001:11::1", "5001:11::1")
2607 sep3.add_vpp_config()
2608 # this EP is not installed immediately
2609 sep4 = VppGbpEndpoint(self, self.pg6,
2610 epg_321, None,
2611 "12.0.1.2", "13.0.1.2",
2612 "4001:11::2", "5001:11::2")
2613
2614 #
2615 # an L2 switch packet between local EPs in different EPGs
2616 # different dest ports on each so the are LB hashed differently
2617 #
2618 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2619 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2620 UDP(sport=1234, dport=1234) /
2621 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002622 (Ether(src=ep3.mac, dst=ep1.mac) /
2623 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2624 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002625 Raw('\xa5' * 100))]
2626 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2627 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2628 UDP(sport=1234, dport=1234) /
2629 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002630 (Ether(src=ep3.mac, dst=ep1.mac) /
2631 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002632 UDP(sport=1234, dport=1230) /
2633 Raw('\xa5' * 100))]
2634
2635 # should be dropped since no contract yet
2636 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2637 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2638
2639 #
2640 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2641 # one of the next-hops is via an EP that is not known
2642 #
2643 acl = VppGbpAcl(self)
2644 rule4 = acl.create_rule(permit_deny=1, proto=17)
2645 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2646 acl_index = acl.add_vpp_config([rule4, rule6])
2647
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002648 #
2649 # test the src-ip hash mode
2650 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002651 c1 = VppGbpContract(
2652 self, 220, 222, acl_index,
2653 [VppGbpContractRule(
2654 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002655 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002656 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2657 sep1.ip4, sep1.epg.rd),
2658 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2659 sep2.ip4, sep2.epg.rd)]),
2660 VppGbpContractRule(
2661 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002662 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002663 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2664 sep3.ip6, sep3.epg.rd),
2665 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002666 sep4.ip6, sep4.epg.rd)])],
2667 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002668 c1.add_vpp_config()
2669
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002670 c2 = VppGbpContract(
2671 self, 222, 220, acl_index,
2672 [VppGbpContractRule(
2673 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2674 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2675 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2676 sep1.ip4, sep1.epg.rd),
2677 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2678 sep2.ip4, sep2.epg.rd)]),
2679 VppGbpContractRule(
2680 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2681 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2682 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2683 sep3.ip6, sep3.epg.rd),
2684 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002685 sep4.ip6, sep4.epg.rd)])],
2686 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002687 c2.add_vpp_config()
2688
Neale Ranns13a08cc2018-11-07 09:25:54 -08002689 #
2690 # send again with the contract preset, now packets arrive
2691 # at SEP1 or SEP2 depending on the hashing
2692 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002693 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002694
2695 for rx in rxs:
2696 self.assertEqual(rx[Ether].src, routed_src_mac)
2697 self.assertEqual(rx[Ether].dst, sep1.mac)
2698 self.assertEqual(rx[IP].src, ep1.ip4.address)
2699 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2700
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002701 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2702
2703 for rx in rxs:
2704 self.assertEqual(rx[Ether].src, routed_src_mac)
2705 self.assertEqual(rx[Ether].dst, sep2.mac)
2706 self.assertEqual(rx[IP].src, ep3.ip4.address)
2707 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2708
Neale Ranns13a08cc2018-11-07 09:25:54 -08002709 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2710
2711 for rx in rxs:
2712 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2713 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2714 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2715 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2716 self.assertEqual(rx[VXLAN].vni, 117)
2717 self.assertTrue(rx[VXLAN].flags.G)
2718 self.assertTrue(rx[VXLAN].flags.Instance)
2719 # redirect policy has been applied
2720 self.assertTrue(rx[VXLAN].gpflags.A)
2721 self.assertFalse(rx[VXLAN].gpflags.D)
2722
2723 inner = rx[VXLAN].payload
2724
2725 self.assertEqual(inner[Ether].src, routed_src_mac)
2726 self.assertEqual(inner[Ether].dst, sep4.mac)
2727 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2728 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2729
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002730 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002731
2732 for rx in rxs:
2733 self.assertEqual(rx[Ether].src, routed_src_mac)
2734 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002735 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2736 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002737
2738 #
2739 # programme the unknown EP
2740 #
2741 sep4.add_vpp_config()
2742
2743 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2744
2745 for rx in rxs:
2746 self.assertEqual(rx[Ether].src, routed_src_mac)
2747 self.assertEqual(rx[Ether].dst, sep4.mac)
2748 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2749 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2750
2751 #
2752 # and revert back to unprogrammed
2753 #
2754 sep4.remove_vpp_config()
2755
2756 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2757
2758 for rx in rxs:
2759 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2760 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2761 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2762 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2763 self.assertEqual(rx[VXLAN].vni, 117)
2764 self.assertTrue(rx[VXLAN].flags.G)
2765 self.assertTrue(rx[VXLAN].flags.Instance)
2766 # redirect policy has been applied
2767 self.assertTrue(rx[VXLAN].gpflags.A)
2768 self.assertFalse(rx[VXLAN].gpflags.D)
2769
2770 inner = rx[VXLAN].payload
2771
2772 self.assertEqual(inner[Ether].src, routed_src_mac)
2773 self.assertEqual(inner[Ether].dst, sep4.mac)
2774 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2775 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2776
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002777 c1.remove_vpp_config()
2778 c2.remove_vpp_config()
2779
2780 #
2781 # test the symmetric hash mode
2782 #
2783 c1 = VppGbpContract(
2784 self, 220, 222, acl_index,
2785 [VppGbpContractRule(
2786 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2787 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2788 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2789 sep1.ip4, sep1.epg.rd),
2790 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2791 sep2.ip4, sep2.epg.rd)]),
2792 VppGbpContractRule(
2793 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2794 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2795 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2796 sep3.ip6, sep3.epg.rd),
2797 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002798 sep4.ip6, sep4.epg.rd)])],
2799 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002800 c1.add_vpp_config()
2801
2802 c2 = VppGbpContract(
2803 self, 222, 220, acl_index,
2804 [VppGbpContractRule(
2805 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2806 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2807 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2808 sep1.ip4, sep1.epg.rd),
2809 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2810 sep2.ip4, sep2.epg.rd)]),
2811 VppGbpContractRule(
2812 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2813 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2814 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2815 sep3.ip6, sep3.epg.rd),
2816 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002817 sep4.ip6, sep4.epg.rd)])],
2818 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002819 c2.add_vpp_config()
2820
2821 #
2822 # send again with the contract preset, now packets arrive
2823 # at SEP1 for both directions
2824 #
2825 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2826
2827 for rx in rxs:
2828 self.assertEqual(rx[Ether].src, routed_src_mac)
2829 self.assertEqual(rx[Ether].dst, sep1.mac)
2830 self.assertEqual(rx[IP].src, ep1.ip4.address)
2831 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2832
2833 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2834
2835 for rx in rxs:
2836 self.assertEqual(rx[Ether].src, routed_src_mac)
2837 self.assertEqual(rx[Ether].dst, sep1.mac)
2838 self.assertEqual(rx[IP].src, ep3.ip4.address)
2839 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2840
Neale Ranns13a08cc2018-11-07 09:25:54 -08002841 #
2842 # programme the unknown EP for the L3 tests
2843 #
2844 sep4.add_vpp_config()
2845
2846 #
2847 # an L3 switch packet between local EPs in different EPGs
2848 # different dest ports on each so the are LB hashed differently
2849 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002850 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002851 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2852 UDP(sport=1234, dport=1234) /
2853 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002854 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002855 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2856 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002857 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002858 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002859 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2860 UDP(sport=1234, dport=1234) /
2861 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002862 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002863 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2864 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002865 Raw('\xa5' * 100))]
2866
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002867 c3 = VppGbpContract(
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002868 self, 220, 221, acl_index,
2869 [VppGbpContractRule(
2870 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2871 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2872 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2873 sep1.ip4, sep1.epg.rd),
2874 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2875 sep2.ip4, sep2.epg.rd)]),
2876 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002877 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002878 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002879 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2880 sep3.ip6, sep3.epg.rd),
2881 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2882 sep4.ip6, sep4.epg.rd)])],
2883 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002884 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002885
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002886 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002887
2888 for rx in rxs:
2889 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002890 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002891 self.assertEqual(rx[IP].src, ep1.ip4.address)
2892 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2893
2894 #
2895 # learn a remote EP in EPG 221
2896 #
2897 vx_tun_l3 = VppGbpVxlanTunnel(
2898 self, 444, rd1.rd_id,
2899 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2900 vx_tun_l3.add_vpp_config()
2901
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002902 c4 = VppGbpContract(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002903 self, 221, 220, acl_index,
2904 [VppGbpContractRule(
2905 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2906 []),
2907 VppGbpContractRule(
2908 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002909 [])],
2910 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002911 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002912
2913 p = (Ether(src=self.pg7.remote_mac,
2914 dst=self.pg7.local_mac) /
2915 IP(src=self.pg7.remote_ip4,
2916 dst=self.pg7.local_ip4) /
2917 UDP(sport=1234, dport=48879) /
2918 VXLAN(vni=444, gpid=221, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01002919 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002920 IP(src="10.0.0.88", dst=ep1.ip4.address) /
2921 UDP(sport=1234, dport=1234) /
2922 Raw('\xa5' * 100))
2923
2924 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2925
2926 # endpoint learnt via the parent GBP-vxlan interface
2927 self.assertTrue(find_gbp_endpoint(self,
2928 vx_tun_l3._sw_if_index,
2929 ip="10.0.0.88"))
2930
2931 p = (Ether(src=self.pg7.remote_mac,
2932 dst=self.pg7.local_mac) /
2933 IP(src=self.pg7.remote_ip4,
2934 dst=self.pg7.local_ip4) /
2935 UDP(sport=1234, dport=48879) /
2936 VXLAN(vni=444, gpid=221, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01002937 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002938 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
2939 UDP(sport=1234, dport=1234) /
2940 Raw('\xa5' * 100))
2941
2942 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2943
2944 # endpoint learnt via the parent GBP-vxlan interface
2945 self.assertTrue(find_gbp_endpoint(self,
2946 vx_tun_l3._sw_if_index,
2947 ip="2001:10::88"))
2948
2949 #
2950 # L3 switch from local to remote EP
2951 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002952 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002953 IP(src=ep1.ip4.address, dst="10.0.0.88") /
2954 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002955 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002956 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002957 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
2958 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002959 Raw('\xa5' * 100))]
2960
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002961 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002962
2963 for rx in rxs:
2964 self.assertEqual(rx[Ether].src, routed_src_mac)
2965 self.assertEqual(rx[Ether].dst, sep1.mac)
2966 self.assertEqual(rx[IP].src, ep1.ip4.address)
2967 self.assertEqual(rx[IP].dst, "10.0.0.88")
2968
2969 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2970
2971 for rx in rxs:
2972 self.assertEqual(rx[Ether].src, routed_src_mac)
2973 self.assertEqual(rx[Ether].dst, sep4.mac)
2974 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2975 self.assertEqual(rx[IPv6].dst, "2001:10::88")
2976
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002977 #
2978 # test the dst-ip hash mode
2979 #
2980 c5 = VppGbpContract(
2981 self, 220, 221, acl_index,
2982 [VppGbpContractRule(
2983 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2984 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
2985 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2986 sep1.ip4, sep1.epg.rd),
2987 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2988 sep2.ip4, sep2.epg.rd)]),
2989 VppGbpContractRule(
2990 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2991 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
2992 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2993 sep3.ip6, sep3.epg.rd),
2994 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002995 sep4.ip6, sep4.epg.rd)])],
2996 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002997 c5.add_vpp_config()
2998
2999 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3000
3001 for rx in rxs:
3002 self.assertEqual(rx[Ether].src, routed_src_mac)
3003 self.assertEqual(rx[Ether].dst, sep1.mac)
3004 self.assertEqual(rx[IP].src, ep1.ip4.address)
3005 self.assertEqual(rx[IP].dst, "10.0.0.88")
3006
3007 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003008
3009 for rx in rxs:
3010 self.assertEqual(rx[Ether].src, routed_src_mac)
3011 self.assertEqual(rx[Ether].dst, sep3.mac)
3012 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3013 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3014
Neale Rannsb6a47952018-11-21 05:44:35 -08003015 #
3016 # cleanup
3017 #
3018 self.pg7.unconfig_ip4()
3019
3020 def test_gbp_l3_out(self):
3021 """ GBP L3 Out """
3022
3023 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3024 self.vapi.cli("set logging class gbp debug")
3025
3026 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3027 routed_src_mac = "00:22:bd:f8:19:ff"
3028
3029 #
3030 # IP tables
3031 #
3032 t4 = VppIpTable(self, 1)
3033 t4.add_vpp_config()
3034 t6 = VppIpTable(self, 1, True)
3035 t6.add_vpp_config()
3036
3037 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3038 rd1.add_vpp_config()
3039
Ole Troan8006c6a2018-12-17 12:02:26 +01003040 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003041
3042 #
3043 # Bind the BVI to the RD
3044 #
3045 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3046 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3047
3048 #
3049 # Pg7 hosts a BD's BUM
3050 # Pg1 some other l3 interface
3051 #
3052 self.pg7.config_ip4()
3053 self.pg7.resolve_arp()
3054
3055 #
3056 # a GBP external bridge domains for the EPs
3057 #
3058 bd1 = VppBridgeDomain(self, 1)
3059 bd1.add_vpp_config()
3060 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
3061 gbd1.add_vpp_config()
3062
3063 #
3064 # The Endpoint-groups in which the external endpoints exist
3065 #
3066 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
3067 None, gbd1.bvi,
3068 "10.0.0.128",
3069 "2001:10::128")
3070 epg_220.add_vpp_config()
3071
3072 # the BVIs have the subnets applied ...
3073 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3074 ip4_addr.add_vpp_config()
3075 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3076 ip6_addr.add_vpp_config()
3077
3078 # ... which are L3-out subnets
3079 l3o_1 = VppGbpSubnet(
3080 self, rd1, "10.0.0.0", 24,
3081 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3082 epg=200)
3083 l3o_1.add_vpp_config()
3084
3085 #
3086 # an external interface attached to the outside world and the
3087 # external BD
3088 #
3089 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3090 vlan_100.admin_up()
3091 ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1)
3092 ext_itf.add_vpp_config()
3093
3094 #
3095 # a multicast vxlan-gbp tunnel for broadcast in the BD
3096 #
3097 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3098 "239.1.1.1", 88,
3099 mcast_itf=self.pg7)
3100 tun_bm.add_vpp_config()
3101 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
3102 port_type=L2_PORT_TYPE.NORMAL)
3103 bp_bm.add_vpp_config()
3104
3105 #
3106 # an unicast vxlan-gbp for inter-BD traffic
3107 #
3108 vx_tun_l3 = VppGbpVxlanTunnel(
3109 self, 444, rd1.rd_id,
3110 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
3111 vx_tun_l3.add_vpp_config()
3112
3113 #
3114 # packets destined to unkown addresses in the BVI's subnet
3115 # are ARP'd for
3116 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003117 p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003118 Dot1Q(vlan=100) /
3119 IP(src="10.0.0.1", dst="10.0.0.88") /
3120 UDP(sport=1234, dport=1234) /
3121 Raw('\xa5' * 100))
Ole Troan8006c6a2018-12-17 12:02:26 +01003122 p6 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003123 Dot1Q(vlan=100) /
3124 IPv6(src="2001:10::1", dst="2001:10::88") /
3125 UDP(sport=1234, dport=1234) /
3126 Raw('\xa5' * 100))
3127
3128 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3129
3130 for rx in rxs:
3131 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3132 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3133 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3134 self.assertEqual(rx[IP].dst, "239.1.1.1")
3135 self.assertEqual(rx[VXLAN].vni, 88)
3136 self.assertTrue(rx[VXLAN].flags.G)
3137 self.assertTrue(rx[VXLAN].flags.Instance)
3138 # policy is not applied since we don't know where it's going
3139 self.assertFalse(rx[VXLAN].gpflags.A)
3140 self.assertFalse(rx[VXLAN].gpflags.D)
3141
3142 inner = rx[VXLAN].payload
3143
3144 self.assertTrue(inner.haslayer(ARP))
3145
3146 #
3147 # An external Endpoint
3148 #
3149 eep = VppGbpEndpoint(self, vlan_100,
3150 epg_220, None,
3151 "10.0.0.1", "11.0.0.1",
3152 "2001:10::1", "3001::1",
3153 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3154 eep.add_vpp_config()
3155
3156 #
3157 # A remote endpoint
3158 #
3159 rep = VppGbpEndpoint(self, vx_tun_l3,
3160 epg_220, None,
3161 "10.0.0.101", "11.0.0.101",
3162 "2001:10::101", "3001::101",
3163 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3164 self.pg7.local_ip4,
3165 self.pg7.remote_ip4,
3166 mac=None)
3167 rep.add_vpp_config()
3168
3169 #
3170 # remote to external
3171 #
3172 p = (Ether(src=self.pg7.remote_mac,
3173 dst=self.pg7.local_mac) /
3174 IP(src=self.pg7.remote_ip4,
3175 dst=self.pg7.local_ip4) /
3176 UDP(sport=1234, dport=48879) /
3177 VXLAN(vni=444, gpid=220, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003178 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003179 IP(src="10.0.0.101", dst="10.0.0.1") /
3180 UDP(sport=1234, dport=1234) /
3181 Raw('\xa5' * 100))
3182
3183 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3184
3185 #
3186 # A subnet reachable through the external EP
3187 #
3188 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
3189 [VppRoutePath(eep.ip4.address,
3190 eep.epg.bvi.sw_if_index)],
3191 table_id=t4.table_id)
3192 ip_220.add_vpp_config()
3193
3194 l3o_220 = VppGbpSubnet(
3195 self, rd1, "10.220.0.0", 24,
3196 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3197 epg=220)
3198 l3o_220.add_vpp_config()
3199
3200 p = (Ether(src=self.pg7.remote_mac,
3201 dst=self.pg7.local_mac) /
3202 IP(src=self.pg7.remote_ip4,
3203 dst=self.pg7.local_ip4) /
3204 UDP(sport=1234, dport=48879) /
3205 VXLAN(vni=444, gpid=220, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003206 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003207 IP(src="10.0.0.101", dst="10.220.0.1") /
3208 UDP(sport=1234, dport=1234) /
3209 Raw('\xa5' * 100))
3210
3211 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3212
3213 #
3214 # another external subnet, this time in a different EPG
3215 #
3216 ip_200 = VppIpRoute(self, "10.200.0.0", 24,
3217 [VppRoutePath(eep.ip4.address,
3218 eep.epg.bvi.sw_if_index)],
3219 table_id=t4.table_id)
3220 ip_200.add_vpp_config()
3221
3222 l3o_200 = VppGbpSubnet(
3223 self, rd1, "10.200.0.0", 24,
3224 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3225 epg=200)
3226 l3o_200.add_vpp_config()
3227
3228 p = (Ether(src=self.pg7.remote_mac,
3229 dst=self.pg7.local_mac) /
3230 IP(src=self.pg7.remote_ip4,
3231 dst=self.pg7.local_ip4) /
3232 UDP(sport=1234, dport=48879) /
3233 VXLAN(vni=444, gpid=220, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003234 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003235 IP(src="10.0.0.101", dst="10.200.0.1") /
3236 UDP(sport=1234, dport=1234) /
3237 Raw('\xa5' * 100))
3238
3239 #
3240 # packets dropped due to lack of contract.
3241 #
3242 rxs = self.send_and_assert_no_replies(self.pg7, p * 1)
3243
3244 #
3245 # from the the subnet in EPG 220 beyond the external to remote
3246 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003247 p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003248 Dot1Q(vlan=100) /
3249 IP(src="10.220.0.1", dst=rep.ip4.address) /
3250 UDP(sport=1234, dport=1234) /
3251 Raw('\xa5' * 100))
3252
3253 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3254
3255 for rx in rxs:
3256 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3257 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3258 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3259 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3260 self.assertEqual(rx[VXLAN].vni, 444)
3261 self.assertTrue(rx[VXLAN].flags.G)
3262 self.assertTrue(rx[VXLAN].flags.Instance)
3263 self.assertTrue(rx[VXLAN].gpflags.A)
3264 self.assertFalse(rx[VXLAN].gpflags.D)
3265
3266 #
3267 # from the the subnet in EPG 200 beyond the external to remote
3268 # dropped due to no contract
3269 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003270 p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003271 Dot1Q(vlan=100) /
3272 IP(src="10.200.0.1", dst=rep.ip4.address) /
3273 UDP(sport=1234, dport=1234) /
3274 Raw('\xa5' * 100))
3275
3276 rxs = self.send_and_assert_no_replies(self.pg0, p4 * 1)
3277
3278 #
3279 # add a contract
3280 #
3281 acl = VppGbpAcl(self)
3282 rule = acl.create_rule(permit_deny=1, proto=17)
3283 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3284 acl_index = acl.add_vpp_config([rule, rule2])
3285 c1 = VppGbpContract(
3286 self, 200, 220, acl_index,
3287 [VppGbpContractRule(
3288 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3289 []),
3290 VppGbpContractRule(
3291 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003292 [])],
3293 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsb6a47952018-11-21 05:44:35 -08003294 c1.add_vpp_config()
3295
3296 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3297
3298 for rx in rxs:
3299 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3300 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3301 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3302 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3303 self.assertEqual(rx[VXLAN].vni, 444)
3304 self.assertTrue(rx[VXLAN].flags.G)
3305 self.assertTrue(rx[VXLAN].flags.Instance)
3306 self.assertTrue(rx[VXLAN].gpflags.A)
3307 self.assertFalse(rx[VXLAN].gpflags.D)
3308
3309 #
3310 # cleanup
3311 #
3312 self.pg7.unconfig_ip4()
3313
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003314
3315if __name__ == '__main__':
3316 unittest.main(testRunner=VppTestRunner)