blob: fd8b79b26b6b28668f1c0f74568d6fec1791731e [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
Neale Ranns879d11c2019-01-21 23:34:18 -0800285 def __init__(self, test, epg, sclass, rd, bd, uplink,
Neale Ranns25b04942018-04-04 09:34:50 -0700286 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
Neale Ranns879d11c2019-01-21 23:34:18 -0800295 self.sclass = sclass
296 if 0 == self.sclass:
297 self.sclass = 0xffff
Neale Ranns25b04942018-04-04 09:34:50 -0700298
299 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700300 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700301 self.epg,
Neale Ranns879d11c2019-01-21 23:34:18 -0800302 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700303 self.bd.bd.bd_id,
304 self.rd.rd_id,
305 self.uplink.sw_if_index if self.uplink else INDEX_INVALID)
Neale Ranns25b04942018-04-04 09:34:50 -0700306 self._test.registry.register(self, self._test.logger)
307
308 def remove_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700309 self._test.vapi.gbp_endpoint_group_del(
310 self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700311
312 def __str__(self):
313 return self.object_id()
314
315 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700316 return "gbp-endpoint-group:[%d]" % (self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700317
318 def query_vpp_config(self):
319 epgs = self._test.vapi.gbp_endpoint_group_dump()
320 for epg in epgs:
321 if epg.epg.epg_id == self.epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800322 return True
323 return False
324
325
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700326class VppGbpBridgeDomain(VppObject):
327 """
328 GBP Bridge Domain
329 """
330
Neale Ranns879d11c2019-01-21 23:34:18 -0800331 def __init__(self, test, bd, bvi, uu_fwd=None,
332 bm_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700333 self._test = test
334 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800335 self.uu_fwd = uu_fwd
336 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700337 self.bd = bd
338
Neale Rannsc29c0af2018-11-07 04:21:12 -0800339 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
340 if (learn):
341 self.learn = e.GBP_BD_API_FLAG_NONE
342 else:
343 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
344
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700345 def add_vpp_config(self):
346 self._test.vapi.gbp_bridge_domain_add(
347 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800348 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700349 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800350 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
351 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700352 self._test.registry.register(self, self._test.logger)
353
354 def remove_vpp_config(self):
355 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
356
357 def __str__(self):
358 return self.object_id()
359
360 def object_id(self):
361 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
362
363 def query_vpp_config(self):
364 bds = self._test.vapi.gbp_bridge_domain_dump()
365 for bd in bds:
366 if bd.bd.bd_id == self.bd.bd_id:
367 return True
368 return False
369
370
371class VppGbpRouteDomain(VppObject):
372 """
373 GBP Route Domain
374 """
375
376 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
377 self._test = test
378 self.rd_id = rd_id
379 self.t4 = t4
380 self.t6 = t6
381 self.ip4_uu = ip4_uu
382 self.ip6_uu = ip6_uu
383
384 def add_vpp_config(self):
385 self._test.vapi.gbp_route_domain_add(
386 self.rd_id,
387 self.t4.table_id,
388 self.t6.table_id,
389 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
390 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
391 self._test.registry.register(self, self._test.logger)
392
393 def remove_vpp_config(self):
394 self._test.vapi.gbp_route_domain_del(self.rd_id)
395
396 def __str__(self):
397 return self.object_id()
398
399 def object_id(self):
400 return "gbp-route-domain:[%d]" % (self.rd_id)
401
402 def query_vpp_config(self):
403 rds = self._test.vapi.gbp_route_domain_dump()
404 for rd in rds:
405 if rd.rd.rd_id == self.rd_id:
406 return True
407 return False
408
409
Neale Ranns13a08cc2018-11-07 09:25:54 -0800410class VppGbpContractNextHop():
411 def __init__(self, mac, bd, ip, rd):
412 self.mac = mac
413 self.ip = ip
414 self.bd = bd
415 self.rd = rd
416
417 def encode(self):
418 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100419 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800420 'bd_id': self.bd.bd.bd_id,
421 'rd_id': self.rd.rd_id}
422
423
424class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100425 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800426 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100427 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800428 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800429
430 def encode(self):
431 nhs = []
432 for nh in self.nhs:
433 nhs.append(nh.encode())
434 while len(nhs) < 8:
435 nhs.append({})
436 return {'action': self.action,
437 'nh_set': {
438 'hash_mode': self.hash_mode,
439 'n_nhs': len(self.nhs),
440 'nhs': nhs}}
441
442
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800443class VppGbpContract(VppObject):
444 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200445 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800446 """
447
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800448 def __init__(self, test, src_epg, dst_epg, acl_index,
449 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800450 self._test = test
451 self.acl_index = acl_index
452 self.src_epg = src_epg
453 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800454 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800455 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800456
457 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800458 rules = []
459 for r in self.rules:
460 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800461 self._test.vapi.gbp_contract_add_del(
462 1,
463 self.src_epg,
464 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800465 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800466 rules,
467 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800468 self._test.registry.register(self, self._test.logger)
469
470 def remove_vpp_config(self):
471 self._test.vapi.gbp_contract_add_del(
472 0,
473 self.src_epg,
474 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800475 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800476 [], [])
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800477
478 def __str__(self):
479 return self.object_id()
480
481 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700482 return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800483 self.dst_epg,
484 self.acl_index)
485
486 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700487 cs = self._test.vapi.gbp_contract_dump()
488 for c in cs:
489 if c.contract.src_epg == self.src_epg \
490 and c.contract.dst_epg == self.dst_epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800491 return True
492 return False
493
494
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700495class VppGbpVxlanTunnel(VppInterface):
496 """
497 GBP VXLAN tunnel
498 """
499
500 def __init__(self, test, vni, bd_rd_id, mode):
501 super(VppGbpVxlanTunnel, self).__init__(test)
502 self._test = test
503 self.vni = vni
504 self.bd_rd_id = bd_rd_id
505 self.mode = mode
506
507 def add_vpp_config(self):
508 r = self._test.vapi.gbp_vxlan_tunnel_add(
509 self.vni,
510 self.bd_rd_id,
511 self.mode)
512 self.set_sw_if_index(r.sw_if_index)
513 self._test.registry.register(self, self._test.logger)
514
515 def remove_vpp_config(self):
516 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
517
518 def __str__(self):
519 return self.object_id()
520
521 def object_id(self):
522 return "gbp-vxlan:%d" % (self.vni)
523
524 def query_vpp_config(self):
525 return find_gbp_vxlan(self._test, self.vni)
526
527
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200528class VppGbpAcl(VppObject):
529 """
530 GBP Acl
531 """
532
533 def __init__(self, test):
534 self._test = test
535 self.acl_index = 4294967295
536
537 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
538 s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
539 sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
540 dport_from=0, dport_to=65535):
541 if proto == -1 or proto == 0:
542 sport_to = 0
543 dport_to = sport_to
544 elif proto == 1 or proto == 58:
545 sport_to = 255
546 dport_to = sport_to
547 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
548 'srcport_or_icmptype_first': sport_from,
549 'srcport_or_icmptype_last': sport_to,
550 'src_ip_prefix_len': s_prefix,
551 'src_ip_addr': s_ip,
552 'dstport_or_icmpcode_first': dport_from,
553 'dstport_or_icmpcode_last': dport_to,
554 'dst_ip_prefix_len': d_prefix,
555 'dst_ip_addr': d_ip})
556 return rule
557
558 def add_vpp_config(self, rules):
559
560 reply = self._test.vapi.acl_add_replace(self.acl_index,
561 r=rules,
562 tag='GBPTest')
563 self.acl_index = reply.acl_index
564 return self.acl_index
565
566 def remove_vpp_config(self):
567 self._test.vapi.acl_del(self.acl_index)
568
569 def __str__(self):
570 return self.object_id()
571
572 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700573 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200574
575 def query_vpp_config(self):
576 cs = self._test.vapi.acl_dump()
577 for c in cs:
578 if c.acl_index == self.acl_index:
579 return True
580 return False
581
582
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800583class TestGBP(VppTestCase):
584 """ GBP Test Case """
585
586 def setUp(self):
587 super(TestGBP, self).setUp()
588
Neale Ranns25b04942018-04-04 09:34:50 -0700589 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700590 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700591
Ole Troan8006c6a2018-12-17 12:02:26 +0100592 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800593
594 for i in self.pg_interfaces:
595 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700596 for i in self.lo_interfaces:
597 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800598
599 def tearDown(self):
600 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700601 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800602
603 super(TestGBP, self).tearDown()
604
Neale Ranns25b04942018-04-04 09:34:50 -0700605 def send_and_expect_bridged(self, src, tx, dst):
606 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800607
Neale Ranns25b04942018-04-04 09:34:50 -0700608 for r in rx:
609 self.assertEqual(r[Ether].src, tx[0][Ether].src)
610 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
611 self.assertEqual(r[IP].src, tx[0][IP].src)
612 self.assertEqual(r[IP].dst, tx[0][IP].dst)
613 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800614
Neale Ranns25b04942018-04-04 09:34:50 -0700615 def send_and_expect_bridged6(self, src, tx, dst):
616 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800617
Neale Ranns25b04942018-04-04 09:34:50 -0700618 for r in rx:
619 self.assertEqual(r[Ether].src, tx[0][Ether].src)
620 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
621 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
622 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
623 return rx
624
625 def send_and_expect_routed(self, src, tx, dst, src_mac):
626 rx = self.send_and_expect(src, tx, dst)
627
628 for r in rx:
629 self.assertEqual(r[Ether].src, src_mac)
630 self.assertEqual(r[Ether].dst, dst.remote_mac)
631 self.assertEqual(r[IP].src, tx[0][IP].src)
632 self.assertEqual(r[IP].dst, tx[0][IP].dst)
633 return rx
634
635 def send_and_expect_natted(self, src, tx, dst, src_ip):
636 rx = self.send_and_expect(src, tx, dst)
637
638 for r in rx:
639 self.assertEqual(r[Ether].src, tx[0][Ether].src)
640 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
641 self.assertEqual(r[IP].src, src_ip)
642 self.assertEqual(r[IP].dst, tx[0][IP].dst)
643 return rx
644
Neale Ranns4a6d0232018-04-24 07:45:33 -0700645 def send_and_expect_natted6(self, src, tx, dst, src_ip):
646 rx = self.send_and_expect(src, tx, dst)
647
648 for r in rx:
649 self.assertEqual(r[Ether].src, tx[0][Ether].src)
650 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
651 self.assertEqual(r[IPv6].src, src_ip)
652 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
653 return rx
654
Neale Ranns25b04942018-04-04 09:34:50 -0700655 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
656 rx = self.send_and_expect(src, tx, dst)
657
658 for r in rx:
659 self.assertEqual(r[Ether].src, tx[0][Ether].src)
660 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
661 self.assertEqual(r[IP].dst, dst_ip)
662 self.assertEqual(r[IP].src, tx[0][IP].src)
663 return rx
664
Neale Ranns4a6d0232018-04-24 07:45:33 -0700665 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
666 rx = self.send_and_expect(src, tx, dst)
667
668 for r in rx:
669 self.assertEqual(r[Ether].src, tx[0][Ether].src)
670 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
671 self.assertEqual(r[IPv6].dst, dst_ip)
672 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
673 return rx
674
Neale Ranns25b04942018-04-04 09:34:50 -0700675 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
676 rx = self.send_and_expect(src, tx, dst)
677
678 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100679 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700680 self.assertEqual(r[Ether].dst, dst.remote_mac)
681 self.assertEqual(r[IP].dst, dst_ip)
682 self.assertEqual(r[IP].src, src_ip)
683 return rx
684
Neale Ranns4a6d0232018-04-24 07:45:33 -0700685 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
686 rx = self.send_and_expect(src, tx, dst)
687
688 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100689 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700690 self.assertEqual(r[Ether].dst, dst.remote_mac)
691 self.assertEqual(r[IPv6].dst, dst_ip)
692 self.assertEqual(r[IPv6].src, src_ip)
693 return rx
694
Neale Ranns25b04942018-04-04 09:34:50 -0700695 def test_gbp(self):
696 """ Group Based Policy """
697
Neale Rannsb6a47952018-11-21 05:44:35 -0800698 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
699
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800700 #
Neale Ranns25b04942018-04-04 09:34:50 -0700701 # Bridge Domains
702 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700703 bd1 = VppBridgeDomain(self, 1)
704 bd2 = VppBridgeDomain(self, 2)
705 bd20 = VppBridgeDomain(self, 20)
706
707 bd1.add_vpp_config()
708 bd2.add_vpp_config()
709 bd20.add_vpp_config()
710
711 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
712 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
713 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
714
715 gbd1.add_vpp_config()
716 gbd2.add_vpp_config()
717 gbd20.add_vpp_config()
718
719 #
720 # Route Domains
721 #
722 gt4 = VppIpTable(self, 0)
723 gt4.add_vpp_config()
724 gt6 = VppIpTable(self, 0, is_ip6=True)
725 gt6.add_vpp_config()
726 nt4 = VppIpTable(self, 20)
727 nt4.add_vpp_config()
728 nt6 = VppIpTable(self, 20, is_ip6=True)
729 nt6.add_vpp_config()
730
731 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
732 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
733
734 rd0.add_vpp_config()
735 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700736
737 #
738 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700739 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
740 #
Neale Ranns879d11c2019-01-21 23:34:18 -0800741 epgs = [VppGbpEndpointGroup(self, 220, 0, rd0, gbd1, self.pg4,
Neale Rannsc0a93142018-09-05 15:42:26 -0700742 self.loop0,
743 "10.0.0.128",
744 "2001:10::128"),
Neale Ranns879d11c2019-01-21 23:34:18 -0800745 VppGbpEndpointGroup(self, 221, 0, rd0, gbd1, self.pg5,
Neale Rannsc0a93142018-09-05 15:42:26 -0700746 self.loop0,
747 "10.0.1.128",
748 "2001:10:1::128"),
Neale Ranns879d11c2019-01-21 23:34:18 -0800749 VppGbpEndpointGroup(self, 222, 0, rd0, gbd2, self.pg6,
Neale Rannsc0a93142018-09-05 15:42:26 -0700750 self.loop1,
751 "10.0.2.128",
752 "2001:10:2::128"),
Neale Ranns879d11c2019-01-21 23:34:18 -0800753 VppGbpEndpointGroup(self, 333, 0, rd20, gbd20, self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -0700754 self.loop2,
755 "11.0.0.128",
756 "3001::128"),
Neale Ranns879d11c2019-01-21 23:34:18 -0800757 VppGbpEndpointGroup(self, 444, 0, rd20, gbd20, self.pg8,
Neale Rannsc0a93142018-09-05 15:42:26 -0700758 self.loop2,
759 "11.0.0.129",
760 "3001::129")]
761 recircs = [VppGbpRecirc(self, epgs[0],
762 self.loop3),
763 VppGbpRecirc(self, epgs[1],
764 self.loop4),
765 VppGbpRecirc(self, epgs[2],
766 self.loop5),
767 VppGbpRecirc(self, epgs[3],
768 self.loop6, is_ext=True),
769 VppGbpRecirc(self, epgs[4],
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700770 self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700771
772 epg_nat = epgs[3]
773 recirc_nat = recircs[3]
774
775 #
776 # 4 end-points, 2 in the same subnet, 3 in the same BD
777 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700778 eps = [VppGbpEndpoint(self, self.pg0,
779 epgs[0], recircs[0],
780 "10.0.0.1", "11.0.0.1",
781 "2001:10::1", "3001::1"),
782 VppGbpEndpoint(self, self.pg1,
783 epgs[0], recircs[0],
784 "10.0.0.2", "11.0.0.2",
785 "2001:10::2", "3001::2"),
786 VppGbpEndpoint(self, self.pg2,
787 epgs[1], recircs[1],
788 "10.0.1.1", "11.0.0.3",
789 "2001:10:1::1", "3001::3"),
790 VppGbpEndpoint(self, self.pg3,
791 epgs[2], recircs[2],
792 "10.0.2.1", "11.0.0.4",
793 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700794
795 #
796 # Config related to each of the EPGs
797 #
798 for epg in epgs:
799 # IP config on the BVI interfaces
800 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700801 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
802 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
803 self.vapi.sw_interface_set_mac_address(
804 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100805 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700806
807 # The BVIs are NAT inside interfaces
808 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
809 is_inside=1,
810 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700811 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
812 is_inside=1,
813 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700814
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700815 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
816 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
817 if_ip4.add_vpp_config()
818 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700819
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700820 # EPG uplink interfaces in the RD
821 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
822 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700823
824 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700825 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100826 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700827 epg.bvi_ip4)
828 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100829 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700830 epg.bvi_ip6)
831 epg.bd_arp_ip4.add_vpp_config()
832 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700833
834 # EPG in VPP
835 epg.add_vpp_config()
836
837 for recirc in recircs:
838 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700839 VppIpInterfaceBind(self, recirc.recirc,
840 recirc.epg.rd.t4).add_vpp_config()
841 VppIpInterfaceBind(self, recirc.recirc,
842 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700843
Neale Ranns4a6d0232018-04-24 07:45:33 -0700844 self.vapi.nat44_interface_add_del_feature(
845 recirc.recirc.sw_if_index,
846 is_inside=0,
847 is_add=1)
848 self.vapi.nat66_add_del_interface(
849 recirc.recirc.sw_if_index,
850 is_inside=0,
851 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700852
853 recirc.add_vpp_config()
854
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700855 for recirc in recircs:
856 self.assertTrue(find_bridge_domain_port(self,
857 recirc.epg.bd.bd.bd_id,
858 recirc.recirc.sw_if_index))
859
Neale Ranns25b04942018-04-04 09:34:50 -0700860 for ep in eps:
861 self.pg_enable_capture(self.pg_interfaces)
862 self.pg_start()
863 #
864 # routes to the endpoints. We need these since there are no
865 # adj-fibs due to the fact the the BVI address has /32 and
866 # the subnet is not attached.
867 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700868 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700869 # Add static mappings for each EP from the 10/8 to 11/8 network
870 if ip.af == AF_INET:
871 self.vapi.nat44_add_del_static_mapping(ip.bytes,
872 fip.bytes,
873 vrf_id=0,
874 addr_only=1)
875 else:
876 self.vapi.nat66_add_del_static_mapping(ip.bytes,
877 fip.bytes,
878 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700879
Neale Ranns25b04942018-04-04 09:34:50 -0700880 # VPP EP create ...
881 ep.add_vpp_config()
882
Neale Rannsc0a93142018-09-05 15:42:26 -0700883 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700884
Neale Rannsc0a93142018-09-05 15:42:26 -0700885 # ... results in a Gratuitous ARP/ND on the EPG's uplink
886 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
887
888 for ii, ip in enumerate(ep.ips):
889 p = rx[ii]
890
891 if ip.is_ip6:
892 self.assertTrue(p.haslayer(ICMPv6ND_NA))
893 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
894 else:
895 self.assertTrue(p.haslayer(ARP))
896 self.assertEqual(p[ARP].psrc, ip.address)
897 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700898
899 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700900 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700901 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
902 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700903
Neale Rannsc0a93142018-09-05 15:42:26 -0700904 # floating IPs route via EPG recirc
905 r = VppIpRoute(self, fip.address, fip.length,
906 [VppRoutePath(fip.address,
907 ep.recirc.recirc.sw_if_index,
908 is_dvr=1,
909 proto=fip.dpo_proto)],
910 table_id=20,
911 is_ip6=fip.is_ip6)
912 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700913
914 # L2 FIB entries in the NAT EPG BD to bridge the packets from
915 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700916 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
917 ep.recirc.recirc, bvi_mac=0)
918 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700919
920 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700921 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700922 #
923 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
924 src=self.pg0.remote_mac) /
925 ARP(op="who-has",
926 hwdst="ff:ff:ff:ff:ff:ff",
927 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700928 pdst="10.0.0.88",
929 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700930
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700931 self.vapi.cli("clear trace")
932 self.pg0.add_stream(pkt_arp)
933
934 self.pg_enable_capture(self.pg_interfaces)
935 self.pg_start()
936
937 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700938
939 #
940 # ARP/ND packets get a response
941 #
942 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
943 src=self.pg0.remote_mac) /
944 ARP(op="who-has",
945 hwdst="ff:ff:ff:ff:ff:ff",
946 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700947 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700948 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700949
950 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
951
Neale Rannsc0a93142018-09-05 15:42:26 -0700952 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700953 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700954 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
955 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700956 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700957 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700958 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
959 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
960
961 #
962 # broadcast packets are flooded
963 #
964 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
965 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700966 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700967 UDP(sport=1234, dport=1234) /
968 Raw('\xa5' * 100))
969
970 self.vapi.cli("clear trace")
971 self.pg0.add_stream(pkt_bcast)
972
973 self.pg_enable_capture(self.pg_interfaces)
974 self.pg_start()
975
976 rxd = eps[1].itf.get_capture(1)
977 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
978 rxd = epgs[0].uplink.get_capture(1)
979 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
980
981 #
982 # packets to non-local L3 destinations dropped
983 #
984 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100985 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700986 IP(src=eps[0].ip4.address,
987 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700988 UDP(sport=1234, dport=1234) /
989 Raw('\xa5' * 100))
990 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100991 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700992 IP(src=eps[0].ip4.address,
993 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700994 UDP(sport=1234, dport=1234) /
995 Raw('\xa5' * 100))
996
997 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
998
999 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001000 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001001 IPv6(src=eps[0].ip6.address,
1002 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001003 UDP(sport=1234, dport=1234) /
1004 Raw('\xa5' * 100))
1005 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
1006
1007 #
1008 # Add the subnet routes
1009 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001010 s41 = VppGbpSubnet(
1011 self, rd0, "10.0.0.0", 24,
1012 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1013 s42 = VppGbpSubnet(
1014 self, rd0, "10.0.1.0", 24,
1015 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1016 s43 = VppGbpSubnet(
1017 self, rd0, "10.0.2.0", 24,
1018 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1019 s61 = VppGbpSubnet(
1020 self, rd0, "2001:10::1", 64,
1021 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1022 s62 = VppGbpSubnet(
1023 self, rd0, "2001:10:1::1", 64,
1024 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1025 s63 = VppGbpSubnet(
1026 self, rd0, "2001:10:2::1", 64,
1027 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001028 s41.add_vpp_config()
1029 s42.add_vpp_config()
1030 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001031 s61.add_vpp_config()
1032 s62.add_vpp_config()
1033 s63.add_vpp_config()
1034
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001035 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001036 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001037 eps[0].epg.uplink)
1038 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001039 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001040 eps[0].epg.uplink)
1041 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001042 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001043 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001044
1045 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1046 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1047 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1048 self.logger.info(self.vapi.cli("sh gbp recirc"))
1049 self.logger.info(self.vapi.cli("sh int"))
1050 self.logger.info(self.vapi.cli("sh int addr"))
1051 self.logger.info(self.vapi.cli("sh int feat loop6"))
1052 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1053 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001054 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001055
1056 #
1057 # Packet destined to unknown unicast is sent on the epg uplink ...
1058 #
1059 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1060 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001061 IP(src=eps[0].ip4.address,
1062 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001063 UDP(sport=1234, dport=1234) /
1064 Raw('\xa5' * 100))
1065
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001066 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001067 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001068 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001069 # ... and nowhere else
1070 self.pg1.get_capture(0, timeout=0.1)
1071 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1072
1073 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1074 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001075 IP(src=eps[0].ip4.address,
1076 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001077 UDP(sport=1234, dport=1234) /
1078 Raw('\xa5' * 100))
1079
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001080 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001081 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001082 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001083
1084 #
1085 # Packets from the uplink are forwarded in the absence of a contract
1086 #
1087 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1088 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001089 IP(src=eps[0].ip4.address,
1090 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001091 UDP(sport=1234, dport=1234) /
1092 Raw('\xa5' * 100))
1093
1094 self.send_and_expect_bridged(self.pg4,
1095 pkt_intra_epg_220_from_uplink * 65,
1096 self.pg0)
1097
1098 #
1099 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001100 # can communicate
1101 #
1102 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001103 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001104 IP(src=eps[0].ip4.address,
1105 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001106 UDP(sport=1234, dport=1234) /
1107 Raw('\xa5' * 100))
1108
Neale Ranns25b04942018-04-04 09:34:50 -07001109 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001110
1111 #
1112 # in the abscense of policy, endpoints in the different EPG
1113 # cannot communicate
1114 #
1115 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001116 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001117 IP(src=eps[0].ip4.address,
1118 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001119 UDP(sport=1234, dport=1234) /
1120 Raw('\xa5' * 100))
1121 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001122 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001123 IP(src=eps[2].ip4.address,
1124 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001125 UDP(sport=1234, dport=1234) /
1126 Raw('\xa5' * 100))
1127 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001128 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001129 IP(src=eps[0].ip4.address,
1130 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001131 UDP(sport=1234, dport=1234) /
1132 Raw('\xa5' * 100))
1133
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001134 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001135 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001136 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001137 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001138
1139 #
1140 # A uni-directional contract from EPG 220 -> 221
1141 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001142 acl = VppGbpAcl(self)
1143 rule = acl.create_rule(permit_deny=1, proto=17)
1144 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1145 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001146 c1 = VppGbpContract(
1147 self, 220, 221, acl_index,
1148 [VppGbpContractRule(
1149 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1150 []),
1151 VppGbpContractRule(
1152 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001153 [])],
1154 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001155 c1.add_vpp_config()
1156
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001157 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001158 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001159 eps[2].itf)
1160 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001161 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001162
1163 #
1164 # contract for the return direction
1165 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001166 c2 = VppGbpContract(
1167 self, 221, 220, acl_index,
1168 [VppGbpContractRule(
1169 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1170 []),
1171 VppGbpContractRule(
1172 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001173 [])],
1174 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001175 c2.add_vpp_config()
1176
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001177 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001178 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001179 eps[2].itf)
1180 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001181 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001182 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001183
1184 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001185 # the contract does not allow non-IP
1186 #
1187 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1188 dst=self.pg2.remote_mac) /
1189 ARP())
1190 self.send_and_assert_no_replies(eps[0].itf,
1191 pkt_non_ip_inter_epg_220_to_221 * 17)
1192
1193 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001194 # check that inter group is still disabled for the groups
1195 # not in the contract.
1196 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001197 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001198 pkt_inter_epg_220_to_222 * 65)
1199
Neale Ranns25b04942018-04-04 09:34:50 -07001200 #
1201 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1202 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001203 c3 = VppGbpContract(
1204 self, 220, 222, acl_index,
1205 [VppGbpContractRule(
1206 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1207 []),
1208 VppGbpContractRule(
1209 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001210 [])],
1211 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001212 c3.add_vpp_config()
1213
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001214 self.logger.info(self.vapi.cli("sh gbp contract"))
1215
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001216 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001217 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001218 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001219 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001220
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001221 #
1222 # remove both contracts, traffic stops in both directions
1223 #
1224 c2.remove_vpp_config()
1225 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001226 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001227 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001228
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001229 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001230 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001231 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001232 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001233 self.send_and_expect_bridged(eps[0].itf,
1234 pkt_intra_epg * 65,
1235 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001236
1237 #
Neale Ranns25b04942018-04-04 09:34:50 -07001238 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001239 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001240
Neale Ranns25b04942018-04-04 09:34:50 -07001241 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001242 se1 = VppGbpSubnet(
1243 self, rd0, "0.0.0.0", 0,
1244 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1245 sw_if_index=recirc_nat.recirc.sw_if_index,
1246 epg=epg_nat.epg)
1247 se2 = VppGbpSubnet(
1248 self, rd0, "11.0.0.0", 8,
1249 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1250 sw_if_index=recirc_nat.recirc.sw_if_index,
1251 epg=epg_nat.epg)
1252 se16 = VppGbpSubnet(
1253 self, rd0, "::", 0,
1254 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1255 sw_if_index=recirc_nat.recirc.sw_if_index,
1256 epg=epg_nat.epg)
Neale Ranns25b04942018-04-04 09:34:50 -07001257 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001258 se3 = VppGbpSubnet(
1259 self, rd20, "0.0.0.0", 0,
1260 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1261 sw_if_index=epg_nat.uplink.sw_if_index,
1262 epg=epg_nat.epg)
1263 se36 = VppGbpSubnet(
1264 self, rd20, "::", 0,
1265 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1266 sw_if_index=epg_nat.uplink.sw_if_index,
1267 epg=epg_nat.epg)
1268 se4 = VppGbpSubnet(
1269 self, rd20, "11.0.0.0", 8,
1270 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1271 sw_if_index=epg_nat.uplink.sw_if_index,
1272 epg=epg_nat.epg)
1273 se1.add_vpp_config()
1274 se2.add_vpp_config()
1275 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001276 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001277 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001278 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001279
Neale Ranns25b04942018-04-04 09:34:50 -07001280 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1281 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001282 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1283 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001284 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001285
Neale Ranns4a6d0232018-04-24 07:45:33 -07001286 #
1287 # From an EP to an outside addess: IN2OUT
1288 #
Neale Ranns25b04942018-04-04 09:34:50 -07001289 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001290 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001291 IP(src=eps[0].ip4.address,
1292 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001293 UDP(sport=1234, dport=1234) /
1294 Raw('\xa5' * 100))
1295
1296 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001297 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001298 pkt_inter_epg_220_to_global * 65)
1299
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001300 acl2 = VppGbpAcl(self)
1301 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1302 sport_to=1234, dport_from=1234, dport_to=1234)
1303 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1304 sport_from=1234, sport_to=1234,
1305 dport_from=1234, dport_to=1234)
1306
1307 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001308 c4 = VppGbpContract(
1309 self, 220, 333, acl_index2,
1310 [VppGbpContractRule(
1311 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1312 []),
1313 VppGbpContractRule(
1314 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001315 [])],
1316 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001317 c4.add_vpp_config()
1318
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001319 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001320 pkt_inter_epg_220_to_global * 65,
1321 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001322 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001323
Neale Ranns4a6d0232018-04-24 07:45:33 -07001324 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001325 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001326 IPv6(src=eps[0].ip6.address,
1327 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001328 UDP(sport=1234, dport=1234) /
1329 Raw('\xa5' * 100))
1330
1331 self.send_and_expect_natted6(self.pg0,
1332 pkt_inter_epg_220_to_global * 65,
1333 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001334 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001335
1336 #
1337 # From a global address to an EP: OUT2IN
1338 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001339 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001340 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001341 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001342 src="1.1.1.1") /
1343 UDP(sport=1234, dport=1234) /
1344 Raw('\xa5' * 100))
1345
1346 self.send_and_assert_no_replies(self.pg7,
1347 pkt_inter_epg_220_from_global * 65)
1348
Neale Ranns13a08cc2018-11-07 09:25:54 -08001349 c5 = VppGbpContract(
1350 self, 333, 220, acl_index2,
1351 [VppGbpContractRule(
1352 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1353 []),
1354 VppGbpContractRule(
1355 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001356 [])],
1357 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001358 c5.add_vpp_config()
1359
1360 self.send_and_expect_unnatted(self.pg7,
1361 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001362 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001363 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001364
Ole Troan8006c6a2018-12-17 12:02:26 +01001365 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001366 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001367 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001368 src="6001::1") /
1369 UDP(sport=1234, dport=1234) /
1370 Raw('\xa5' * 100))
1371
1372 self.send_and_expect_unnatted6(self.pg7,
1373 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001374 eps[0].itf,
1375 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001376
1377 #
1378 # From a local VM to another local VM using resp. public addresses:
1379 # IN2OUT2IN
1380 #
Neale Ranns25b04942018-04-04 09:34:50 -07001381 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001382 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001383 IP(src=eps[0].ip4.address,
1384 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001385 UDP(sport=1234, dport=1234) /
1386 Raw('\xa5' * 100))
1387
Neale Ranns4a6d0232018-04-24 07:45:33 -07001388 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001389 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001390 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001391 eps[0].fip4.address,
1392 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001393
Neale Rannsc0a93142018-09-05 15:42:26 -07001394 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001395 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001396 IPv6(src=eps[0].ip6.address,
1397 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001398 UDP(sport=1234, dport=1234) /
1399 Raw('\xa5' * 100))
1400
Neale Rannsc0a93142018-09-05 15:42:26 -07001401 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001402 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001403 eps[1].itf,
1404 eps[0].fip6.address,
1405 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001406
1407 #
Neale Ranns25b04942018-04-04 09:34:50 -07001408 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001409 #
Neale Ranns25b04942018-04-04 09:34:50 -07001410 for ep in eps:
1411 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001412 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1413 ep.fip4.bytes,
1414 vrf_id=0,
1415 addr_only=1,
1416 is_add=0)
1417 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1418 ep.fip6.bytes,
1419 vrf_id=0,
1420 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001421
Neale Ranns25b04942018-04-04 09:34:50 -07001422 for epg in epgs:
1423 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001424 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001425 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1426 is_inside=1,
1427 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001428 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1429 is_inside=1,
1430 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001431
Neale Ranns25b04942018-04-04 09:34:50 -07001432 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001433 self.vapi.nat44_interface_add_del_feature(
1434 recirc.recirc.sw_if_index,
1435 is_inside=0,
1436 is_add=0)
1437 self.vapi.nat66_add_del_interface(
1438 recirc.recirc.sw_if_index,
1439 is_inside=0,
1440 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001441
Neale Ranns774356a2018-11-29 12:02:16 +00001442 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1443 n_tries=100, s_time=1):
1444 while (n_tries):
1445 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1446 return True
1447 n_tries = n_tries - 1
1448 self.sleep(s_time)
1449 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1450 return False
1451
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001452 def test_gbp_learn_l2(self):
1453 """ GBP L2 Endpoint Learning """
1454
Neale Rannsb6a47952018-11-21 05:44:35 -08001455 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001456 learnt = [{'mac': '00:00:11:11:11:01',
1457 'ip': '10.0.0.1',
1458 'ip6': '2001:10::2'},
1459 {'mac': '00:00:11:11:11:02',
1460 'ip': '10.0.0.2',
1461 'ip6': '2001:10::3'}]
1462
1463 #
1464 # lower the inactive threshold so these tests pass in a
1465 # reasonable amount of time
1466 #
Neale Ranns00a469d2018-12-20 06:12:19 -08001467 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001468
1469 #
1470 # IP tables
1471 #
1472 gt4 = VppIpTable(self, 1)
1473 gt4.add_vpp_config()
1474 gt6 = VppIpTable(self, 1, is_ip6=True)
1475 gt6.add_vpp_config()
1476
1477 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1478 rd1.add_vpp_config()
1479
1480 #
1481 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1482 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1483 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1484 #
1485 self.pg2.config_ip4()
1486 self.pg2.resolve_arp()
1487 self.pg2.generate_remote_hosts(4)
1488 self.pg2.configure_ipv4_neighbors()
1489 self.pg3.config_ip4()
1490 self.pg3.resolve_arp()
1491 self.pg4.config_ip4()
1492 self.pg4.resolve_arp()
1493
1494 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001495 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1496 #
1497 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1498 "239.1.1.1", 88,
1499 mcast_itf=self.pg4)
1500 tun_bm.add_vpp_config()
1501
1502 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001503 # a GBP bridge domain with a BVI and a UU-flood interface
1504 #
1505 bd1 = VppBridgeDomain(self, 1)
1506 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001507 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001508 gbd1.add_vpp_config()
1509
1510 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1511 self.logger.info(self.vapi.cli("sh gbp bridge"))
1512
1513 # ... and has a /32 applied
1514 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1515 ip_addr.add_vpp_config()
1516
1517 #
1518 # The Endpoint-group in which we are learning endpoints
1519 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001520 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001521 None, self.loop0,
1522 "10.0.0.128",
1523 "2001:10::128")
1524 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001525 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001526 None, self.loop1,
1527 "10.0.1.128",
1528 "2001:11::128")
1529 epg_330.add_vpp_config()
1530
1531 #
1532 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1533 # leanring enabled
1534 #
1535 vx_tun_l2_1 = VppGbpVxlanTunnel(
1536 self, 99, bd1.bd_id,
1537 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1538 vx_tun_l2_1.add_vpp_config()
1539
1540 #
1541 # A static endpoint that the learnt endpoints are trying to
1542 # talk to
1543 #
1544 ep = VppGbpEndpoint(self, self.pg0,
1545 epg_220, None,
1546 "10.0.0.127", "11.0.0.127",
1547 "2001:10::1", "3001::1")
1548 ep.add_vpp_config()
1549
1550 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1551
1552 # a packet with an sclass from an unknwon EPG
1553 p = (Ether(src=self.pg2.remote_mac,
1554 dst=self.pg2.local_mac) /
1555 IP(src=self.pg2.remote_hosts[0].ip4,
1556 dst=self.pg2.local_ip4) /
1557 UDP(sport=1234, dport=48879) /
1558 VXLAN(vni=99, gpid=88, flags=0x88) /
1559 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1560 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1561 UDP(sport=1234, dport=1234) /
1562 Raw('\xa5' * 100))
1563
1564 self.send_and_assert_no_replies(self.pg2, p)
1565
1566 #
1567 # we should not have learnt a new tunnel endpoint, since
1568 # the EPG was not learnt.
1569 #
1570 self.assertEqual(INDEX_INVALID,
1571 find_vxlan_gbp_tunnel(self,
1572 self.pg2.local_ip4,
1573 self.pg2.remote_hosts[0].ip4,
1574 99))
1575
1576 # epg is not learnt, becasue the EPG is unknwon
1577 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1578
1579 for ii, l in enumerate(learnt):
1580 # a packet with an sclass from a knwon EPG
1581 # arriving on an unknown TEP
1582 p = (Ether(src=self.pg2.remote_mac,
1583 dst=self.pg2.local_mac) /
1584 IP(src=self.pg2.remote_hosts[1].ip4,
1585 dst=self.pg2.local_ip4) /
1586 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001587 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001588 Ether(src=l['mac'], dst=ep.mac) /
1589 IP(src=l['ip'], dst=ep.ip4.address) /
1590 UDP(sport=1234, dport=1234) /
1591 Raw('\xa5' * 100))
1592
1593 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1594
1595 # the new TEP
1596 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1597 self,
1598 self.pg2.local_ip4,
1599 self.pg2.remote_hosts[1].ip4,
1600 99)
1601 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1602
1603 #
1604 # the EP is learnt via the learnt TEP
1605 # both from its MAC and its IP
1606 #
1607 self.assertTrue(find_gbp_endpoint(self,
1608 vx_tun_l2_1.sw_if_index,
1609 mac=l['mac']))
1610 self.assertTrue(find_gbp_endpoint(self,
1611 vx_tun_l2_1.sw_if_index,
1612 ip=l['ip']))
1613
1614 self.logger.info(self.vapi.cli("show gbp endpoint"))
1615 self.logger.info(self.vapi.cli("show gbp vxlan"))
1616 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1617
1618 #
1619 # If we sleep for the threshold time, the learnt endpoints should
1620 # age out
1621 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001622 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001623 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1624 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001625
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001626 #
1627 # repeat. the do not learn bit is set so the EPs are not learnt
1628 #
1629 for l in learnt:
1630 # a packet with an sclass from a knwon EPG
1631 p = (Ether(src=self.pg2.remote_mac,
1632 dst=self.pg2.local_mac) /
1633 IP(src=self.pg2.remote_hosts[1].ip4,
1634 dst=self.pg2.local_ip4) /
1635 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001636 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001637 Ether(src=l['mac'], dst=ep.mac) /
1638 IP(src=l['ip'], dst=ep.ip4.address) /
1639 UDP(sport=1234, dport=1234) /
1640 Raw('\xa5' * 100))
1641
1642 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1643
1644 for l in learnt:
1645 self.assertFalse(find_gbp_endpoint(self,
1646 vx_tun_l2_1.sw_if_index,
1647 mac=l['mac']))
1648
1649 #
1650 # repeat
1651 #
1652 for l in learnt:
1653 # a packet with an sclass from a knwon EPG
1654 p = (Ether(src=self.pg2.remote_mac,
1655 dst=self.pg2.local_mac) /
1656 IP(src=self.pg2.remote_hosts[1].ip4,
1657 dst=self.pg2.local_ip4) /
1658 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001659 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001660 Ether(src=l['mac'], dst=ep.mac) /
1661 IP(src=l['ip'], dst=ep.ip4.address) /
1662 UDP(sport=1234, dport=1234) /
1663 Raw('\xa5' * 100))
1664
1665 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1666
1667 self.assertTrue(find_gbp_endpoint(self,
1668 vx_tun_l2_1.sw_if_index,
1669 mac=l['mac']))
1670
1671 #
1672 # Static EP replies to dynamics
1673 #
1674 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1675 for l in learnt:
1676 p = (Ether(src=ep.mac, dst=l['mac']) /
1677 IP(dst=l['ip'], src=ep.ip4.address) /
1678 UDP(sport=1234, dport=1234) /
1679 Raw('\xa5' * 100))
1680
1681 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1682
1683 for rx in rxs:
1684 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1685 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1686 self.assertEqual(rx[UDP].dport, 48879)
1687 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001688 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001689 self.assertEqual(rx[VXLAN].vni, 99)
1690 self.assertTrue(rx[VXLAN].flags.G)
1691 self.assertTrue(rx[VXLAN].flags.Instance)
1692 self.assertTrue(rx[VXLAN].gpflags.A)
1693 self.assertFalse(rx[VXLAN].gpflags.D)
1694
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001695 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001696 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1697 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001698
1699 #
1700 # repeat in the other EPG
1701 # there's no contract between 220 and 330, but the A-bit is set
1702 # so the packet is cleared for delivery
1703 #
1704 for l in learnt:
1705 # a packet with an sclass from a knwon EPG
1706 p = (Ether(src=self.pg2.remote_mac,
1707 dst=self.pg2.local_mac) /
1708 IP(src=self.pg2.remote_hosts[1].ip4,
1709 dst=self.pg2.local_ip4) /
1710 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001711 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001712 Ether(src=l['mac'], dst=ep.mac) /
1713 IP(src=l['ip'], dst=ep.ip4.address) /
1714 UDP(sport=1234, dport=1234) /
1715 Raw('\xa5' * 100))
1716
1717 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1718
1719 self.assertTrue(find_gbp_endpoint(self,
1720 vx_tun_l2_1.sw_if_index,
1721 mac=l['mac']))
1722
1723 #
1724 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001725 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001726 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001727 p = (Ether(src=ep.mac, dst=l['mac']) /
1728 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1729 UDP(sport=1234, dport=1234) /
1730 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001731
Neale Ranns13a08cc2018-11-07 09:25:54 -08001732 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001733
1734 #
1735 # refresh the entries after the check for no replies above
1736 #
1737 for l in learnt:
1738 # a packet with an sclass from a knwon EPG
1739 p = (Ether(src=self.pg2.remote_mac,
1740 dst=self.pg2.local_mac) /
1741 IP(src=self.pg2.remote_hosts[1].ip4,
1742 dst=self.pg2.local_ip4) /
1743 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001744 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001745 Ether(src=l['mac'], dst=ep.mac) /
1746 IP(src=l['ip'], dst=ep.ip4.address) /
1747 UDP(sport=1234, dport=1234) /
1748 Raw('\xa5' * 100))
1749
1750 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1751
1752 self.assertTrue(find_gbp_endpoint(self,
1753 vx_tun_l2_1.sw_if_index,
1754 mac=l['mac']))
1755
1756 #
1757 # Add the contract so they can talk
1758 #
1759 acl = VppGbpAcl(self)
1760 rule = acl.create_rule(permit_deny=1, proto=17)
1761 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1762 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001763 c1 = VppGbpContract(
1764 self, 220, 330, acl_index,
1765 [VppGbpContractRule(
1766 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1767 []),
1768 VppGbpContractRule(
1769 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001770 [])],
1771 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001772 c1.add_vpp_config()
1773
1774 for l in learnt:
1775 p = (Ether(src=ep.mac, dst=l['mac']) /
1776 IP(dst=l['ip'], src=ep.ip4.address) /
1777 UDP(sport=1234, dport=1234) /
1778 Raw('\xa5' * 100))
1779
1780 self.send_and_expect(self.pg0, [p], self.pg2)
1781
1782 #
1783 # send UU packets from the local EP
1784 #
1785 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1786 self.logger.info(self.vapi.cli("sh gbp bridge"))
1787 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1788 IP(dst="10.0.0.133", src=ep.ip4.address) /
1789 UDP(sport=1234, dport=1234) /
1790 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001791 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001792
1793 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1794
1795 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1796 IP(dst="10.0.0.133", src=ep.ip4.address) /
1797 UDP(sport=1234, dport=1234) /
1798 Raw('\xa5' * 100))
1799 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1800
Neale Ranns879d11c2019-01-21 23:34:18 -08001801 for rx in rxs:
1802 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1803 self.assertEqual(rx[IP].dst, "239.1.1.1")
1804 self.assertEqual(rx[UDP].dport, 48879)
1805 # the UDP source port is a random value for hashing
1806 self.assertEqual(rx[VXLAN].gpid, 112)
1807 self.assertEqual(rx[VXLAN].vni, 88)
1808 self.assertTrue(rx[VXLAN].flags.G)
1809 self.assertTrue(rx[VXLAN].flags.Instance)
1810 self.assertFalse(rx[VXLAN].gpflags.A)
1811 self.assertFalse(rx[VXLAN].gpflags.D)
1812
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001813 #
1814 # Check v6 Endpoints
1815 #
1816 for l in learnt:
1817 # a packet with an sclass from a knwon EPG
1818 p = (Ether(src=self.pg2.remote_mac,
1819 dst=self.pg2.local_mac) /
1820 IP(src=self.pg2.remote_hosts[1].ip4,
1821 dst=self.pg2.local_ip4) /
1822 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001823 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001824 Ether(src=l['mac'], dst=ep.mac) /
1825 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1826 UDP(sport=1234, dport=1234) /
1827 Raw('\xa5' * 100))
1828
1829 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1830
1831 self.assertTrue(find_gbp_endpoint(self,
1832 vx_tun_l2_1.sw_if_index,
1833 mac=l['mac']))
1834
1835 #
1836 # L3 Endpoint Learning
1837 # - configured on the bridge's BVI
1838 #
1839
1840 #
1841 # clean up
1842 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001843 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001844 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1845 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001846
1847 self.pg2.unconfig_ip4()
1848 self.pg3.unconfig_ip4()
1849 self.pg4.unconfig_ip4()
1850
1851 self.logger.info(self.vapi.cli("sh int"))
1852 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1853
Neale Rannsc29c0af2018-11-07 04:21:12 -08001854 def test_gbp_learn_vlan_l2(self):
1855 """ GBP L2 Endpoint w/ VLANs"""
1856
Neale Rannsb6a47952018-11-21 05:44:35 -08001857 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001858 learnt = [{'mac': '00:00:11:11:11:01',
1859 'ip': '10.0.0.1',
1860 'ip6': '2001:10::2'},
1861 {'mac': '00:00:11:11:11:02',
1862 'ip': '10.0.0.2',
1863 'ip6': '2001:10::3'}]
1864
1865 #
1866 # lower the inactive threshold so these tests pass in a
1867 # reasonable amount of time
1868 #
Neale Ranns00a469d2018-12-20 06:12:19 -08001869 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001870
1871 #
1872 # IP tables
1873 #
1874 gt4 = VppIpTable(self, 1)
1875 gt4.add_vpp_config()
1876 gt6 = VppIpTable(self, 1, is_ip6=True)
1877 gt6.add_vpp_config()
1878
1879 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1880 rd1.add_vpp_config()
1881
1882 #
1883 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1884 #
1885 self.pg2.config_ip4()
1886 self.pg2.resolve_arp()
1887 self.pg2.generate_remote_hosts(4)
1888 self.pg2.configure_ipv4_neighbors()
1889 self.pg3.config_ip4()
1890 self.pg3.resolve_arp()
1891
1892 #
1893 # The EP will be on a vlan sub-interface
1894 #
1895 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1896 vlan_11.admin_up()
1897 self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index,
1898 L2_VTR_OP.L2_POP_1,
1899 11)
1900
1901 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1902 self.pg3.remote_ip4, 116)
1903 bd_uu_fwd.add_vpp_config()
1904
1905 #
1906 # a GBP bridge domain with a BVI and a UU-flood interface
1907 # The BD is marked as do not learn, so no endpoints are ever
1908 # learnt in this BD.
1909 #
1910 bd1 = VppBridgeDomain(self, 1)
1911 bd1.add_vpp_config()
1912 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1913 learn=False)
1914 gbd1.add_vpp_config()
1915
1916 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1917 self.logger.info(self.vapi.cli("sh gbp bridge"))
1918
1919 # ... and has a /32 applied
1920 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1921 ip_addr.add_vpp_config()
1922
1923 #
1924 # The Endpoint-group in which we are learning endpoints
1925 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001926 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08001927 None, self.loop0,
1928 "10.0.0.128",
1929 "2001:10::128")
1930 epg_220.add_vpp_config()
1931
1932 #
1933 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1934 # leanring enabled
1935 #
1936 vx_tun_l2_1 = VppGbpVxlanTunnel(
1937 self, 99, bd1.bd_id,
1938 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1939 vx_tun_l2_1.add_vpp_config()
1940
1941 #
1942 # A static endpoint that the learnt endpoints are trying to
1943 # talk to
1944 #
1945 ep = VppGbpEndpoint(self, vlan_11,
1946 epg_220, None,
1947 "10.0.0.127", "11.0.0.127",
1948 "2001:10::1", "3001::1")
1949 ep.add_vpp_config()
1950
1951 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1952
1953 #
1954 # Send to the static EP
1955 #
1956 for ii, l in enumerate(learnt):
1957 # a packet with an sclass from a knwon EPG
1958 # arriving on an unknown TEP
1959 p = (Ether(src=self.pg2.remote_mac,
1960 dst=self.pg2.local_mac) /
1961 IP(src=self.pg2.remote_hosts[1].ip4,
1962 dst=self.pg2.local_ip4) /
1963 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001964 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08001965 Ether(src=l['mac'], dst=ep.mac) /
1966 IP(src=l['ip'], dst=ep.ip4.address) /
1967 UDP(sport=1234, dport=1234) /
1968 Raw('\xa5' * 100))
1969
1970 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
1971
1972 #
1973 # packet to EP has the EP's vlan tag
1974 #
1975 for rx in rxs:
1976 self.assertEqual(rx[Dot1Q].vlan, 11)
1977
1978 #
1979 # the EP is not learnt since the BD setting prevents it
1980 # also no TEP too
1981 #
1982 self.assertFalse(find_gbp_endpoint(self,
1983 vx_tun_l2_1.sw_if_index,
1984 mac=l['mac']))
1985 self.assertEqual(INDEX_INVALID,
1986 find_vxlan_gbp_tunnel(
1987 self,
1988 self.pg2.local_ip4,
1989 self.pg2.remote_hosts[1].ip4,
1990 99))
1991
1992 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1993
1994 #
1995 # static to remotes
1996 # we didn't learn the remotes so they are sent to the UU-fwd
1997 #
1998 for l in learnt:
1999 p = (Ether(src=ep.mac, dst=l['mac']) /
2000 Dot1Q(vlan=11) /
2001 IP(dst=l['ip'], src=ep.ip4.address) /
2002 UDP(sport=1234, dport=1234) /
2003 Raw('\xa5' * 100))
2004
2005 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2006
2007 for rx in rxs:
2008 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2009 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2010 self.assertEqual(rx[UDP].dport, 48879)
2011 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002012 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002013 self.assertEqual(rx[VXLAN].vni, 116)
2014 self.assertTrue(rx[VXLAN].flags.G)
2015 self.assertTrue(rx[VXLAN].flags.Instance)
2016 self.assertFalse(rx[VXLAN].gpflags.A)
2017 self.assertFalse(rx[VXLAN].gpflags.D)
2018
2019 self.pg2.unconfig_ip4()
2020 self.pg3.unconfig_ip4()
2021
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002022 def test_gbp_learn_l3(self):
2023 """ GBP L3 Endpoint Learning """
2024
Neale Ranns13a08cc2018-11-07 09:25:54 -08002025 self.vapi.cli("set logging class gbp debug")
2026
Neale Rannsb6a47952018-11-21 05:44:35 -08002027 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002028 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2029 routed_src_mac = "00:22:bd:f8:19:ff"
2030
2031 learnt = [{'mac': '00:00:11:11:11:02',
2032 'ip': '10.0.1.2',
2033 'ip6': '2001:10::2'},
2034 {'mac': '00:00:11:11:11:03',
2035 'ip': '10.0.1.3',
2036 'ip6': '2001:10::3'}]
2037
2038 #
2039 # lower the inactive threshold so these tests pass in a
2040 # reasonable amount of time
2041 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002042 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002043
2044 #
2045 # IP tables
2046 #
2047 t4 = VppIpTable(self, 1)
2048 t4.add_vpp_config()
2049 t6 = VppIpTable(self, 1, True)
2050 t6.add_vpp_config()
2051
2052 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2053 self.pg4.remote_ip4, 114)
2054 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2055 self.pg4.remote_ip4, 116)
2056 tun_ip4_uu.add_vpp_config()
2057 tun_ip6_uu.add_vpp_config()
2058
2059 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2060 rd1.add_vpp_config()
2061
Ole Troan8006c6a2018-12-17 12:02:26 +01002062 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002063
2064 #
2065 # Bind the BVI to the RD
2066 #
2067 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2068 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2069
2070 #
2071 # Pg2 hosts the vxlan tunnel
2072 # hosts on pg2 to act as TEPs
2073 # pg3 is BD uu-fwd
2074 # pg4 is RD uu-fwd
2075 #
2076 self.pg2.config_ip4()
2077 self.pg2.resolve_arp()
2078 self.pg2.generate_remote_hosts(4)
2079 self.pg2.configure_ipv4_neighbors()
2080 self.pg3.config_ip4()
2081 self.pg3.resolve_arp()
2082 self.pg4.config_ip4()
2083 self.pg4.resolve_arp()
2084
2085 #
2086 # a GBP bridge domain with a BVI and a UU-flood interface
2087 #
2088 bd1 = VppBridgeDomain(self, 1)
2089 bd1.add_vpp_config()
2090 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2091 gbd1.add_vpp_config()
2092
2093 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2094 self.logger.info(self.vapi.cli("sh gbp bridge"))
2095 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002096
2097 # ... and has a /32 and /128 applied
2098 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2099 ip4_addr.add_vpp_config()
2100 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2101 ip6_addr.add_vpp_config()
2102
2103 #
2104 # The Endpoint-group in which we are learning endpoints
2105 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002106 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002107 None, self.loop0,
2108 "10.0.0.128",
2109 "2001:10::128")
2110 epg_220.add_vpp_config()
2111
2112 #
2113 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2114 # leanring enabled
2115 #
2116 vx_tun_l3 = VppGbpVxlanTunnel(
2117 self, 101, rd1.rd_id,
2118 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2119 vx_tun_l3.add_vpp_config()
2120
2121 #
2122 # A static endpoint that the learnt endpoints are trying to
2123 # talk to
2124 #
2125 ep = VppGbpEndpoint(self, self.pg0,
2126 epg_220, None,
2127 "10.0.0.127", "11.0.0.127",
2128 "2001:10::1", "3001::1")
2129 ep.add_vpp_config()
2130
2131 #
2132 # learn some remote IPv4 EPs
2133 #
2134 for ii, l in enumerate(learnt):
2135 # a packet with an sclass from a knwon EPG
2136 # arriving on an unknown TEP
2137 p = (Ether(src=self.pg2.remote_mac,
2138 dst=self.pg2.local_mac) /
2139 IP(src=self.pg2.remote_hosts[1].ip4,
2140 dst=self.pg2.local_ip4) /
2141 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002142 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002143 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2144 IP(src=l['ip'], dst=ep.ip4.address) /
2145 UDP(sport=1234, dport=1234) /
2146 Raw('\xa5' * 100))
2147
2148 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2149
2150 # the new TEP
2151 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2152 self,
2153 self.pg2.local_ip4,
2154 self.pg2.remote_hosts[1].ip4,
2155 vx_tun_l3.vni)
2156 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2157
2158 # endpoint learnt via the parent GBP-vxlan interface
2159 self.assertTrue(find_gbp_endpoint(self,
2160 vx_tun_l3._sw_if_index,
2161 ip=l['ip']))
2162
2163 #
2164 # Static IPv4 EP replies to learnt
2165 #
2166 for l in learnt:
2167 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2168 IP(dst=l['ip'], src=ep.ip4.address) /
2169 UDP(sport=1234, dport=1234) /
2170 Raw('\xa5' * 100))
2171
2172 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2173
2174 for rx in rxs:
2175 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2176 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2177 self.assertEqual(rx[UDP].dport, 48879)
2178 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002179 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002180 self.assertEqual(rx[VXLAN].vni, 101)
2181 self.assertTrue(rx[VXLAN].flags.G)
2182 self.assertTrue(rx[VXLAN].flags.Instance)
2183 self.assertTrue(rx[VXLAN].gpflags.A)
2184 self.assertFalse(rx[VXLAN].gpflags.D)
2185
2186 inner = rx[VXLAN].payload
2187
2188 self.assertEqual(inner[Ether].src, routed_src_mac)
2189 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2190 self.assertEqual(inner[IP].src, ep.ip4.address)
2191 self.assertEqual(inner[IP].dst, l['ip'])
2192
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002193 for l in learnt:
2194 self.assertFalse(find_gbp_endpoint(self,
2195 tep1_sw_if_index,
2196 ip=l['ip']))
2197
2198 #
2199 # learn some remote IPv6 EPs
2200 #
2201 for ii, l in enumerate(learnt):
2202 # a packet with an sclass from a knwon EPG
2203 # arriving on an unknown TEP
2204 p = (Ether(src=self.pg2.remote_mac,
2205 dst=self.pg2.local_mac) /
2206 IP(src=self.pg2.remote_hosts[1].ip4,
2207 dst=self.pg2.local_ip4) /
2208 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002209 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002210 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2211 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2212 UDP(sport=1234, dport=1234) /
2213 Raw('\xa5' * 100))
2214
2215 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2216
2217 # the new TEP
2218 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2219 self,
2220 self.pg2.local_ip4,
2221 self.pg2.remote_hosts[1].ip4,
2222 vx_tun_l3.vni)
2223 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2224
2225 self.logger.info(self.vapi.cli("show gbp bridge"))
2226 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2227 self.logger.info(self.vapi.cli("show gbp vxlan"))
2228 self.logger.info(self.vapi.cli("show int addr"))
2229
2230 # endpoint learnt via the TEP
2231 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2232
2233 self.logger.info(self.vapi.cli("show gbp endpoint"))
2234 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2235
2236 #
2237 # Static EP replies to learnt
2238 #
2239 for l in learnt:
2240 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2241 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2242 UDP(sport=1234, dport=1234) /
2243 Raw('\xa5' * 100))
2244
2245 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2246
2247 for rx in rxs:
2248 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2249 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2250 self.assertEqual(rx[UDP].dport, 48879)
2251 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002252 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002253 self.assertEqual(rx[VXLAN].vni, 101)
2254 self.assertTrue(rx[VXLAN].flags.G)
2255 self.assertTrue(rx[VXLAN].flags.Instance)
2256 self.assertTrue(rx[VXLAN].gpflags.A)
2257 self.assertFalse(rx[VXLAN].gpflags.D)
2258
2259 inner = rx[VXLAN].payload
2260
2261 self.assertEqual(inner[Ether].src, routed_src_mac)
2262 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2263 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2264 self.assertEqual(inner[IPv6].dst, l['ip6'])
2265
2266 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002267 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002268 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002269
2270 #
2271 # Static sends to unknown EP with no route
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 self.send_and_assert_no_replies(self.pg0, [p])
2279
2280 #
2281 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002282 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002283 #
2284 se_10_24 = VppGbpSubnet(
2285 self, rd1, "10.0.0.0", 24,
2286 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2287 se_10_24.add_vpp_config()
2288
2289 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2290 IP(dst="10.0.0.99", src=ep.ip4.address) /
2291 UDP(sport=1234, dport=1234) /
2292 Raw('\xa5' * 100))
2293
2294 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2295 for rx in rxs:
2296 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2297 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2298 self.assertEqual(rx[UDP].dport, 48879)
2299 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002300 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002301 self.assertEqual(rx[VXLAN].vni, 114)
2302 self.assertTrue(rx[VXLAN].flags.G)
2303 self.assertTrue(rx[VXLAN].flags.Instance)
2304 # policy is not applied to packets sent to the uu-fwd interfaces
2305 self.assertFalse(rx[VXLAN].gpflags.A)
2306 self.assertFalse(rx[VXLAN].gpflags.D)
2307
2308 #
2309 # learn some remote IPv4 EPs
2310 #
2311 for ii, l in enumerate(learnt):
2312 # a packet with an sclass from a knwon EPG
2313 # arriving on an unknown TEP
2314 p = (Ether(src=self.pg2.remote_mac,
2315 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002316 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002317 dst=self.pg2.local_ip4) /
2318 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002319 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002320 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2321 IP(src=l['ip'], dst=ep.ip4.address) /
2322 UDP(sport=1234, dport=1234) /
2323 Raw('\xa5' * 100))
2324
2325 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2326
2327 # the new TEP
2328 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2329 self,
2330 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002331 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002332 vx_tun_l3.vni)
2333 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2334
2335 # endpoint learnt via the parent GBP-vxlan interface
2336 self.assertTrue(find_gbp_endpoint(self,
2337 vx_tun_l3._sw_if_index,
2338 ip=l['ip']))
2339
2340 #
2341 # Add a remote endpoint from the API
2342 #
2343 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2344 epg_220, None,
2345 "10.0.0.88", "11.0.0.88",
2346 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002347 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002348 self.pg2.local_ip4,
2349 self.pg2.remote_hosts[1].ip4,
2350 mac=None)
2351 rep_88.add_vpp_config()
2352
2353 #
2354 # Add a remote endpoint from the API that matches an existing one
2355 #
2356 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2357 epg_220, None,
2358 learnt[0]['ip'], "11.0.0.101",
2359 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002360 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002361 self.pg2.local_ip4,
2362 self.pg2.remote_hosts[1].ip4,
2363 mac=None)
2364 rep_2.add_vpp_config()
2365
2366 #
2367 # Add a route to the leanred EP's v4 subnet
2368 # packets should be send on the v4/v6 uu=fwd interface resp.
2369 #
2370 se_10_1_24 = VppGbpSubnet(
2371 self, rd1, "10.0.1.0", 24,
2372 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2373 se_10_1_24.add_vpp_config()
2374
2375 self.logger.info(self.vapi.cli("show gbp endpoint"))
2376
2377 ips = ["10.0.0.88", learnt[0]['ip']]
2378 for ip in ips:
2379 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2380 IP(dst=ip, src=ep.ip4.address) /
2381 UDP(sport=1234, dport=1234) /
2382 Raw('\xa5' * 100))
2383
2384 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2385
2386 for rx in rxs:
2387 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2388 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2389 self.assertEqual(rx[UDP].dport, 48879)
2390 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002391 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002392 self.assertEqual(rx[VXLAN].vni, 101)
2393 self.assertTrue(rx[VXLAN].flags.G)
2394 self.assertTrue(rx[VXLAN].flags.Instance)
2395 self.assertTrue(rx[VXLAN].gpflags.A)
2396 self.assertFalse(rx[VXLAN].gpflags.D)
2397
2398 inner = rx[VXLAN].payload
2399
2400 self.assertEqual(inner[Ether].src, routed_src_mac)
2401 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2402 self.assertEqual(inner[IP].src, ep.ip4.address)
2403 self.assertEqual(inner[IP].dst, ip)
2404
2405 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002406 # remove the API remote EPs, only API sourced is gone, the DP
2407 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002408 #
2409 rep_88.remove_vpp_config()
2410 rep_2.remove_vpp_config()
2411
Neale Ranns00a469d2018-12-20 06:12:19 -08002412 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2413
2414 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2415 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2416 UDP(sport=1234, dport=1234) /
2417 Raw('\xa5' * 100))
2418 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002419
Neale Ranns13a08cc2018-11-07 09:25:54 -08002420 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002421
Neale Ranns13a08cc2018-11-07 09:25:54 -08002422 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2423 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2424 UDP(sport=1234, dport=1234) /
2425 Raw('\xa5' * 100))
2426 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002427
Neale Ranns13a08cc2018-11-07 09:25:54 -08002428 #
2429 # to appease the testcase we cannot have the registered EP stll
2430 # present (because it's DP learnt) when the TC ends so wait until
2431 # it is removed
2432 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002433 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2434 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002435
2436 #
2437 # shutdown with learnt endpoint present
2438 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002439 p = (Ether(src=self.pg2.remote_mac,
2440 dst=self.pg2.local_mac) /
2441 IP(src=self.pg2.remote_hosts[1].ip4,
2442 dst=self.pg2.local_ip4) /
2443 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002444 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002445 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2446 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2447 UDP(sport=1234, dport=1234) /
2448 Raw('\xa5' * 100))
2449
2450 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2451
2452 # endpoint learnt via the parent GBP-vxlan interface
2453 self.assertTrue(find_gbp_endpoint(self,
2454 vx_tun_l3._sw_if_index,
2455 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002456
2457 #
2458 # TODO
2459 # remote endpoint becomes local
2460 #
2461 self.pg2.unconfig_ip4()
2462 self.pg3.unconfig_ip4()
2463 self.pg4.unconfig_ip4()
2464
Neale Ranns13a08cc2018-11-07 09:25:54 -08002465 def test_gbp_redirect(self):
2466 """ GBP Endpoint Redirect """
2467
2468 self.vapi.cli("set logging class gbp debug")
2469
Neale Rannsb6a47952018-11-21 05:44:35 -08002470 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002471 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2472 routed_src_mac = "00:22:bd:f8:19:ff"
2473
2474 learnt = [{'mac': '00:00:11:11:11:02',
2475 'ip': '10.0.1.2',
2476 'ip6': '2001:10::2'},
2477 {'mac': '00:00:11:11:11:03',
2478 'ip': '10.0.1.3',
2479 'ip6': '2001:10::3'}]
2480
2481 #
2482 # lower the inactive threshold so these tests pass in a
2483 # reasonable amount of time
2484 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002485 self.vapi.gbp_endpoint_learn_set_inactive_threshold(2)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002486
2487 #
2488 # IP tables
2489 #
2490 t4 = VppIpTable(self, 1)
2491 t4.add_vpp_config()
2492 t6 = VppIpTable(self, 1, True)
2493 t6.add_vpp_config()
2494
2495 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2496 rd1.add_vpp_config()
2497
Ole Troan8006c6a2018-12-17 12:02:26 +01002498 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002499
2500 #
2501 # Bind the BVI to the RD
2502 #
2503 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2504 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2505
2506 #
2507 # Pg7 hosts a BD's UU-fwd
2508 #
2509 self.pg7.config_ip4()
2510 self.pg7.resolve_arp()
2511
2512 #
2513 # a GBP bridge domains for the EPs
2514 #
2515 bd1 = VppBridgeDomain(self, 1)
2516 bd1.add_vpp_config()
2517 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2518 gbd1.add_vpp_config()
2519
2520 bd2 = VppBridgeDomain(self, 2)
2521 bd2.add_vpp_config()
2522 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2523 gbd2.add_vpp_config()
2524
2525 # ... and has a /32 and /128 applied
2526 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2527 ip4_addr.add_vpp_config()
2528 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2529 ip6_addr.add_vpp_config()
2530 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2531 ip4_addr.add_vpp_config()
2532 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2533 ip6_addr.add_vpp_config()
2534
2535 #
2536 # The Endpoint-groups in which we are learning endpoints
2537 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002538 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002539 None, gbd1.bvi,
2540 "10.0.0.128",
2541 "2001:10::128")
2542 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002543 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002544 None, gbd2.bvi,
2545 "10.0.1.128",
2546 "2001:11::128")
2547 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002548 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002549 None, gbd1.bvi,
2550 "10.0.2.128",
2551 "2001:12::128")
2552 epg_222.add_vpp_config()
2553
2554 #
2555 # a GBP bridge domains for the SEPs
2556 #
2557 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2558 self.pg7.remote_ip4, 116)
2559 bd_uu1.add_vpp_config()
2560 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2561 self.pg7.remote_ip4, 117)
2562 bd_uu2.add_vpp_config()
2563
2564 bd3 = VppBridgeDomain(self, 3)
2565 bd3.add_vpp_config()
2566 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2567 gbd3.add_vpp_config()
2568 bd4 = VppBridgeDomain(self, 4)
2569 bd4.add_vpp_config()
2570 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2571 gbd4.add_vpp_config()
2572
2573 #
2574 # EPGs in which the service endpoints exist
2575 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002576 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002577 None, gbd1.bvi,
2578 "12.0.0.128",
2579 "4001:10::128")
2580 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002581 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002582 None, gbd2.bvi,
2583 "12.0.1.128",
2584 "4001:11::128")
2585 epg_321.add_vpp_config()
2586
2587 #
2588 # three local endpoints
2589 #
2590 ep1 = VppGbpEndpoint(self, self.pg0,
2591 epg_220, None,
2592 "10.0.0.1", "11.0.0.1",
2593 "2001:10::1", "3001:10::1")
2594 ep1.add_vpp_config()
2595 ep2 = VppGbpEndpoint(self, self.pg1,
2596 epg_221, None,
2597 "10.0.1.1", "11.0.1.1",
2598 "2001:11::1", "3001:11::1")
2599 ep2.add_vpp_config()
2600 ep3 = VppGbpEndpoint(self, self.pg2,
2601 epg_222, None,
2602 "10.0.2.2", "11.0.2.2",
2603 "2001:12::1", "3001:12::1")
2604 ep3.add_vpp_config()
2605
2606 #
2607 # service endpoints
2608 #
2609 sep1 = VppGbpEndpoint(self, self.pg3,
2610 epg_320, None,
2611 "12.0.0.1", "13.0.0.1",
2612 "4001:10::1", "5001:10::1")
2613 sep1.add_vpp_config()
2614 sep2 = VppGbpEndpoint(self, self.pg4,
2615 epg_320, None,
2616 "12.0.0.2", "13.0.0.2",
2617 "4001:10::2", "5001:10::2")
2618 sep2.add_vpp_config()
2619 sep3 = VppGbpEndpoint(self, self.pg5,
2620 epg_321, None,
2621 "12.0.1.1", "13.0.1.1",
2622 "4001:11::1", "5001:11::1")
2623 sep3.add_vpp_config()
2624 # this EP is not installed immediately
2625 sep4 = VppGbpEndpoint(self, self.pg6,
2626 epg_321, None,
2627 "12.0.1.2", "13.0.1.2",
2628 "4001:11::2", "5001:11::2")
2629
2630 #
2631 # an L2 switch packet between local EPs in different EPGs
2632 # different dest ports on each so the are LB hashed differently
2633 #
2634 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2635 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2636 UDP(sport=1234, dport=1234) /
2637 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002638 (Ether(src=ep3.mac, dst=ep1.mac) /
2639 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2640 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002641 Raw('\xa5' * 100))]
2642 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2643 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2644 UDP(sport=1234, dport=1234) /
2645 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002646 (Ether(src=ep3.mac, dst=ep1.mac) /
2647 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002648 UDP(sport=1234, dport=1230) /
2649 Raw('\xa5' * 100))]
2650
2651 # should be dropped since no contract yet
2652 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2653 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2654
2655 #
2656 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2657 # one of the next-hops is via an EP that is not known
2658 #
2659 acl = VppGbpAcl(self)
2660 rule4 = acl.create_rule(permit_deny=1, proto=17)
2661 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2662 acl_index = acl.add_vpp_config([rule4, rule6])
2663
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002664 #
2665 # test the src-ip hash mode
2666 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002667 c1 = VppGbpContract(
2668 self, 220, 222, acl_index,
2669 [VppGbpContractRule(
2670 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002671 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002672 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2673 sep1.ip4, sep1.epg.rd),
2674 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2675 sep2.ip4, sep2.epg.rd)]),
2676 VppGbpContractRule(
2677 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002678 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002679 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2680 sep3.ip6, sep3.epg.rd),
2681 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002682 sep4.ip6, sep4.epg.rd)])],
2683 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002684 c1.add_vpp_config()
2685
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002686 c2 = VppGbpContract(
2687 self, 222, 220, acl_index,
2688 [VppGbpContractRule(
2689 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2690 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2691 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2692 sep1.ip4, sep1.epg.rd),
2693 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2694 sep2.ip4, sep2.epg.rd)]),
2695 VppGbpContractRule(
2696 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2697 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2698 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2699 sep3.ip6, sep3.epg.rd),
2700 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002701 sep4.ip6, sep4.epg.rd)])],
2702 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002703 c2.add_vpp_config()
2704
Neale Ranns13a08cc2018-11-07 09:25:54 -08002705 #
2706 # send again with the contract preset, now packets arrive
2707 # at SEP1 or SEP2 depending on the hashing
2708 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002709 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002710
2711 for rx in rxs:
2712 self.assertEqual(rx[Ether].src, routed_src_mac)
2713 self.assertEqual(rx[Ether].dst, sep1.mac)
2714 self.assertEqual(rx[IP].src, ep1.ip4.address)
2715 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2716
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002717 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2718
2719 for rx in rxs:
2720 self.assertEqual(rx[Ether].src, routed_src_mac)
2721 self.assertEqual(rx[Ether].dst, sep2.mac)
2722 self.assertEqual(rx[IP].src, ep3.ip4.address)
2723 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2724
Neale Ranns13a08cc2018-11-07 09:25:54 -08002725 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2726
2727 for rx in rxs:
2728 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2729 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2730 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2731 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2732 self.assertEqual(rx[VXLAN].vni, 117)
2733 self.assertTrue(rx[VXLAN].flags.G)
2734 self.assertTrue(rx[VXLAN].flags.Instance)
2735 # redirect policy has been applied
2736 self.assertTrue(rx[VXLAN].gpflags.A)
2737 self.assertFalse(rx[VXLAN].gpflags.D)
2738
2739 inner = rx[VXLAN].payload
2740
2741 self.assertEqual(inner[Ether].src, routed_src_mac)
2742 self.assertEqual(inner[Ether].dst, sep4.mac)
2743 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2744 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2745
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002746 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002747
2748 for rx in rxs:
2749 self.assertEqual(rx[Ether].src, routed_src_mac)
2750 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002751 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2752 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002753
2754 #
2755 # programme the unknown EP
2756 #
2757 sep4.add_vpp_config()
2758
2759 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2760
2761 for rx in rxs:
2762 self.assertEqual(rx[Ether].src, routed_src_mac)
2763 self.assertEqual(rx[Ether].dst, sep4.mac)
2764 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2765 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2766
2767 #
2768 # and revert back to unprogrammed
2769 #
2770 sep4.remove_vpp_config()
2771
2772 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2773
2774 for rx in rxs:
2775 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2776 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2777 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2778 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2779 self.assertEqual(rx[VXLAN].vni, 117)
2780 self.assertTrue(rx[VXLAN].flags.G)
2781 self.assertTrue(rx[VXLAN].flags.Instance)
2782 # redirect policy has been applied
2783 self.assertTrue(rx[VXLAN].gpflags.A)
2784 self.assertFalse(rx[VXLAN].gpflags.D)
2785
2786 inner = rx[VXLAN].payload
2787
2788 self.assertEqual(inner[Ether].src, routed_src_mac)
2789 self.assertEqual(inner[Ether].dst, sep4.mac)
2790 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2791 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2792
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002793 c1.remove_vpp_config()
2794 c2.remove_vpp_config()
2795
2796 #
2797 # test the symmetric hash mode
2798 #
2799 c1 = VppGbpContract(
2800 self, 220, 222, acl_index,
2801 [VppGbpContractRule(
2802 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2803 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2804 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2805 sep1.ip4, sep1.epg.rd),
2806 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2807 sep2.ip4, sep2.epg.rd)]),
2808 VppGbpContractRule(
2809 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2810 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2811 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2812 sep3.ip6, sep3.epg.rd),
2813 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002814 sep4.ip6, sep4.epg.rd)])],
2815 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002816 c1.add_vpp_config()
2817
2818 c2 = VppGbpContract(
2819 self, 222, 220, acl_index,
2820 [VppGbpContractRule(
2821 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2822 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2823 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2824 sep1.ip4, sep1.epg.rd),
2825 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2826 sep2.ip4, sep2.epg.rd)]),
2827 VppGbpContractRule(
2828 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2829 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2830 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2831 sep3.ip6, sep3.epg.rd),
2832 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002833 sep4.ip6, sep4.epg.rd)])],
2834 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002835 c2.add_vpp_config()
2836
2837 #
2838 # send again with the contract preset, now packets arrive
2839 # at SEP1 for both directions
2840 #
2841 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2842
2843 for rx in rxs:
2844 self.assertEqual(rx[Ether].src, routed_src_mac)
2845 self.assertEqual(rx[Ether].dst, sep1.mac)
2846 self.assertEqual(rx[IP].src, ep1.ip4.address)
2847 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2848
2849 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2850
2851 for rx in rxs:
2852 self.assertEqual(rx[Ether].src, routed_src_mac)
2853 self.assertEqual(rx[Ether].dst, sep1.mac)
2854 self.assertEqual(rx[IP].src, ep3.ip4.address)
2855 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2856
Neale Ranns13a08cc2018-11-07 09:25:54 -08002857 #
2858 # programme the unknown EP for the L3 tests
2859 #
2860 sep4.add_vpp_config()
2861
2862 #
2863 # an L3 switch packet between local EPs in different EPGs
2864 # different dest ports on each so the are LB hashed differently
2865 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002866 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002867 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2868 UDP(sport=1234, dport=1234) /
2869 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002870 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002871 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2872 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002873 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002874 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002875 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2876 UDP(sport=1234, dport=1234) /
2877 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002878 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002879 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2880 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002881 Raw('\xa5' * 100))]
2882
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002883 c3 = VppGbpContract(
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002884 self, 220, 221, acl_index,
2885 [VppGbpContractRule(
2886 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2887 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2888 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2889 sep1.ip4, sep1.epg.rd),
2890 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2891 sep2.ip4, sep2.epg.rd)]),
2892 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002893 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002894 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002895 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2896 sep3.ip6, sep3.epg.rd),
2897 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2898 sep4.ip6, sep4.epg.rd)])],
2899 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002900 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002901
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002902 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002903
2904 for rx in rxs:
2905 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002906 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002907 self.assertEqual(rx[IP].src, ep1.ip4.address)
2908 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2909
2910 #
2911 # learn a remote EP in EPG 221
2912 #
2913 vx_tun_l3 = VppGbpVxlanTunnel(
2914 self, 444, rd1.rd_id,
2915 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2916 vx_tun_l3.add_vpp_config()
2917
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002918 c4 = VppGbpContract(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002919 self, 221, 220, acl_index,
2920 [VppGbpContractRule(
2921 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2922 []),
2923 VppGbpContractRule(
2924 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002925 [])],
2926 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002927 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002928
2929 p = (Ether(src=self.pg7.remote_mac,
2930 dst=self.pg7.local_mac) /
2931 IP(src=self.pg7.remote_ip4,
2932 dst=self.pg7.local_ip4) /
2933 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002934 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01002935 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002936 IP(src="10.0.0.88", dst=ep1.ip4.address) /
2937 UDP(sport=1234, dport=1234) /
2938 Raw('\xa5' * 100))
2939
2940 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2941
2942 # endpoint learnt via the parent GBP-vxlan interface
2943 self.assertTrue(find_gbp_endpoint(self,
2944 vx_tun_l3._sw_if_index,
2945 ip="10.0.0.88"))
2946
2947 p = (Ether(src=self.pg7.remote_mac,
2948 dst=self.pg7.local_mac) /
2949 IP(src=self.pg7.remote_ip4,
2950 dst=self.pg7.local_ip4) /
2951 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002952 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01002953 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002954 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
2955 UDP(sport=1234, dport=1234) /
2956 Raw('\xa5' * 100))
2957
2958 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2959
2960 # endpoint learnt via the parent GBP-vxlan interface
2961 self.assertTrue(find_gbp_endpoint(self,
2962 vx_tun_l3._sw_if_index,
2963 ip="2001:10::88"))
2964
2965 #
2966 # L3 switch from local to remote EP
2967 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002968 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002969 IP(src=ep1.ip4.address, dst="10.0.0.88") /
2970 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002971 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002972 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002973 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
2974 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002975 Raw('\xa5' * 100))]
2976
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002977 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002978
2979 for rx in rxs:
2980 self.assertEqual(rx[Ether].src, routed_src_mac)
2981 self.assertEqual(rx[Ether].dst, sep1.mac)
2982 self.assertEqual(rx[IP].src, ep1.ip4.address)
2983 self.assertEqual(rx[IP].dst, "10.0.0.88")
2984
2985 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2986
2987 for rx in rxs:
2988 self.assertEqual(rx[Ether].src, routed_src_mac)
2989 self.assertEqual(rx[Ether].dst, sep4.mac)
2990 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2991 self.assertEqual(rx[IPv6].dst, "2001:10::88")
2992
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002993 #
2994 # test the dst-ip hash mode
2995 #
2996 c5 = VppGbpContract(
2997 self, 220, 221, acl_index,
2998 [VppGbpContractRule(
2999 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3000 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3001 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3002 sep1.ip4, sep1.epg.rd),
3003 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3004 sep2.ip4, sep2.epg.rd)]),
3005 VppGbpContractRule(
3006 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3007 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3008 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3009 sep3.ip6, sep3.epg.rd),
3010 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003011 sep4.ip6, sep4.epg.rd)])],
3012 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003013 c5.add_vpp_config()
3014
3015 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3016
3017 for rx in rxs:
3018 self.assertEqual(rx[Ether].src, routed_src_mac)
3019 self.assertEqual(rx[Ether].dst, sep1.mac)
3020 self.assertEqual(rx[IP].src, ep1.ip4.address)
3021 self.assertEqual(rx[IP].dst, "10.0.0.88")
3022
3023 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003024
3025 for rx in rxs:
3026 self.assertEqual(rx[Ether].src, routed_src_mac)
3027 self.assertEqual(rx[Ether].dst, sep3.mac)
3028 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3029 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3030
Neale Rannsb6a47952018-11-21 05:44:35 -08003031 #
3032 # cleanup
3033 #
3034 self.pg7.unconfig_ip4()
3035
3036 def test_gbp_l3_out(self):
3037 """ GBP L3 Out """
3038
3039 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3040 self.vapi.cli("set logging class gbp debug")
3041
3042 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3043 routed_src_mac = "00:22:bd:f8:19:ff"
3044
3045 #
3046 # IP tables
3047 #
3048 t4 = VppIpTable(self, 1)
3049 t4.add_vpp_config()
3050 t6 = VppIpTable(self, 1, True)
3051 t6.add_vpp_config()
3052
3053 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3054 rd1.add_vpp_config()
3055
Ole Troan8006c6a2018-12-17 12:02:26 +01003056 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003057
3058 #
3059 # Bind the BVI to the RD
3060 #
3061 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3062 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3063
3064 #
3065 # Pg7 hosts a BD's BUM
3066 # Pg1 some other l3 interface
3067 #
3068 self.pg7.config_ip4()
3069 self.pg7.resolve_arp()
3070
3071 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003072 # a multicast vxlan-gbp tunnel for broadcast in the BD
3073 #
3074 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3075 "239.1.1.1", 88,
3076 mcast_itf=self.pg7)
3077 tun_bm.add_vpp_config()
3078
3079 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003080 # a GBP external bridge domains for the EPs
3081 #
3082 bd1 = VppBridgeDomain(self, 1)
3083 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003084 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003085 gbd1.add_vpp_config()
3086
3087 #
3088 # The Endpoint-groups in which the external endpoints exist
3089 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003090 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003091 None, gbd1.bvi,
3092 "10.0.0.128",
3093 "2001:10::128")
3094 epg_220.add_vpp_config()
3095
3096 # the BVIs have the subnets applied ...
3097 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3098 ip4_addr.add_vpp_config()
3099 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3100 ip6_addr.add_vpp_config()
3101
3102 # ... which are L3-out subnets
3103 l3o_1 = VppGbpSubnet(
3104 self, rd1, "10.0.0.0", 24,
3105 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns879d11c2019-01-21 23:34:18 -08003106 epg=220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003107 l3o_1.add_vpp_config()
3108
3109 #
3110 # an external interface attached to the outside world and the
3111 # external BD
3112 #
3113 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3114 vlan_100.admin_up()
3115 ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1)
3116 ext_itf.add_vpp_config()
3117
3118 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003119 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003120 #
3121 vx_tun_l3 = VppGbpVxlanTunnel(
3122 self, 444, rd1.rd_id,
3123 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
3124 vx_tun_l3.add_vpp_config()
3125
3126 #
3127 # packets destined to unkown addresses in the BVI's subnet
3128 # are ARP'd for
3129 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003130 p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003131 Dot1Q(vlan=100) /
3132 IP(src="10.0.0.1", dst="10.0.0.88") /
3133 UDP(sport=1234, dport=1234) /
3134 Raw('\xa5' * 100))
Ole Troan8006c6a2018-12-17 12:02:26 +01003135 p6 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003136 Dot1Q(vlan=100) /
3137 IPv6(src="2001:10::1", dst="2001:10::88") /
3138 UDP(sport=1234, dport=1234) /
3139 Raw('\xa5' * 100))
3140
3141 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3142
3143 for rx in rxs:
3144 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3145 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3146 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3147 self.assertEqual(rx[IP].dst, "239.1.1.1")
3148 self.assertEqual(rx[VXLAN].vni, 88)
3149 self.assertTrue(rx[VXLAN].flags.G)
3150 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003151 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003152 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003153 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003154 self.assertFalse(rx[VXLAN].gpflags.D)
3155
3156 inner = rx[VXLAN].payload
3157
3158 self.assertTrue(inner.haslayer(ARP))
3159
3160 #
3161 # An external Endpoint
3162 #
3163 eep = VppGbpEndpoint(self, vlan_100,
3164 epg_220, None,
3165 "10.0.0.1", "11.0.0.1",
3166 "2001:10::1", "3001::1",
3167 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3168 eep.add_vpp_config()
3169
3170 #
3171 # A remote endpoint
3172 #
3173 rep = VppGbpEndpoint(self, vx_tun_l3,
3174 epg_220, None,
3175 "10.0.0.101", "11.0.0.101",
3176 "2001:10::101", "3001::101",
3177 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3178 self.pg7.local_ip4,
3179 self.pg7.remote_ip4,
3180 mac=None)
3181 rep.add_vpp_config()
3182
3183 #
3184 # remote to external
3185 #
3186 p = (Ether(src=self.pg7.remote_mac,
3187 dst=self.pg7.local_mac) /
3188 IP(src=self.pg7.remote_ip4,
3189 dst=self.pg7.local_ip4) /
3190 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003191 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003192 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003193 IP(src="10.0.0.101", dst="10.0.0.1") /
3194 UDP(sport=1234, dport=1234) /
3195 Raw('\xa5' * 100))
3196
3197 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3198
3199 #
3200 # A subnet reachable through the external EP
3201 #
3202 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
3203 [VppRoutePath(eep.ip4.address,
3204 eep.epg.bvi.sw_if_index)],
3205 table_id=t4.table_id)
3206 ip_220.add_vpp_config()
3207
3208 l3o_220 = VppGbpSubnet(
3209 self, rd1, "10.220.0.0", 24,
3210 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3211 epg=220)
3212 l3o_220.add_vpp_config()
3213
3214 p = (Ether(src=self.pg7.remote_mac,
3215 dst=self.pg7.local_mac) /
3216 IP(src=self.pg7.remote_ip4,
3217 dst=self.pg7.local_ip4) /
3218 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003219 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003220 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003221 IP(src="10.0.0.101", dst="10.220.0.1") /
3222 UDP(sport=1234, dport=1234) /
3223 Raw('\xa5' * 100))
3224
3225 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3226
3227 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003228 # cleanup
3229 #
3230 self.pg7.unconfig_ip4()
3231
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003232
3233if __name__ == '__main__':
3234 unittest.main(testRunner=VppTestRunner)