blob: 4d8328474b9011d9329c977365095f0752d6c6c8 [file] [log] [blame]
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001#!/usr/bin/env python
2
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08003from socket import AF_INET, AF_INET6
Neale Rannsbc27d1b2018-02-05 01:13:38 -08004import unittest
Neale Rannsbc27d1b2018-02-05 01:13:38 -08005
Neale Rannsbc27d1b2018-02-05 01:13:38 -08006from scapy.packet import Raw
Neale Rannsc29c0af2018-11-07 04:21:12 -08007from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Ranns36abbf12019-03-12 02:34:07 -07008from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns25b04942018-04-04 09:34:50 -07009from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
Klement Sekerab9ef2732018-06-24 22:49:33 +020010 ICMPv6ND_NA
Neale Ranns25b04942018-04-04 09:34:50 -070011from scapy.utils6 import in6_getnsma, in6_getnsmac
Neale Ranns93cc3ee2018-10-10 07:22:51 -070012from scapy.layers.vxlan import VXLAN
Neale Ranns1c17e2e2018-12-20 12:03:59 -080013from scapy.data import ETH_P_IP, ETH_P_IPV6
Neale Ranns25b04942018-04-04 09:34:50 -070014from scapy.utils import inet_pton, inet_ntop
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080015
16from framework import VppTestCase, VppTestRunner
17from vpp_object import VppObject
18from vpp_interface import VppInterface
19from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \
20 VppIpInterfaceAddress, VppIpInterfaceBind, find_route
21from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
Neale Ranns36abbf12019-03-12 02:34:07 -070022 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080023from vpp_sub_interface import VppDot1QSubint
24from vpp_ip import VppIpAddress, VppIpPrefix
25from vpp_papi import VppEnum, MACAddress
Neale Rannsc29c0af2018-11-07 04:21:12 -080026from vpp_papi_provider import L2_VTR_OP
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080027from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \
28 VppVxlanGbpTunnel
Neale Rannsbc27d1b2018-02-05 01:13:38 -080029
30
Neale Ranns93cc3ee2018-10-10 07:22:51 -070031def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None):
32 if ip:
33 vip = VppIpAddress(ip)
34 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010035 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070036
37 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070038
Neale Rannsc0a93142018-09-05 15:42:26 -070039 for ep in eps:
Neale Ranns93cc3ee2018-10-10 07:22:51 -070040 if sw_if_index:
41 if ep.endpoint.sw_if_index != sw_if_index:
42 continue
43 if ip:
44 for eip in ep.endpoint.ips:
45 if vip == eip:
46 return True
47 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010048 if vmac.packed == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070049 return True
50 return False
51
52
Neale Ranns93cc3ee2018-10-10 07:22:51 -070053def find_gbp_vxlan(test, vni):
54 ts = test.vapi.gbp_vxlan_tunnel_dump()
55 for t in ts:
56 if t.tunnel.vni == vni:
57 return True
58 return False
59
60
Neale Rannsbc27d1b2018-02-05 01:13:38 -080061class VppGbpEndpoint(VppObject):
62 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020063 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080064 """
65
Neale Ranns25b04942018-04-04 09:34:50 -070066 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -070067 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +010068 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -070069
70 @property
Neale Rannsc0a93142018-09-05 15:42:26 -070071 def ip4(self):
72 return self._ip4
73
74 @property
75 def fip4(self):
76 return self._fip4
77
78 @property
79 def ip6(self):
80 return self._ip6
81
82 @property
83 def fip6(self):
84 return self._fip6
85
86 @property
87 def ips(self):
88 return [self.ip4, self.ip6]
89
90 @property
91 def fips(self):
92 return [self.fip4, self.fip6]
93
Neale Ranns93cc3ee2018-10-10 07:22:51 -070094 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
95 flags=0,
96 tun_src="0.0.0.0",
97 tun_dst="0.0.0.0",
98 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -080099 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700100 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800101 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700102 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700103
104 self._ip4 = VppIpAddress(ip4)
105 self._fip4 = VppIpAddress(fip4)
106 self._ip6 = VppIpAddress(ip6)
107 self._fip6 = VppIpAddress(fip6)
108
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700109 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100110 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700111 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100112 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700113
114 self.flags = flags
115 self.tun_src = VppIpAddress(tun_src)
116 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800117
118 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700119 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700120 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700121 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100122 self.vmac.packed,
Neale Ranns4ba67722019-02-28 11:11:39 +0000123 self.epg.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700124 self.flags,
125 self.tun_src.encode(),
126 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700127 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800128 self._test.registry.register(self, self._test.logger)
129
130 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700131 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800132
133 def __str__(self):
134 return self.object_id()
135
136 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700137 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
138 self.itf.sw_if_index,
139 self.ip4.address,
Neale Ranns4ba67722019-02-28 11:11:39 +0000140 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800141
142 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700143 return find_gbp_endpoint(self._test,
144 self.itf.sw_if_index,
145 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700146
147
148class VppGbpRecirc(VppObject):
149 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200150 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700151 """
152
153 def __init__(self, test, epg, recirc, is_ext=False):
154 self._test = test
155 self.recirc = recirc
156 self.epg = epg
157 self.is_ext = is_ext
158
159 def add_vpp_config(self):
160 self._test.vapi.gbp_recirc_add_del(
161 1,
162 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000163 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700164 self.is_ext)
165 self._test.registry.register(self, self._test.logger)
166
167 def remove_vpp_config(self):
168 self._test.vapi.gbp_recirc_add_del(
169 0,
170 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000171 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700172 self.is_ext)
173
174 def __str__(self):
175 return self.object_id()
176
177 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700178 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700179
180 def query_vpp_config(self):
181 rs = self._test.vapi.gbp_recirc_dump()
182 for r in rs:
183 if r.recirc.sw_if_index == self.recirc.sw_if_index:
184 return True
185 return False
186
187
Neale Rannsb6a47952018-11-21 05:44:35 -0800188class VppGbpExtItf(VppObject):
189 """
190 GBP ExtItfulation Interface
191 """
192
193 def __init__(self, test, itf, bd, rd):
194 self._test = test
195 self.itf = itf
196 self.bd = bd
197 self.rd = rd
198
199 def add_vpp_config(self):
200 self._test.vapi.gbp_ext_itf_add_del(
201 1,
202 self.itf.sw_if_index,
203 self.bd.bd_id,
204 self.rd.rd_id)
205 self._test.registry.register(self, self._test.logger)
206
207 def remove_vpp_config(self):
208 self._test.vapi.gbp_ext_itf_add_del(
209 0,
210 self.itf.sw_if_index,
211 self.bd.bd_id,
212 self.rd.rd_id)
213
214 def __str__(self):
215 return self.object_id()
216
217 def object_id(self):
218 return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index)
219
220 def query_vpp_config(self):
221 rs = self._test.vapi.gbp_ext_itf_dump()
222 for r in rs:
223 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
224 return True
225 return False
226
227
Neale Ranns25b04942018-04-04 09:34:50 -0700228class VppGbpSubnet(VppObject):
229 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200230 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700231 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700232 def __init__(self, test, rd, address, address_len,
233 type, sw_if_index=None, epg=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700234 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700235 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200236 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700237 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700238 self.sw_if_index = sw_if_index
239 self.epg = epg
240
241 def add_vpp_config(self):
242 self._test.vapi.gbp_subnet_add_del(
243 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700244 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200245 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700246 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700247 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4ba67722019-02-28 11:11:39 +0000248 sclass=self.epg.sclass if self.epg else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700249 self._test.registry.register(self, self._test.logger)
250
251 def remove_vpp_config(self):
252 self._test.vapi.gbp_subnet_add_del(
253 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700254 self.rd_id,
255 self.prefix.encode(),
256 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700257
258 def __str__(self):
259 return self.object_id()
260
261 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700262 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700263
264 def query_vpp_config(self):
265 ss = self._test.vapi.gbp_subnet_dump()
266 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700267 if s.subnet.rd_id == self.rd_id and \
268 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200269 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700270 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700271 return False
272
273
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800274class VppGbpEndpointRetention(object):
275 def __init__(self, remote_ep_timeout=0xffffffff):
276 self.remote_ep_timeout = remote_ep_timeout
277
278 def encode(self):
279 return {'remote_ep_timeout': self.remote_ep_timeout}
280
281
Neale Ranns25b04942018-04-04 09:34:50 -0700282class VppGbpEndpointGroup(VppObject):
283 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200284 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700285 """
286
Neale Ranns4ba67722019-02-28 11:11:39 +0000287 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800288 bvi, bvi_ip4, bvi_ip6=None,
289 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700290 self._test = test
291 self.uplink = uplink
292 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700293 self.bvi_ip4 = VppIpAddress(bvi_ip4)
294 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000295 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700296 self.bd = bd
297 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800298 self.sclass = sclass
299 if 0 == self.sclass:
300 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800301 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700302
303 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700304 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000305 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800306 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700307 self.bd.bd.bd_id,
308 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800309 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
310 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700311 self._test.registry.register(self, self._test.logger)
312
313 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000314 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700315
316 def __str__(self):
317 return self.object_id()
318
319 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000320 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700321
322 def query_vpp_config(self):
323 epgs = self._test.vapi.gbp_endpoint_group_dump()
324 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000325 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800326 return True
327 return False
328
329
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700330class VppGbpBridgeDomain(VppObject):
331 """
332 GBP Bridge Domain
333 """
334
Neale Ranns879d11c2019-01-21 23:34:18 -0800335 def __init__(self, test, bd, bvi, uu_fwd=None,
336 bm_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700337 self._test = test
338 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800339 self.uu_fwd = uu_fwd
340 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700341 self.bd = bd
342
Neale Rannsc29c0af2018-11-07 04:21:12 -0800343 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
344 if (learn):
345 self.learn = e.GBP_BD_API_FLAG_NONE
346 else:
347 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
348
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700349 def add_vpp_config(self):
350 self._test.vapi.gbp_bridge_domain_add(
351 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800352 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700353 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800354 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
355 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700356 self._test.registry.register(self, self._test.logger)
357
358 def remove_vpp_config(self):
359 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
360
361 def __str__(self):
362 return self.object_id()
363
364 def object_id(self):
365 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
366
367 def query_vpp_config(self):
368 bds = self._test.vapi.gbp_bridge_domain_dump()
369 for bd in bds:
370 if bd.bd.bd_id == self.bd.bd_id:
371 return True
372 return False
373
374
375class VppGbpRouteDomain(VppObject):
376 """
377 GBP Route Domain
378 """
379
380 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
381 self._test = test
382 self.rd_id = rd_id
383 self.t4 = t4
384 self.t6 = t6
385 self.ip4_uu = ip4_uu
386 self.ip6_uu = ip6_uu
387
388 def add_vpp_config(self):
389 self._test.vapi.gbp_route_domain_add(
390 self.rd_id,
391 self.t4.table_id,
392 self.t6.table_id,
393 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
394 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
395 self._test.registry.register(self, self._test.logger)
396
397 def remove_vpp_config(self):
398 self._test.vapi.gbp_route_domain_del(self.rd_id)
399
400 def __str__(self):
401 return self.object_id()
402
403 def object_id(self):
404 return "gbp-route-domain:[%d]" % (self.rd_id)
405
406 def query_vpp_config(self):
407 rds = self._test.vapi.gbp_route_domain_dump()
408 for rd in rds:
409 if rd.rd.rd_id == self.rd_id:
410 return True
411 return False
412
413
Neale Ranns13a08cc2018-11-07 09:25:54 -0800414class VppGbpContractNextHop():
415 def __init__(self, mac, bd, ip, rd):
416 self.mac = mac
417 self.ip = ip
418 self.bd = bd
419 self.rd = rd
420
421 def encode(self):
422 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100423 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800424 'bd_id': self.bd.bd.bd_id,
425 'rd_id': self.rd.rd_id}
426
427
428class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100429 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800430 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100431 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800432 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800433
434 def encode(self):
435 nhs = []
436 for nh in self.nhs:
437 nhs.append(nh.encode())
438 while len(nhs) < 8:
439 nhs.append({})
440 return {'action': self.action,
441 'nh_set': {
442 'hash_mode': self.hash_mode,
443 'n_nhs': len(self.nhs),
444 'nhs': nhs}}
445
446
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800447class VppGbpContract(VppObject):
448 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200449 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800450 """
451
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800452 def __init__(self, test, src_epg, dst_epg, acl_index,
453 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800454 self._test = test
455 self.acl_index = acl_index
456 self.src_epg = src_epg
457 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800458 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800459 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700460 while (len(self.allowed_ethertypes) < 16):
461 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800462
463 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800464 rules = []
465 for r in self.rules:
466 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800467 self._test.vapi.gbp_contract_add_del(
468 1,
Neale Ranns4ba67722019-02-28 11:11:39 +0000469 self.src_epg.sclass,
470 self.dst_epg.sclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800471 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800472 rules,
473 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800474 self._test.registry.register(self, self._test.logger)
475
476 def remove_vpp_config(self):
477 self._test.vapi.gbp_contract_add_del(
478 0,
Neale Ranns4ba67722019-02-28 11:11:39 +0000479 self.src_epg.sclass,
480 self.dst_epg.sclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800481 self.acl_index,
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700482 [],
483 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800484
485 def __str__(self):
486 return self.object_id()
487
488 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000489 return "gbp-contract:[%d:%s:%d]" % (self.src_epg.sclass,
490 self.dst_epg.sclass,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800491 self.acl_index)
492
493 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700494 cs = self._test.vapi.gbp_contract_dump()
495 for c in cs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000496 if c.contract.sclass == self.src_epg.sclass \
497 and c.contract.dclass == self.dst_epg.sclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800498 return True
499 return False
500
501
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700502class VppGbpVxlanTunnel(VppInterface):
503 """
504 GBP VXLAN tunnel
505 """
506
Neale Ranns8da9fc62019-03-04 14:08:11 -0800507 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700508 super(VppGbpVxlanTunnel, self).__init__(test)
509 self._test = test
510 self.vni = vni
511 self.bd_rd_id = bd_rd_id
512 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800513 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700514
515 def add_vpp_config(self):
516 r = self._test.vapi.gbp_vxlan_tunnel_add(
517 self.vni,
518 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800519 self.mode,
520 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700521 self.set_sw_if_index(r.sw_if_index)
522 self._test.registry.register(self, self._test.logger)
523
524 def remove_vpp_config(self):
525 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
526
527 def __str__(self):
528 return self.object_id()
529
530 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800531 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700532
533 def query_vpp_config(self):
534 return find_gbp_vxlan(self._test, self.vni)
535
536
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200537class VppGbpAcl(VppObject):
538 """
539 GBP Acl
540 """
541
542 def __init__(self, test):
543 self._test = test
544 self.acl_index = 4294967295
545
546 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800547 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
548 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200549 dport_from=0, dport_to=65535):
550 if proto == -1 or proto == 0:
551 sport_to = 0
552 dport_to = sport_to
553 elif proto == 1 or proto == 58:
554 sport_to = 255
555 dport_to = sport_to
556 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
557 'srcport_or_icmptype_first': sport_from,
558 'srcport_or_icmptype_last': sport_to,
559 'src_ip_prefix_len': s_prefix,
560 'src_ip_addr': s_ip,
561 'dstport_or_icmpcode_first': dport_from,
562 'dstport_or_icmpcode_last': dport_to,
563 'dst_ip_prefix_len': d_prefix,
564 'dst_ip_addr': d_ip})
565 return rule
566
567 def add_vpp_config(self, rules):
568
569 reply = self._test.vapi.acl_add_replace(self.acl_index,
570 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800571 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200572 self.acl_index = reply.acl_index
573 return self.acl_index
574
575 def remove_vpp_config(self):
576 self._test.vapi.acl_del(self.acl_index)
577
578 def __str__(self):
579 return self.object_id()
580
581 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700582 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200583
584 def query_vpp_config(self):
585 cs = self._test.vapi.acl_dump()
586 for c in cs:
587 if c.acl_index == self.acl_index:
588 return True
589 return False
590
591
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800592class TestGBP(VppTestCase):
593 """ GBP Test Case """
594
595 def setUp(self):
596 super(TestGBP, self).setUp()
597
Neale Ranns25b04942018-04-04 09:34:50 -0700598 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700599 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700600
Ole Troan8006c6a2018-12-17 12:02:26 +0100601 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800602
603 for i in self.pg_interfaces:
604 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700605 for i in self.lo_interfaces:
606 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800607
608 def tearDown(self):
609 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700610 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800611
612 super(TestGBP, self).tearDown()
613
Neale Ranns25b04942018-04-04 09:34:50 -0700614 def send_and_expect_bridged(self, src, tx, dst):
615 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800616
Neale Ranns25b04942018-04-04 09:34:50 -0700617 for r in rx:
618 self.assertEqual(r[Ether].src, tx[0][Ether].src)
619 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
620 self.assertEqual(r[IP].src, tx[0][IP].src)
621 self.assertEqual(r[IP].dst, tx[0][IP].dst)
622 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800623
Neale Ranns25b04942018-04-04 09:34:50 -0700624 def send_and_expect_bridged6(self, src, tx, dst):
625 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800626
Neale Ranns25b04942018-04-04 09:34:50 -0700627 for r in rx:
628 self.assertEqual(r[Ether].src, tx[0][Ether].src)
629 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
630 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
631 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
632 return rx
633
634 def send_and_expect_routed(self, src, tx, dst, src_mac):
635 rx = self.send_and_expect(src, tx, dst)
636
637 for r in rx:
638 self.assertEqual(r[Ether].src, src_mac)
639 self.assertEqual(r[Ether].dst, dst.remote_mac)
640 self.assertEqual(r[IP].src, tx[0][IP].src)
641 self.assertEqual(r[IP].dst, tx[0][IP].dst)
642 return rx
643
644 def send_and_expect_natted(self, src, tx, dst, src_ip):
645 rx = self.send_and_expect(src, tx, dst)
646
647 for r in rx:
648 self.assertEqual(r[Ether].src, tx[0][Ether].src)
649 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
650 self.assertEqual(r[IP].src, src_ip)
651 self.assertEqual(r[IP].dst, tx[0][IP].dst)
652 return rx
653
Neale Ranns4a6d0232018-04-24 07:45:33 -0700654 def send_and_expect_natted6(self, src, tx, dst, src_ip):
655 rx = self.send_and_expect(src, tx, dst)
656
657 for r in rx:
658 self.assertEqual(r[Ether].src, tx[0][Ether].src)
659 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
660 self.assertEqual(r[IPv6].src, src_ip)
661 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
662 return rx
663
Neale Ranns25b04942018-04-04 09:34:50 -0700664 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
665 rx = self.send_and_expect(src, tx, dst)
666
667 for r in rx:
668 self.assertEqual(r[Ether].src, tx[0][Ether].src)
669 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
670 self.assertEqual(r[IP].dst, dst_ip)
671 self.assertEqual(r[IP].src, tx[0][IP].src)
672 return rx
673
Neale Ranns4a6d0232018-04-24 07:45:33 -0700674 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
675 rx = self.send_and_expect(src, tx, dst)
676
677 for r in rx:
678 self.assertEqual(r[Ether].src, tx[0][Ether].src)
679 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
680 self.assertEqual(r[IPv6].dst, dst_ip)
681 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
682 return rx
683
Neale Ranns25b04942018-04-04 09:34:50 -0700684 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
685 rx = self.send_and_expect(src, tx, dst)
686
687 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100688 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700689 self.assertEqual(r[Ether].dst, dst.remote_mac)
690 self.assertEqual(r[IP].dst, dst_ip)
691 self.assertEqual(r[IP].src, src_ip)
692 return rx
693
Neale Ranns4a6d0232018-04-24 07:45:33 -0700694 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
695 rx = self.send_and_expect(src, tx, dst)
696
697 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100698 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700699 self.assertEqual(r[Ether].dst, dst.remote_mac)
700 self.assertEqual(r[IPv6].dst, dst_ip)
701 self.assertEqual(r[IPv6].src, src_ip)
702 return rx
703
Neale Ranns25b04942018-04-04 09:34:50 -0700704 def test_gbp(self):
705 """ Group Based Policy """
706
Neale Rannsb6a47952018-11-21 05:44:35 -0800707 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
708
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800709 #
Neale Ranns25b04942018-04-04 09:34:50 -0700710 # Bridge Domains
711 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700712 bd1 = VppBridgeDomain(self, 1)
713 bd2 = VppBridgeDomain(self, 2)
714 bd20 = VppBridgeDomain(self, 20)
715
716 bd1.add_vpp_config()
717 bd2.add_vpp_config()
718 bd20.add_vpp_config()
719
720 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
721 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
722 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
723
724 gbd1.add_vpp_config()
725 gbd2.add_vpp_config()
726 gbd20.add_vpp_config()
727
728 #
729 # Route Domains
730 #
731 gt4 = VppIpTable(self, 0)
732 gt4.add_vpp_config()
733 gt6 = VppIpTable(self, 0, is_ip6=True)
734 gt6.add_vpp_config()
735 nt4 = VppIpTable(self, 20)
736 nt4.add_vpp_config()
737 nt6 = VppIpTable(self, 20, is_ip6=True)
738 nt6.add_vpp_config()
739
740 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
741 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
742
743 rd0.add_vpp_config()
744 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700745
746 #
747 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700748 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
749 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000750 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
751 self.pg4, self.loop0,
752 "10.0.0.128", "2001:10::128"),
753 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
754 self.pg5, self.loop0,
755 "10.0.1.128", "2001:10:1::128"),
756 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
757 self.pg6, self.loop1,
758 "10.0.2.128", "2001:10:2::128"),
759 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
760 self.pg7, self.loop2,
761 "11.0.0.128", "3001::128"),
762 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
763 self.pg8, self.loop2,
764 "11.0.0.129", "3001::129")]
765 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
766 VppGbpRecirc(self, epgs[1], self.loop4),
767 VppGbpRecirc(self, epgs[2], self.loop5),
768 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
769 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700770
771 epg_nat = epgs[3]
772 recirc_nat = recircs[3]
773
774 #
775 # 4 end-points, 2 in the same subnet, 3 in the same BD
776 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700777 eps = [VppGbpEndpoint(self, self.pg0,
778 epgs[0], recircs[0],
779 "10.0.0.1", "11.0.0.1",
780 "2001:10::1", "3001::1"),
781 VppGbpEndpoint(self, self.pg1,
782 epgs[0], recircs[0],
783 "10.0.0.2", "11.0.0.2",
784 "2001:10::2", "3001::2"),
785 VppGbpEndpoint(self, self.pg2,
786 epgs[1], recircs[1],
787 "10.0.1.1", "11.0.0.3",
788 "2001:10:1::1", "3001::3"),
789 VppGbpEndpoint(self, self.pg3,
790 epgs[2], recircs[2],
791 "10.0.2.1", "11.0.0.4",
792 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700793
794 #
795 # Config related to each of the EPGs
796 #
797 for epg in epgs:
798 # IP config on the BVI interfaces
799 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700800 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
801 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
802 self.vapi.sw_interface_set_mac_address(
803 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100804 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700805
806 # The BVIs are NAT inside interfaces
807 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
808 is_inside=1,
809 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700810 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
811 is_inside=1,
812 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700813
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700814 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
815 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
816 if_ip4.add_vpp_config()
817 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700818
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700819 # EPG uplink interfaces in the RD
820 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
821 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700822
823 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700824 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100825 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700826 epg.bvi_ip4)
827 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100828 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700829 epg.bvi_ip6)
830 epg.bd_arp_ip4.add_vpp_config()
831 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700832
833 # EPG in VPP
834 epg.add_vpp_config()
835
836 for recirc in recircs:
837 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700838 VppIpInterfaceBind(self, recirc.recirc,
839 recirc.epg.rd.t4).add_vpp_config()
840 VppIpInterfaceBind(self, recirc.recirc,
841 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700842
Neale Ranns4a6d0232018-04-24 07:45:33 -0700843 self.vapi.nat44_interface_add_del_feature(
844 recirc.recirc.sw_if_index,
845 is_inside=0,
846 is_add=1)
847 self.vapi.nat66_add_del_interface(
848 recirc.recirc.sw_if_index,
849 is_inside=0,
850 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700851
852 recirc.add_vpp_config()
853
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700854 for recirc in recircs:
855 self.assertTrue(find_bridge_domain_port(self,
856 recirc.epg.bd.bd.bd_id,
857 recirc.recirc.sw_if_index))
858
Neale Ranns25b04942018-04-04 09:34:50 -0700859 for ep in eps:
860 self.pg_enable_capture(self.pg_interfaces)
861 self.pg_start()
862 #
863 # routes to the endpoints. We need these since there are no
864 # adj-fibs due to the fact the the BVI address has /32 and
865 # the subnet is not attached.
866 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700867 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700868 # Add static mappings for each EP from the 10/8 to 11/8 network
869 if ip.af == AF_INET:
870 self.vapi.nat44_add_del_static_mapping(ip.bytes,
871 fip.bytes,
872 vrf_id=0,
873 addr_only=1)
874 else:
875 self.vapi.nat66_add_del_static_mapping(ip.bytes,
876 fip.bytes,
877 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700878
Neale Ranns25b04942018-04-04 09:34:50 -0700879 # VPP EP create ...
880 ep.add_vpp_config()
881
Neale Rannsc0a93142018-09-05 15:42:26 -0700882 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700883
Neale Rannsc0a93142018-09-05 15:42:26 -0700884 # ... results in a Gratuitous ARP/ND on the EPG's uplink
885 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
886
887 for ii, ip in enumerate(ep.ips):
888 p = rx[ii]
889
890 if ip.is_ip6:
891 self.assertTrue(p.haslayer(ICMPv6ND_NA))
892 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
893 else:
894 self.assertTrue(p.haslayer(ARP))
895 self.assertEqual(p[ARP].psrc, ip.address)
896 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700897
898 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700899 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700900 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
901 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700902
Neale Rannsc0a93142018-09-05 15:42:26 -0700903 # floating IPs route via EPG recirc
904 r = VppIpRoute(self, fip.address, fip.length,
905 [VppRoutePath(fip.address,
906 ep.recirc.recirc.sw_if_index,
907 is_dvr=1,
908 proto=fip.dpo_proto)],
909 table_id=20,
910 is_ip6=fip.is_ip6)
911 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700912
913 # L2 FIB entries in the NAT EPG BD to bridge the packets from
914 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700915 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
916 ep.recirc.recirc, bvi_mac=0)
917 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700918
919 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700920 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700921 #
922 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
923 src=self.pg0.remote_mac) /
924 ARP(op="who-has",
925 hwdst="ff:ff:ff:ff:ff:ff",
926 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700927 pdst="10.0.0.88",
928 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700929
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700930 self.vapi.cli("clear trace")
931 self.pg0.add_stream(pkt_arp)
932
933 self.pg_enable_capture(self.pg_interfaces)
934 self.pg_start()
935
936 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700937
938 #
939 # ARP/ND packets get a response
940 #
941 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
942 src=self.pg0.remote_mac) /
943 ARP(op="who-has",
944 hwdst="ff:ff:ff:ff:ff:ff",
945 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700946 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700947 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700948
949 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
950
Neale Rannsc0a93142018-09-05 15:42:26 -0700951 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700952 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700953 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
954 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700955 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700956 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700957 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
958 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
959
960 #
961 # broadcast packets are flooded
962 #
963 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
964 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700965 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700966 UDP(sport=1234, dport=1234) /
967 Raw('\xa5' * 100))
968
969 self.vapi.cli("clear trace")
970 self.pg0.add_stream(pkt_bcast)
971
972 self.pg_enable_capture(self.pg_interfaces)
973 self.pg_start()
974
975 rxd = eps[1].itf.get_capture(1)
976 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
977 rxd = epgs[0].uplink.get_capture(1)
978 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
979
980 #
981 # packets to non-local L3 destinations dropped
982 #
983 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100984 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700985 IP(src=eps[0].ip4.address,
986 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700987 UDP(sport=1234, dport=1234) /
988 Raw('\xa5' * 100))
989 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100990 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700991 IP(src=eps[0].ip4.address,
992 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700993 UDP(sport=1234, dport=1234) /
994 Raw('\xa5' * 100))
995
996 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
997
998 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100999 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001000 IPv6(src=eps[0].ip6.address,
1001 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001002 UDP(sport=1234, dport=1234) /
1003 Raw('\xa5' * 100))
1004 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
1005
1006 #
1007 # Add the subnet routes
1008 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001009 s41 = VppGbpSubnet(
1010 self, rd0, "10.0.0.0", 24,
1011 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1012 s42 = VppGbpSubnet(
1013 self, rd0, "10.0.1.0", 24,
1014 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1015 s43 = VppGbpSubnet(
1016 self, rd0, "10.0.2.0", 24,
1017 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1018 s61 = VppGbpSubnet(
1019 self, rd0, "2001:10::1", 64,
1020 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1021 s62 = VppGbpSubnet(
1022 self, rd0, "2001:10:1::1", 64,
1023 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1024 s63 = VppGbpSubnet(
1025 self, rd0, "2001:10:2::1", 64,
1026 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001027 s41.add_vpp_config()
1028 s42.add_vpp_config()
1029 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001030 s61.add_vpp_config()
1031 s62.add_vpp_config()
1032 s63.add_vpp_config()
1033
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001034 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001035 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001036 eps[0].epg.uplink)
1037 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001038 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001039 eps[0].epg.uplink)
1040 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001041 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001042 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001043
1044 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1045 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1046 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1047 self.logger.info(self.vapi.cli("sh gbp recirc"))
1048 self.logger.info(self.vapi.cli("sh int"))
1049 self.logger.info(self.vapi.cli("sh int addr"))
1050 self.logger.info(self.vapi.cli("sh int feat loop6"))
1051 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1052 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001053 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001054
1055 #
1056 # Packet destined to unknown unicast is sent on the epg uplink ...
1057 #
1058 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1059 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001060 IP(src=eps[0].ip4.address,
1061 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001062 UDP(sport=1234, dport=1234) /
1063 Raw('\xa5' * 100))
1064
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001065 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001066 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001067 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001068 # ... and nowhere else
1069 self.pg1.get_capture(0, timeout=0.1)
1070 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1071
1072 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1073 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001074 IP(src=eps[0].ip4.address,
1075 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001076 UDP(sport=1234, dport=1234) /
1077 Raw('\xa5' * 100))
1078
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001079 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001080 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001081 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001082
1083 #
1084 # Packets from the uplink are forwarded in the absence of a contract
1085 #
1086 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1087 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001088 IP(src=eps[0].ip4.address,
1089 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001090 UDP(sport=1234, dport=1234) /
1091 Raw('\xa5' * 100))
1092
1093 self.send_and_expect_bridged(self.pg4,
1094 pkt_intra_epg_220_from_uplink * 65,
1095 self.pg0)
1096
1097 #
1098 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001099 # can communicate
1100 #
1101 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001102 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001103 IP(src=eps[0].ip4.address,
1104 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001105 UDP(sport=1234, dport=1234) /
1106 Raw('\xa5' * 100))
1107
Neale Ranns25b04942018-04-04 09:34:50 -07001108 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001109
1110 #
1111 # in the abscense of policy, endpoints in the different EPG
1112 # cannot communicate
1113 #
1114 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001115 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001116 IP(src=eps[0].ip4.address,
1117 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001118 UDP(sport=1234, dport=1234) /
1119 Raw('\xa5' * 100))
1120 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001121 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001122 IP(src=eps[2].ip4.address,
1123 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001124 UDP(sport=1234, dport=1234) /
1125 Raw('\xa5' * 100))
1126 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001127 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001128 IP(src=eps[0].ip4.address,
1129 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001130 UDP(sport=1234, dport=1234) /
1131 Raw('\xa5' * 100))
1132
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001133 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001134 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001135 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001136 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001137
1138 #
1139 # A uni-directional contract from EPG 220 -> 221
1140 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001141 acl = VppGbpAcl(self)
1142 rule = acl.create_rule(permit_deny=1, proto=17)
1143 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1144 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001145 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001146 self, epgs[0], epgs[1], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001147 [VppGbpContractRule(
1148 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1149 []),
1150 VppGbpContractRule(
1151 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001152 [])],
1153 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001154 c1.add_vpp_config()
1155
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001156 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001157 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001158 eps[2].itf)
1159 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001160 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001161
1162 #
1163 # contract for the return direction
1164 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001165 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001166 self, epgs[1], epgs[0], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001167 [VppGbpContractRule(
1168 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1169 []),
1170 VppGbpContractRule(
1171 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001172 [])],
1173 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001174 c2.add_vpp_config()
1175
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001176 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001177 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001178 eps[2].itf)
1179 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001180 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001181 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001182
1183 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001184 # the contract does not allow non-IP
1185 #
1186 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1187 dst=self.pg2.remote_mac) /
1188 ARP())
1189 self.send_and_assert_no_replies(eps[0].itf,
1190 pkt_non_ip_inter_epg_220_to_221 * 17)
1191
1192 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001193 # check that inter group is still disabled for the groups
1194 # not in the contract.
1195 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001196 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001197 pkt_inter_epg_220_to_222 * 65)
1198
Neale Ranns25b04942018-04-04 09:34:50 -07001199 #
1200 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1201 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001202 c3 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001203 self, epgs[0], epgs[2], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001204 [VppGbpContractRule(
1205 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1206 []),
1207 VppGbpContractRule(
1208 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001209 [])],
1210 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001211 c3.add_vpp_config()
1212
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001213 self.logger.info(self.vapi.cli("sh gbp contract"))
1214
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001215 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001216 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001217 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001218 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001219
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001220 #
1221 # remove both contracts, traffic stops in both directions
1222 #
1223 c2.remove_vpp_config()
1224 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001225 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001226 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001227
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001228 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001229 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001230 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001231 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001232 self.send_and_expect_bridged(eps[0].itf,
1233 pkt_intra_epg * 65,
1234 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001235
1236 #
Neale Ranns25b04942018-04-04 09:34:50 -07001237 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001238 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001239
Neale Ranns25b04942018-04-04 09:34:50 -07001240 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001241 se1 = VppGbpSubnet(
1242 self, rd0, "0.0.0.0", 0,
1243 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1244 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001245 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001246 se2 = VppGbpSubnet(
1247 self, rd0, "11.0.0.0", 8,
1248 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1249 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001250 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001251 se16 = VppGbpSubnet(
1252 self, rd0, "::", 0,
1253 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1254 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001255 epg=epg_nat)
Neale Ranns25b04942018-04-04 09:34:50 -07001256 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001257 se3 = VppGbpSubnet(
1258 self, rd20, "0.0.0.0", 0,
1259 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1260 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001261 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001262 se36 = VppGbpSubnet(
1263 self, rd20, "::", 0,
1264 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1265 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001266 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001267 se4 = VppGbpSubnet(
1268 self, rd20, "11.0.0.0", 8,
1269 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1270 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001271 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001272 se1.add_vpp_config()
1273 se2.add_vpp_config()
1274 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001275 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001276 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001277 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001278
Neale Ranns25b04942018-04-04 09:34:50 -07001279 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1280 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001281 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1282 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001283 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001284
Neale Ranns4a6d0232018-04-24 07:45:33 -07001285 #
1286 # From an EP to an outside addess: IN2OUT
1287 #
Neale Ranns25b04942018-04-04 09:34:50 -07001288 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001289 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001290 IP(src=eps[0].ip4.address,
1291 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001292 UDP(sport=1234, dport=1234) /
1293 Raw('\xa5' * 100))
1294
1295 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001296 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001297 pkt_inter_epg_220_to_global * 65)
1298
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001299 acl2 = VppGbpAcl(self)
1300 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1301 sport_to=1234, dport_from=1234, dport_to=1234)
1302 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1303 sport_from=1234, sport_to=1234,
1304 dport_from=1234, dport_to=1234)
1305
1306 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001307 c4 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001308 self, epgs[0], epgs[3], acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001309 [VppGbpContractRule(
1310 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1311 []),
1312 VppGbpContractRule(
1313 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001314 [])],
1315 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001316 c4.add_vpp_config()
1317
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001318 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001319 pkt_inter_epg_220_to_global * 65,
1320 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001321 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001322
Neale Ranns4a6d0232018-04-24 07:45:33 -07001323 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001324 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001325 IPv6(src=eps[0].ip6.address,
1326 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001327 UDP(sport=1234, dport=1234) /
1328 Raw('\xa5' * 100))
1329
1330 self.send_and_expect_natted6(self.pg0,
1331 pkt_inter_epg_220_to_global * 65,
1332 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001333 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001334
1335 #
1336 # From a global address to an EP: OUT2IN
1337 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001338 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001339 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001340 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001341 src="1.1.1.1") /
1342 UDP(sport=1234, dport=1234) /
1343 Raw('\xa5' * 100))
1344
1345 self.send_and_assert_no_replies(self.pg7,
1346 pkt_inter_epg_220_from_global * 65)
1347
Neale Ranns13a08cc2018-11-07 09:25:54 -08001348 c5 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001349 self, epgs[3], epgs[0], acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001350 [VppGbpContractRule(
1351 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1352 []),
1353 VppGbpContractRule(
1354 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001355 [])],
1356 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001357 c5.add_vpp_config()
1358
1359 self.send_and_expect_unnatted(self.pg7,
1360 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001361 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001362 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001363
Ole Troan8006c6a2018-12-17 12:02:26 +01001364 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001365 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001366 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001367 src="6001::1") /
1368 UDP(sport=1234, dport=1234) /
1369 Raw('\xa5' * 100))
1370
1371 self.send_and_expect_unnatted6(self.pg7,
1372 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001373 eps[0].itf,
1374 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001375
1376 #
1377 # From a local VM to another local VM using resp. public addresses:
1378 # IN2OUT2IN
1379 #
Neale Ranns25b04942018-04-04 09:34:50 -07001380 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001381 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001382 IP(src=eps[0].ip4.address,
1383 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001384 UDP(sport=1234, dport=1234) /
1385 Raw('\xa5' * 100))
1386
Neale Ranns4a6d0232018-04-24 07:45:33 -07001387 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001388 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001389 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001390 eps[0].fip4.address,
1391 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001392
Neale Rannsc0a93142018-09-05 15:42:26 -07001393 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001394 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001395 IPv6(src=eps[0].ip6.address,
1396 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001397 UDP(sport=1234, dport=1234) /
1398 Raw('\xa5' * 100))
1399
Neale Rannsc0a93142018-09-05 15:42:26 -07001400 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001401 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001402 eps[1].itf,
1403 eps[0].fip6.address,
1404 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001405
1406 #
Neale Ranns25b04942018-04-04 09:34:50 -07001407 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001408 #
Neale Ranns25b04942018-04-04 09:34:50 -07001409 for ep in eps:
1410 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001411 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1412 ep.fip4.bytes,
1413 vrf_id=0,
1414 addr_only=1,
1415 is_add=0)
1416 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1417 ep.fip6.bytes,
1418 vrf_id=0,
1419 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001420
Neale Ranns25b04942018-04-04 09:34:50 -07001421 for epg in epgs:
1422 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001423 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001424 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1425 is_inside=1,
1426 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001427 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1428 is_inside=1,
1429 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001430
Neale Ranns25b04942018-04-04 09:34:50 -07001431 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001432 self.vapi.nat44_interface_add_del_feature(
1433 recirc.recirc.sw_if_index,
1434 is_inside=0,
1435 is_add=0)
1436 self.vapi.nat66_add_del_interface(
1437 recirc.recirc.sw_if_index,
1438 is_inside=0,
1439 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001440
Neale Ranns774356a2018-11-29 12:02:16 +00001441 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1442 n_tries=100, s_time=1):
1443 while (n_tries):
1444 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1445 return True
1446 n_tries = n_tries - 1
1447 self.sleep(s_time)
1448 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1449 return False
1450
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001451 def test_gbp_learn_l2(self):
1452 """ GBP L2 Endpoint Learning """
1453
Neale Rannsb6a47952018-11-21 05:44:35 -08001454 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001455 learnt = [{'mac': '00:00:11:11:11:01',
1456 'ip': '10.0.0.1',
1457 'ip6': '2001:10::2'},
1458 {'mac': '00:00:11:11:11:02',
1459 'ip': '10.0.0.2',
1460 'ip6': '2001:10::3'}]
1461
1462 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001463 # IP tables
1464 #
1465 gt4 = VppIpTable(self, 1)
1466 gt4.add_vpp_config()
1467 gt6 = VppIpTable(self, 1, is_ip6=True)
1468 gt6.add_vpp_config()
1469
1470 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1471 rd1.add_vpp_config()
1472
1473 #
1474 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1475 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1476 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1477 #
1478 self.pg2.config_ip4()
1479 self.pg2.resolve_arp()
1480 self.pg2.generate_remote_hosts(4)
1481 self.pg2.configure_ipv4_neighbors()
1482 self.pg3.config_ip4()
1483 self.pg3.resolve_arp()
1484 self.pg4.config_ip4()
1485 self.pg4.resolve_arp()
1486
1487 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001488 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1489 #
1490 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1491 "239.1.1.1", 88,
1492 mcast_itf=self.pg4)
1493 tun_bm.add_vpp_config()
1494
1495 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001496 # a GBP bridge domain with a BVI and a UU-flood interface
1497 #
1498 bd1 = VppBridgeDomain(self, 1)
1499 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001500 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001501 gbd1.add_vpp_config()
1502
1503 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1504 self.logger.info(self.vapi.cli("sh gbp bridge"))
1505
1506 # ... and has a /32 applied
1507 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1508 ip_addr.add_vpp_config()
1509
1510 #
1511 # The Endpoint-group in which we are learning endpoints
1512 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001513 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001514 None, self.loop0,
1515 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001516 "2001:10::128",
1517 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001518 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001519 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001520 None, self.loop1,
1521 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001522 "2001:11::128",
1523 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001524 epg_330.add_vpp_config()
1525
1526 #
1527 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1528 # leanring enabled
1529 #
1530 vx_tun_l2_1 = VppGbpVxlanTunnel(
1531 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001532 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1533 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001534 vx_tun_l2_1.add_vpp_config()
1535
1536 #
1537 # A static endpoint that the learnt endpoints are trying to
1538 # talk to
1539 #
1540 ep = VppGbpEndpoint(self, self.pg0,
1541 epg_220, None,
1542 "10.0.0.127", "11.0.0.127",
1543 "2001:10::1", "3001::1")
1544 ep.add_vpp_config()
1545
1546 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1547
1548 # a packet with an sclass from an unknwon EPG
1549 p = (Ether(src=self.pg2.remote_mac,
1550 dst=self.pg2.local_mac) /
1551 IP(src=self.pg2.remote_hosts[0].ip4,
1552 dst=self.pg2.local_ip4) /
1553 UDP(sport=1234, dport=48879) /
1554 VXLAN(vni=99, gpid=88, flags=0x88) /
1555 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1556 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1557 UDP(sport=1234, dport=1234) /
1558 Raw('\xa5' * 100))
1559
1560 self.send_and_assert_no_replies(self.pg2, p)
1561
1562 #
1563 # we should not have learnt a new tunnel endpoint, since
1564 # the EPG was not learnt.
1565 #
1566 self.assertEqual(INDEX_INVALID,
1567 find_vxlan_gbp_tunnel(self,
1568 self.pg2.local_ip4,
1569 self.pg2.remote_hosts[0].ip4,
1570 99))
1571
1572 # epg is not learnt, becasue the EPG is unknwon
1573 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1574
Neale Ranns8da9fc62019-03-04 14:08:11 -08001575 #
1576 # Learn new EPs from IP packets
1577 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001578 for ii, l in enumerate(learnt):
1579 # a packet with an sclass from a knwon EPG
1580 # arriving on an unknown TEP
1581 p = (Ether(src=self.pg2.remote_mac,
1582 dst=self.pg2.local_mac) /
1583 IP(src=self.pg2.remote_hosts[1].ip4,
1584 dst=self.pg2.local_ip4) /
1585 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001586 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001587 Ether(src=l['mac'], dst=ep.mac) /
1588 IP(src=l['ip'], dst=ep.ip4.address) /
1589 UDP(sport=1234, dport=1234) /
1590 Raw('\xa5' * 100))
1591
1592 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1593
1594 # the new TEP
1595 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1596 self,
1597 self.pg2.local_ip4,
1598 self.pg2.remote_hosts[1].ip4,
1599 99)
1600 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1601
1602 #
1603 # the EP is learnt via the learnt TEP
1604 # both from its MAC and its IP
1605 #
1606 self.assertTrue(find_gbp_endpoint(self,
1607 vx_tun_l2_1.sw_if_index,
1608 mac=l['mac']))
1609 self.assertTrue(find_gbp_endpoint(self,
1610 vx_tun_l2_1.sw_if_index,
1611 ip=l['ip']))
1612
1613 self.logger.info(self.vapi.cli("show gbp endpoint"))
1614 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001615 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001616
1617 #
1618 # If we sleep for the threshold time, the learnt endpoints should
1619 # age out
1620 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001621 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001622 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1623 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001624
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001625 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001626 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1627 #
1628 for ii, l in enumerate(learnt):
1629 # a packet with an sclass from a knwon EPG
1630 # arriving on an unknown TEP
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="239.1.1.1") /
1635 UDP(sport=1234, dport=48879) /
1636 VXLAN(vni=88, gpid=112, flags=0x88) /
1637 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1638 ARP(op="who-has",
1639 psrc=l['ip'], pdst=l['ip'],
1640 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1641
1642 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1643
1644 # the new TEP
1645 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1646 self,
1647 self.pg2.local_ip4,
1648 self.pg2.remote_hosts[1].ip4,
1649 99)
1650 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1651
1652 #
1653 # the EP is learnt via the learnt TEP
1654 # both from its MAC and its IP
1655 #
1656 self.assertTrue(find_gbp_endpoint(self,
1657 vx_tun_l2_1.sw_if_index,
1658 mac=l['mac']))
1659 self.assertTrue(find_gbp_endpoint(self,
1660 vx_tun_l2_1.sw_if_index,
1661 ip=l['ip']))
1662
1663 #
1664 # wait for the learnt endpoints to age out
1665 #
1666 for l in learnt:
1667 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1668 mac=l['mac'])
1669
1670 #
1671 # Learn new EPs from L2 packets
1672 #
1673 for ii, l in enumerate(learnt):
1674 # a packet with an sclass from a knwon EPG
1675 # arriving on an unknown TEP
1676 p = (Ether(src=self.pg2.remote_mac,
1677 dst=self.pg2.local_mac) /
1678 IP(src=self.pg2.remote_hosts[1].ip4,
1679 dst=self.pg2.local_ip4) /
1680 UDP(sport=1234, dport=48879) /
1681 VXLAN(vni=99, gpid=112, flags=0x88) /
1682 Ether(src=l['mac'], dst=ep.mac) /
1683 Raw('\xa5' * 100))
1684
1685 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1686
1687 # the new TEP
1688 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1689 self,
1690 self.pg2.local_ip4,
1691 self.pg2.remote_hosts[1].ip4,
1692 99)
1693 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1694
1695 #
1696 # the EP is learnt via the learnt TEP
1697 # both from its MAC and its IP
1698 #
1699 self.assertTrue(find_gbp_endpoint(self,
1700 vx_tun_l2_1.sw_if_index,
1701 mac=l['mac']))
1702
1703 self.logger.info(self.vapi.cli("show gbp endpoint"))
1704 self.logger.info(self.vapi.cli("show gbp vxlan"))
1705 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1706
1707 #
1708 # wait for the learnt endpoints to age out
1709 #
1710 for l in learnt:
1711 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1712 mac=l['mac'])
1713
1714 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001715 # repeat. the do not learn bit is set so the EPs are not learnt
1716 #
1717 for l in learnt:
1718 # a packet with an sclass from a knwon EPG
1719 p = (Ether(src=self.pg2.remote_mac,
1720 dst=self.pg2.local_mac) /
1721 IP(src=self.pg2.remote_hosts[1].ip4,
1722 dst=self.pg2.local_ip4) /
1723 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001724 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001725 Ether(src=l['mac'], dst=ep.mac) /
1726 IP(src=l['ip'], dst=ep.ip4.address) /
1727 UDP(sport=1234, dport=1234) /
1728 Raw('\xa5' * 100))
1729
1730 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1731
1732 for l in learnt:
1733 self.assertFalse(find_gbp_endpoint(self,
1734 vx_tun_l2_1.sw_if_index,
1735 mac=l['mac']))
1736
1737 #
1738 # repeat
1739 #
1740 for l in learnt:
1741 # a packet with an sclass from a knwon EPG
1742 p = (Ether(src=self.pg2.remote_mac,
1743 dst=self.pg2.local_mac) /
1744 IP(src=self.pg2.remote_hosts[1].ip4,
1745 dst=self.pg2.local_ip4) /
1746 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001747 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001748 Ether(src=l['mac'], dst=ep.mac) /
1749 IP(src=l['ip'], dst=ep.ip4.address) /
1750 UDP(sport=1234, dport=1234) /
1751 Raw('\xa5' * 100))
1752
1753 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1754
1755 self.assertTrue(find_gbp_endpoint(self,
1756 vx_tun_l2_1.sw_if_index,
1757 mac=l['mac']))
1758
1759 #
1760 # Static EP replies to dynamics
1761 #
1762 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1763 for l in learnt:
1764 p = (Ether(src=ep.mac, dst=l['mac']) /
1765 IP(dst=l['ip'], src=ep.ip4.address) /
1766 UDP(sport=1234, dport=1234) /
1767 Raw('\xa5' * 100))
1768
1769 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1770
1771 for rx in rxs:
1772 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1773 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1774 self.assertEqual(rx[UDP].dport, 48879)
1775 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001776 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001777 self.assertEqual(rx[VXLAN].vni, 99)
1778 self.assertTrue(rx[VXLAN].flags.G)
1779 self.assertTrue(rx[VXLAN].flags.Instance)
1780 self.assertTrue(rx[VXLAN].gpflags.A)
1781 self.assertFalse(rx[VXLAN].gpflags.D)
1782
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001783 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001784 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1785 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001786
1787 #
1788 # repeat in the other EPG
1789 # there's no contract between 220 and 330, but the A-bit is set
1790 # so the packet is cleared for delivery
1791 #
1792 for l in learnt:
1793 # a packet with an sclass from a knwon EPG
1794 p = (Ether(src=self.pg2.remote_mac,
1795 dst=self.pg2.local_mac) /
1796 IP(src=self.pg2.remote_hosts[1].ip4,
1797 dst=self.pg2.local_ip4) /
1798 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001799 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001800 Ether(src=l['mac'], dst=ep.mac) /
1801 IP(src=l['ip'], dst=ep.ip4.address) /
1802 UDP(sport=1234, dport=1234) /
1803 Raw('\xa5' * 100))
1804
1805 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1806
1807 self.assertTrue(find_gbp_endpoint(self,
1808 vx_tun_l2_1.sw_if_index,
1809 mac=l['mac']))
1810
1811 #
1812 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001813 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001814 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001815 p = (Ether(src=ep.mac, dst=l['mac']) /
1816 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1817 UDP(sport=1234, dport=1234) /
1818 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001819
Neale Ranns13a08cc2018-11-07 09:25:54 -08001820 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001821
1822 #
1823 # refresh the entries after the check for no replies above
1824 #
1825 for l in learnt:
1826 # a packet with an sclass from a knwon EPG
1827 p = (Ether(src=self.pg2.remote_mac,
1828 dst=self.pg2.local_mac) /
1829 IP(src=self.pg2.remote_hosts[1].ip4,
1830 dst=self.pg2.local_ip4) /
1831 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001832 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001833 Ether(src=l['mac'], dst=ep.mac) /
1834 IP(src=l['ip'], dst=ep.ip4.address) /
1835 UDP(sport=1234, dport=1234) /
1836 Raw('\xa5' * 100))
1837
1838 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1839
1840 self.assertTrue(find_gbp_endpoint(self,
1841 vx_tun_l2_1.sw_if_index,
1842 mac=l['mac']))
1843
1844 #
1845 # Add the contract so they can talk
1846 #
1847 acl = VppGbpAcl(self)
1848 rule = acl.create_rule(permit_deny=1, proto=17)
1849 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1850 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001851 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001852 self, epg_220, epg_330, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001853 [VppGbpContractRule(
1854 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1855 []),
1856 VppGbpContractRule(
1857 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001858 [])],
1859 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001860 c1.add_vpp_config()
1861
1862 for l in learnt:
1863 p = (Ether(src=ep.mac, dst=l['mac']) /
1864 IP(dst=l['ip'], src=ep.ip4.address) /
1865 UDP(sport=1234, dport=1234) /
1866 Raw('\xa5' * 100))
1867
1868 self.send_and_expect(self.pg0, [p], self.pg2)
1869
1870 #
1871 # send UU packets from the local EP
1872 #
1873 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1874 self.logger.info(self.vapi.cli("sh gbp bridge"))
1875 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1876 IP(dst="10.0.0.133", src=ep.ip4.address) /
1877 UDP(sport=1234, dport=1234) /
1878 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001879 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001880
1881 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1882
1883 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1884 IP(dst="10.0.0.133", src=ep.ip4.address) /
1885 UDP(sport=1234, dport=1234) /
1886 Raw('\xa5' * 100))
1887 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1888
Neale Ranns879d11c2019-01-21 23:34:18 -08001889 for rx in rxs:
1890 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1891 self.assertEqual(rx[IP].dst, "239.1.1.1")
1892 self.assertEqual(rx[UDP].dport, 48879)
1893 # the UDP source port is a random value for hashing
1894 self.assertEqual(rx[VXLAN].gpid, 112)
1895 self.assertEqual(rx[VXLAN].vni, 88)
1896 self.assertTrue(rx[VXLAN].flags.G)
1897 self.assertTrue(rx[VXLAN].flags.Instance)
1898 self.assertFalse(rx[VXLAN].gpflags.A)
1899 self.assertFalse(rx[VXLAN].gpflags.D)
1900
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001901 #
1902 # Check v6 Endpoints
1903 #
1904 for l in learnt:
1905 # a packet with an sclass from a knwon EPG
1906 p = (Ether(src=self.pg2.remote_mac,
1907 dst=self.pg2.local_mac) /
1908 IP(src=self.pg2.remote_hosts[1].ip4,
1909 dst=self.pg2.local_ip4) /
1910 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001911 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001912 Ether(src=l['mac'], dst=ep.mac) /
1913 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1914 UDP(sport=1234, dport=1234) /
1915 Raw('\xa5' * 100))
1916
1917 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1918
1919 self.assertTrue(find_gbp_endpoint(self,
1920 vx_tun_l2_1.sw_if_index,
1921 mac=l['mac']))
1922
1923 #
1924 # L3 Endpoint Learning
1925 # - configured on the bridge's BVI
1926 #
1927
1928 #
1929 # clean up
1930 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001931 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001932 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1933 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001934
1935 self.pg2.unconfig_ip4()
1936 self.pg3.unconfig_ip4()
1937 self.pg4.unconfig_ip4()
1938
1939 self.logger.info(self.vapi.cli("sh int"))
1940 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1941
Neale Rannsc29c0af2018-11-07 04:21:12 -08001942 def test_gbp_learn_vlan_l2(self):
1943 """ GBP L2 Endpoint w/ VLANs"""
1944
Neale Rannsb6a47952018-11-21 05:44:35 -08001945 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001946 learnt = [{'mac': '00:00:11:11:11:01',
1947 'ip': '10.0.0.1',
1948 'ip6': '2001:10::2'},
1949 {'mac': '00:00:11:11:11:02',
1950 'ip': '10.0.0.2',
1951 'ip6': '2001:10::3'}]
1952
1953 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08001954 # IP tables
1955 #
1956 gt4 = VppIpTable(self, 1)
1957 gt4.add_vpp_config()
1958 gt6 = VppIpTable(self, 1, is_ip6=True)
1959 gt6.add_vpp_config()
1960
1961 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1962 rd1.add_vpp_config()
1963
1964 #
1965 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1966 #
1967 self.pg2.config_ip4()
1968 self.pg2.resolve_arp()
1969 self.pg2.generate_remote_hosts(4)
1970 self.pg2.configure_ipv4_neighbors()
1971 self.pg3.config_ip4()
1972 self.pg3.resolve_arp()
1973
1974 #
1975 # The EP will be on a vlan sub-interface
1976 #
1977 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1978 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01001979 self.vapi.l2_interface_vlan_tag_rewrite(
1980 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
1981 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001982
1983 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1984 self.pg3.remote_ip4, 116)
1985 bd_uu_fwd.add_vpp_config()
1986
1987 #
1988 # a GBP bridge domain with a BVI and a UU-flood interface
1989 # The BD is marked as do not learn, so no endpoints are ever
1990 # learnt in this BD.
1991 #
1992 bd1 = VppBridgeDomain(self, 1)
1993 bd1.add_vpp_config()
1994 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1995 learn=False)
1996 gbd1.add_vpp_config()
1997
1998 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1999 self.logger.info(self.vapi.cli("sh gbp bridge"))
2000
2001 # ... and has a /32 applied
2002 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2003 ip_addr.add_vpp_config()
2004
2005 #
2006 # The Endpoint-group in which we are learning endpoints
2007 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002008 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002009 None, self.loop0,
2010 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002011 "2001:10::128",
2012 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002013 epg_220.add_vpp_config()
2014
2015 #
2016 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2017 # leanring enabled
2018 #
2019 vx_tun_l2_1 = VppGbpVxlanTunnel(
2020 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002021 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2022 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002023 vx_tun_l2_1.add_vpp_config()
2024
2025 #
2026 # A static endpoint that the learnt endpoints are trying to
2027 # talk to
2028 #
2029 ep = VppGbpEndpoint(self, vlan_11,
2030 epg_220, None,
2031 "10.0.0.127", "11.0.0.127",
2032 "2001:10::1", "3001::1")
2033 ep.add_vpp_config()
2034
2035 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2036
2037 #
2038 # Send to the static EP
2039 #
2040 for ii, l in enumerate(learnt):
2041 # a packet with an sclass from a knwon EPG
2042 # arriving on an unknown TEP
2043 p = (Ether(src=self.pg2.remote_mac,
2044 dst=self.pg2.local_mac) /
2045 IP(src=self.pg2.remote_hosts[1].ip4,
2046 dst=self.pg2.local_ip4) /
2047 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002048 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002049 Ether(src=l['mac'], dst=ep.mac) /
2050 IP(src=l['ip'], dst=ep.ip4.address) /
2051 UDP(sport=1234, dport=1234) /
2052 Raw('\xa5' * 100))
2053
2054 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2055
2056 #
2057 # packet to EP has the EP's vlan tag
2058 #
2059 for rx in rxs:
2060 self.assertEqual(rx[Dot1Q].vlan, 11)
2061
2062 #
2063 # the EP is not learnt since the BD setting prevents it
2064 # also no TEP too
2065 #
2066 self.assertFalse(find_gbp_endpoint(self,
2067 vx_tun_l2_1.sw_if_index,
2068 mac=l['mac']))
2069 self.assertEqual(INDEX_INVALID,
2070 find_vxlan_gbp_tunnel(
2071 self,
2072 self.pg2.local_ip4,
2073 self.pg2.remote_hosts[1].ip4,
2074 99))
2075
2076 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2077
2078 #
2079 # static to remotes
2080 # we didn't learn the remotes so they are sent to the UU-fwd
2081 #
2082 for l in learnt:
2083 p = (Ether(src=ep.mac, dst=l['mac']) /
2084 Dot1Q(vlan=11) /
2085 IP(dst=l['ip'], src=ep.ip4.address) /
2086 UDP(sport=1234, dport=1234) /
2087 Raw('\xa5' * 100))
2088
2089 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2090
2091 for rx in rxs:
2092 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2093 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2094 self.assertEqual(rx[UDP].dport, 48879)
2095 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002096 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002097 self.assertEqual(rx[VXLAN].vni, 116)
2098 self.assertTrue(rx[VXLAN].flags.G)
2099 self.assertTrue(rx[VXLAN].flags.Instance)
2100 self.assertFalse(rx[VXLAN].gpflags.A)
2101 self.assertFalse(rx[VXLAN].gpflags.D)
2102
2103 self.pg2.unconfig_ip4()
2104 self.pg3.unconfig_ip4()
2105
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002106 def test_gbp_learn_l3(self):
2107 """ GBP L3 Endpoint Learning """
2108
Neale Ranns13a08cc2018-11-07 09:25:54 -08002109 self.vapi.cli("set logging class gbp debug")
2110
Neale Rannsb6a47952018-11-21 05:44:35 -08002111 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002112 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2113 routed_src_mac = "00:22:bd:f8:19:ff"
2114
2115 learnt = [{'mac': '00:00:11:11:11:02',
2116 'ip': '10.0.1.2',
2117 'ip6': '2001:10::2'},
2118 {'mac': '00:00:11:11:11:03',
2119 'ip': '10.0.1.3',
2120 'ip6': '2001:10::3'}]
2121
2122 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002123 # IP tables
2124 #
2125 t4 = VppIpTable(self, 1)
2126 t4.add_vpp_config()
2127 t6 = VppIpTable(self, 1, True)
2128 t6.add_vpp_config()
2129
2130 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2131 self.pg4.remote_ip4, 114)
2132 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2133 self.pg4.remote_ip4, 116)
2134 tun_ip4_uu.add_vpp_config()
2135 tun_ip6_uu.add_vpp_config()
2136
2137 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2138 rd1.add_vpp_config()
2139
Ole Troan8006c6a2018-12-17 12:02:26 +01002140 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002141
2142 #
2143 # Bind the BVI to the RD
2144 #
2145 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2146 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2147
2148 #
2149 # Pg2 hosts the vxlan tunnel
2150 # hosts on pg2 to act as TEPs
2151 # pg3 is BD uu-fwd
2152 # pg4 is RD uu-fwd
2153 #
2154 self.pg2.config_ip4()
2155 self.pg2.resolve_arp()
2156 self.pg2.generate_remote_hosts(4)
2157 self.pg2.configure_ipv4_neighbors()
2158 self.pg3.config_ip4()
2159 self.pg3.resolve_arp()
2160 self.pg4.config_ip4()
2161 self.pg4.resolve_arp()
2162
2163 #
2164 # a GBP bridge domain with a BVI and a UU-flood interface
2165 #
2166 bd1 = VppBridgeDomain(self, 1)
2167 bd1.add_vpp_config()
2168 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2169 gbd1.add_vpp_config()
2170
2171 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2172 self.logger.info(self.vapi.cli("sh gbp bridge"))
2173 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002174
2175 # ... and has a /32 and /128 applied
2176 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2177 ip4_addr.add_vpp_config()
2178 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2179 ip6_addr.add_vpp_config()
2180
2181 #
2182 # The Endpoint-group in which we are learning endpoints
2183 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002184 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002185 None, self.loop0,
2186 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002187 "2001:10::128",
2188 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002189 epg_220.add_vpp_config()
2190
2191 #
2192 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2193 # leanring enabled
2194 #
2195 vx_tun_l3 = VppGbpVxlanTunnel(
2196 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002197 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2198 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002199 vx_tun_l3.add_vpp_config()
2200
2201 #
2202 # A static endpoint that the learnt endpoints are trying to
2203 # talk to
2204 #
2205 ep = VppGbpEndpoint(self, self.pg0,
2206 epg_220, None,
2207 "10.0.0.127", "11.0.0.127",
2208 "2001:10::1", "3001::1")
2209 ep.add_vpp_config()
2210
2211 #
2212 # learn some remote IPv4 EPs
2213 #
2214 for ii, l in enumerate(learnt):
2215 # a packet with an sclass from a knwon EPG
2216 # arriving on an unknown TEP
2217 p = (Ether(src=self.pg2.remote_mac,
2218 dst=self.pg2.local_mac) /
2219 IP(src=self.pg2.remote_hosts[1].ip4,
2220 dst=self.pg2.local_ip4) /
2221 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002222 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002223 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2224 IP(src=l['ip'], dst=ep.ip4.address) /
2225 UDP(sport=1234, dport=1234) /
2226 Raw('\xa5' * 100))
2227
2228 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2229
2230 # the new TEP
2231 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2232 self,
2233 self.pg2.local_ip4,
2234 self.pg2.remote_hosts[1].ip4,
2235 vx_tun_l3.vni)
2236 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2237
2238 # endpoint learnt via the parent GBP-vxlan interface
2239 self.assertTrue(find_gbp_endpoint(self,
2240 vx_tun_l3._sw_if_index,
2241 ip=l['ip']))
2242
2243 #
2244 # Static IPv4 EP replies to learnt
2245 #
2246 for l in learnt:
2247 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2248 IP(dst=l['ip'], src=ep.ip4.address) /
2249 UDP(sport=1234, dport=1234) /
2250 Raw('\xa5' * 100))
2251
2252 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2253
2254 for rx in rxs:
2255 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2256 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2257 self.assertEqual(rx[UDP].dport, 48879)
2258 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002259 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002260 self.assertEqual(rx[VXLAN].vni, 101)
2261 self.assertTrue(rx[VXLAN].flags.G)
2262 self.assertTrue(rx[VXLAN].flags.Instance)
2263 self.assertTrue(rx[VXLAN].gpflags.A)
2264 self.assertFalse(rx[VXLAN].gpflags.D)
2265
2266 inner = rx[VXLAN].payload
2267
2268 self.assertEqual(inner[Ether].src, routed_src_mac)
2269 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2270 self.assertEqual(inner[IP].src, ep.ip4.address)
2271 self.assertEqual(inner[IP].dst, l['ip'])
2272
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002273 for l in learnt:
2274 self.assertFalse(find_gbp_endpoint(self,
2275 tep1_sw_if_index,
2276 ip=l['ip']))
2277
2278 #
2279 # learn some remote IPv6 EPs
2280 #
2281 for ii, l in enumerate(learnt):
2282 # a packet with an sclass from a knwon EPG
2283 # arriving on an unknown TEP
2284 p = (Ether(src=self.pg2.remote_mac,
2285 dst=self.pg2.local_mac) /
2286 IP(src=self.pg2.remote_hosts[1].ip4,
2287 dst=self.pg2.local_ip4) /
2288 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002289 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002290 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2291 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2292 UDP(sport=1234, dport=1234) /
2293 Raw('\xa5' * 100))
2294
2295 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2296
2297 # the new TEP
2298 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2299 self,
2300 self.pg2.local_ip4,
2301 self.pg2.remote_hosts[1].ip4,
2302 vx_tun_l3.vni)
2303 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2304
2305 self.logger.info(self.vapi.cli("show gbp bridge"))
2306 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2307 self.logger.info(self.vapi.cli("show gbp vxlan"))
2308 self.logger.info(self.vapi.cli("show int addr"))
2309
2310 # endpoint learnt via the TEP
2311 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2312
2313 self.logger.info(self.vapi.cli("show gbp endpoint"))
2314 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2315
2316 #
2317 # Static EP replies to learnt
2318 #
2319 for l in learnt:
2320 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2321 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2322 UDP(sport=1234, dport=1234) /
2323 Raw('\xa5' * 100))
2324
2325 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2326
2327 for rx in rxs:
2328 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2329 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2330 self.assertEqual(rx[UDP].dport, 48879)
2331 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002332 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002333 self.assertEqual(rx[VXLAN].vni, 101)
2334 self.assertTrue(rx[VXLAN].flags.G)
2335 self.assertTrue(rx[VXLAN].flags.Instance)
2336 self.assertTrue(rx[VXLAN].gpflags.A)
2337 self.assertFalse(rx[VXLAN].gpflags.D)
2338
2339 inner = rx[VXLAN].payload
2340
2341 self.assertEqual(inner[Ether].src, routed_src_mac)
2342 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2343 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2344 self.assertEqual(inner[IPv6].dst, l['ip6'])
2345
2346 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002347 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002348 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002349
2350 #
2351 # Static sends to unknown EP with no route
2352 #
2353 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2354 IP(dst="10.0.0.99", src=ep.ip4.address) /
2355 UDP(sport=1234, dport=1234) /
2356 Raw('\xa5' * 100))
2357
2358 self.send_and_assert_no_replies(self.pg0, [p])
2359
2360 #
2361 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002362 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002363 #
2364 se_10_24 = VppGbpSubnet(
2365 self, rd1, "10.0.0.0", 24,
2366 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2367 se_10_24.add_vpp_config()
2368
2369 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2370 IP(dst="10.0.0.99", src=ep.ip4.address) /
2371 UDP(sport=1234, dport=1234) /
2372 Raw('\xa5' * 100))
2373
2374 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2375 for rx in rxs:
2376 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2377 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2378 self.assertEqual(rx[UDP].dport, 48879)
2379 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002380 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002381 self.assertEqual(rx[VXLAN].vni, 114)
2382 self.assertTrue(rx[VXLAN].flags.G)
2383 self.assertTrue(rx[VXLAN].flags.Instance)
2384 # policy is not applied to packets sent to the uu-fwd interfaces
2385 self.assertFalse(rx[VXLAN].gpflags.A)
2386 self.assertFalse(rx[VXLAN].gpflags.D)
2387
2388 #
2389 # learn some remote IPv4 EPs
2390 #
2391 for ii, l in enumerate(learnt):
2392 # a packet with an sclass from a knwon EPG
2393 # arriving on an unknown TEP
2394 p = (Ether(src=self.pg2.remote_mac,
2395 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002396 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002397 dst=self.pg2.local_ip4) /
2398 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002399 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002400 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2401 IP(src=l['ip'], dst=ep.ip4.address) /
2402 UDP(sport=1234, dport=1234) /
2403 Raw('\xa5' * 100))
2404
2405 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2406
2407 # the new TEP
2408 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2409 self,
2410 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002411 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002412 vx_tun_l3.vni)
2413 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2414
2415 # endpoint learnt via the parent GBP-vxlan interface
2416 self.assertTrue(find_gbp_endpoint(self,
2417 vx_tun_l3._sw_if_index,
2418 ip=l['ip']))
2419
2420 #
2421 # Add a remote endpoint from the API
2422 #
2423 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2424 epg_220, None,
2425 "10.0.0.88", "11.0.0.88",
2426 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002427 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002428 self.pg2.local_ip4,
2429 self.pg2.remote_hosts[1].ip4,
2430 mac=None)
2431 rep_88.add_vpp_config()
2432
2433 #
2434 # Add a remote endpoint from the API that matches an existing one
2435 #
2436 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2437 epg_220, None,
2438 learnt[0]['ip'], "11.0.0.101",
2439 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002440 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002441 self.pg2.local_ip4,
2442 self.pg2.remote_hosts[1].ip4,
2443 mac=None)
2444 rep_2.add_vpp_config()
2445
2446 #
2447 # Add a route to the leanred EP's v4 subnet
2448 # packets should be send on the v4/v6 uu=fwd interface resp.
2449 #
2450 se_10_1_24 = VppGbpSubnet(
2451 self, rd1, "10.0.1.0", 24,
2452 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2453 se_10_1_24.add_vpp_config()
2454
2455 self.logger.info(self.vapi.cli("show gbp endpoint"))
2456
2457 ips = ["10.0.0.88", learnt[0]['ip']]
2458 for ip in ips:
2459 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2460 IP(dst=ip, src=ep.ip4.address) /
2461 UDP(sport=1234, dport=1234) /
2462 Raw('\xa5' * 100))
2463
2464 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2465
2466 for rx in rxs:
2467 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2468 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2469 self.assertEqual(rx[UDP].dport, 48879)
2470 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002471 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002472 self.assertEqual(rx[VXLAN].vni, 101)
2473 self.assertTrue(rx[VXLAN].flags.G)
2474 self.assertTrue(rx[VXLAN].flags.Instance)
2475 self.assertTrue(rx[VXLAN].gpflags.A)
2476 self.assertFalse(rx[VXLAN].gpflags.D)
2477
2478 inner = rx[VXLAN].payload
2479
2480 self.assertEqual(inner[Ether].src, routed_src_mac)
2481 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2482 self.assertEqual(inner[IP].src, ep.ip4.address)
2483 self.assertEqual(inner[IP].dst, ip)
2484
2485 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002486 # remove the API remote EPs, only API sourced is gone, the DP
2487 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002488 #
2489 rep_88.remove_vpp_config()
2490 rep_2.remove_vpp_config()
2491
Neale Ranns00a469d2018-12-20 06:12:19 -08002492 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2493
2494 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2495 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2496 UDP(sport=1234, dport=1234) /
2497 Raw('\xa5' * 100))
2498 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002499
Neale Ranns13a08cc2018-11-07 09:25:54 -08002500 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002501
Neale Ranns13a08cc2018-11-07 09:25:54 -08002502 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2503 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2504 UDP(sport=1234, dport=1234) /
2505 Raw('\xa5' * 100))
2506 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002507
Neale Ranns13a08cc2018-11-07 09:25:54 -08002508 #
2509 # to appease the testcase we cannot have the registered EP stll
2510 # present (because it's DP learnt) when the TC ends so wait until
2511 # it is removed
2512 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002513 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2514 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002515
2516 #
2517 # shutdown with learnt endpoint present
2518 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002519 p = (Ether(src=self.pg2.remote_mac,
2520 dst=self.pg2.local_mac) /
2521 IP(src=self.pg2.remote_hosts[1].ip4,
2522 dst=self.pg2.local_ip4) /
2523 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002524 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002525 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2526 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2527 UDP(sport=1234, dport=1234) /
2528 Raw('\xa5' * 100))
2529
2530 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2531
2532 # endpoint learnt via the parent GBP-vxlan interface
2533 self.assertTrue(find_gbp_endpoint(self,
2534 vx_tun_l3._sw_if_index,
2535 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002536
2537 #
2538 # TODO
2539 # remote endpoint becomes local
2540 #
2541 self.pg2.unconfig_ip4()
2542 self.pg3.unconfig_ip4()
2543 self.pg4.unconfig_ip4()
2544
Neale Ranns13a08cc2018-11-07 09:25:54 -08002545 def test_gbp_redirect(self):
2546 """ GBP Endpoint Redirect """
2547
2548 self.vapi.cli("set logging class gbp debug")
2549
Neale Rannsb6a47952018-11-21 05:44:35 -08002550 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002551 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2552 routed_src_mac = "00:22:bd:f8:19:ff"
2553
2554 learnt = [{'mac': '00:00:11:11:11:02',
2555 'ip': '10.0.1.2',
2556 'ip6': '2001:10::2'},
2557 {'mac': '00:00:11:11:11:03',
2558 'ip': '10.0.1.3',
2559 'ip6': '2001:10::3'}]
2560
2561 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002562 # IP tables
2563 #
2564 t4 = VppIpTable(self, 1)
2565 t4.add_vpp_config()
2566 t6 = VppIpTable(self, 1, True)
2567 t6.add_vpp_config()
2568
2569 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2570 rd1.add_vpp_config()
2571
Ole Troan8006c6a2018-12-17 12:02:26 +01002572 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002573
2574 #
2575 # Bind the BVI to the RD
2576 #
2577 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2578 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2579
2580 #
2581 # Pg7 hosts a BD's UU-fwd
2582 #
2583 self.pg7.config_ip4()
2584 self.pg7.resolve_arp()
2585
2586 #
2587 # a GBP bridge domains for the EPs
2588 #
2589 bd1 = VppBridgeDomain(self, 1)
2590 bd1.add_vpp_config()
2591 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2592 gbd1.add_vpp_config()
2593
2594 bd2 = VppBridgeDomain(self, 2)
2595 bd2.add_vpp_config()
2596 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2597 gbd2.add_vpp_config()
2598
2599 # ... and has a /32 and /128 applied
2600 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2601 ip4_addr.add_vpp_config()
2602 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2603 ip6_addr.add_vpp_config()
2604 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2605 ip4_addr.add_vpp_config()
2606 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2607 ip6_addr.add_vpp_config()
2608
2609 #
2610 # The Endpoint-groups in which we are learning endpoints
2611 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002612 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002613 None, gbd1.bvi,
2614 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002615 "2001:10::128",
2616 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002617 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002618 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002619 None, gbd2.bvi,
2620 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002621 "2001:11::128",
2622 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002623 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002624 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002625 None, gbd1.bvi,
2626 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002627 "2001:12::128",
2628 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002629 epg_222.add_vpp_config()
2630
2631 #
2632 # a GBP bridge domains for the SEPs
2633 #
2634 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2635 self.pg7.remote_ip4, 116)
2636 bd_uu1.add_vpp_config()
2637 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2638 self.pg7.remote_ip4, 117)
2639 bd_uu2.add_vpp_config()
2640
2641 bd3 = VppBridgeDomain(self, 3)
2642 bd3.add_vpp_config()
2643 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2644 gbd3.add_vpp_config()
2645 bd4 = VppBridgeDomain(self, 4)
2646 bd4.add_vpp_config()
2647 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2648 gbd4.add_vpp_config()
2649
2650 #
2651 # EPGs in which the service endpoints exist
2652 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002653 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002654 None, gbd1.bvi,
2655 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002656 "4001:10::128",
2657 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002658 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002659 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002660 None, gbd2.bvi,
2661 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002662 "4001:11::128",
2663 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002664 epg_321.add_vpp_config()
2665
2666 #
2667 # three local endpoints
2668 #
2669 ep1 = VppGbpEndpoint(self, self.pg0,
2670 epg_220, None,
2671 "10.0.0.1", "11.0.0.1",
2672 "2001:10::1", "3001:10::1")
2673 ep1.add_vpp_config()
2674 ep2 = VppGbpEndpoint(self, self.pg1,
2675 epg_221, None,
2676 "10.0.1.1", "11.0.1.1",
2677 "2001:11::1", "3001:11::1")
2678 ep2.add_vpp_config()
2679 ep3 = VppGbpEndpoint(self, self.pg2,
2680 epg_222, None,
2681 "10.0.2.2", "11.0.2.2",
2682 "2001:12::1", "3001:12::1")
2683 ep3.add_vpp_config()
2684
2685 #
2686 # service endpoints
2687 #
2688 sep1 = VppGbpEndpoint(self, self.pg3,
2689 epg_320, None,
2690 "12.0.0.1", "13.0.0.1",
2691 "4001:10::1", "5001:10::1")
2692 sep1.add_vpp_config()
2693 sep2 = VppGbpEndpoint(self, self.pg4,
2694 epg_320, None,
2695 "12.0.0.2", "13.0.0.2",
2696 "4001:10::2", "5001:10::2")
2697 sep2.add_vpp_config()
2698 sep3 = VppGbpEndpoint(self, self.pg5,
2699 epg_321, None,
2700 "12.0.1.1", "13.0.1.1",
2701 "4001:11::1", "5001:11::1")
2702 sep3.add_vpp_config()
2703 # this EP is not installed immediately
2704 sep4 = VppGbpEndpoint(self, self.pg6,
2705 epg_321, None,
2706 "12.0.1.2", "13.0.1.2",
2707 "4001:11::2", "5001:11::2")
2708
2709 #
2710 # an L2 switch packet between local EPs in different EPGs
2711 # different dest ports on each so the are LB hashed differently
2712 #
2713 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2714 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2715 UDP(sport=1234, dport=1234) /
2716 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002717 (Ether(src=ep3.mac, dst=ep1.mac) /
2718 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2719 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002720 Raw('\xa5' * 100))]
2721 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2722 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2723 UDP(sport=1234, dport=1234) /
2724 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002725 (Ether(src=ep3.mac, dst=ep1.mac) /
2726 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002727 UDP(sport=1234, dport=1230) /
2728 Raw('\xa5' * 100))]
2729
2730 # should be dropped since no contract yet
2731 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2732 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2733
2734 #
2735 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2736 # one of the next-hops is via an EP that is not known
2737 #
2738 acl = VppGbpAcl(self)
2739 rule4 = acl.create_rule(permit_deny=1, proto=17)
2740 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2741 acl_index = acl.add_vpp_config([rule4, rule6])
2742
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002743 #
2744 # test the src-ip hash mode
2745 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002746 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002747 self, epg_220, epg_222, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002748 [VppGbpContractRule(
2749 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002750 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002751 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2752 sep1.ip4, sep1.epg.rd),
2753 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2754 sep2.ip4, sep2.epg.rd)]),
2755 VppGbpContractRule(
2756 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002757 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002758 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2759 sep3.ip6, sep3.epg.rd),
2760 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002761 sep4.ip6, sep4.epg.rd)])],
2762 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002763 c1.add_vpp_config()
2764
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002765 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002766 self, epg_222, epg_220, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002767 [VppGbpContractRule(
2768 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2769 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2770 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2771 sep1.ip4, sep1.epg.rd),
2772 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2773 sep2.ip4, sep2.epg.rd)]),
2774 VppGbpContractRule(
2775 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2776 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2777 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2778 sep3.ip6, sep3.epg.rd),
2779 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002780 sep4.ip6, sep4.epg.rd)])],
2781 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002782 c2.add_vpp_config()
2783
Neale Ranns13a08cc2018-11-07 09:25:54 -08002784 #
2785 # send again with the contract preset, now packets arrive
2786 # at SEP1 or SEP2 depending on the hashing
2787 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002788 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002789
2790 for rx in rxs:
2791 self.assertEqual(rx[Ether].src, routed_src_mac)
2792 self.assertEqual(rx[Ether].dst, sep1.mac)
2793 self.assertEqual(rx[IP].src, ep1.ip4.address)
2794 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2795
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002796 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2797
2798 for rx in rxs:
2799 self.assertEqual(rx[Ether].src, routed_src_mac)
2800 self.assertEqual(rx[Ether].dst, sep2.mac)
2801 self.assertEqual(rx[IP].src, ep3.ip4.address)
2802 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2803
Neale Ranns13a08cc2018-11-07 09:25:54 -08002804 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2805
2806 for rx in rxs:
2807 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2808 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2809 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2810 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2811 self.assertEqual(rx[VXLAN].vni, 117)
2812 self.assertTrue(rx[VXLAN].flags.G)
2813 self.assertTrue(rx[VXLAN].flags.Instance)
2814 # redirect policy has been applied
2815 self.assertTrue(rx[VXLAN].gpflags.A)
2816 self.assertFalse(rx[VXLAN].gpflags.D)
2817
2818 inner = rx[VXLAN].payload
2819
2820 self.assertEqual(inner[Ether].src, routed_src_mac)
2821 self.assertEqual(inner[Ether].dst, sep4.mac)
2822 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2823 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2824
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002825 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002826
2827 for rx in rxs:
2828 self.assertEqual(rx[Ether].src, routed_src_mac)
2829 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002830 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2831 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002832
2833 #
2834 # programme the unknown EP
2835 #
2836 sep4.add_vpp_config()
2837
2838 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2839
2840 for rx in rxs:
2841 self.assertEqual(rx[Ether].src, routed_src_mac)
2842 self.assertEqual(rx[Ether].dst, sep4.mac)
2843 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2844 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2845
2846 #
2847 # and revert back to unprogrammed
2848 #
2849 sep4.remove_vpp_config()
2850
2851 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2852
2853 for rx in rxs:
2854 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2855 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2856 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2857 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2858 self.assertEqual(rx[VXLAN].vni, 117)
2859 self.assertTrue(rx[VXLAN].flags.G)
2860 self.assertTrue(rx[VXLAN].flags.Instance)
2861 # redirect policy has been applied
2862 self.assertTrue(rx[VXLAN].gpflags.A)
2863 self.assertFalse(rx[VXLAN].gpflags.D)
2864
2865 inner = rx[VXLAN].payload
2866
2867 self.assertEqual(inner[Ether].src, routed_src_mac)
2868 self.assertEqual(inner[Ether].dst, sep4.mac)
2869 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2870 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2871
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002872 c1.remove_vpp_config()
2873 c2.remove_vpp_config()
2874
2875 #
2876 # test the symmetric hash mode
2877 #
2878 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002879 self, epg_220, epg_222, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002880 [VppGbpContractRule(
2881 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2882 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2883 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2884 sep1.ip4, sep1.epg.rd),
2885 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2886 sep2.ip4, sep2.epg.rd)]),
2887 VppGbpContractRule(
2888 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2889 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2890 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2891 sep3.ip6, sep3.epg.rd),
2892 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002893 sep4.ip6, sep4.epg.rd)])],
2894 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002895 c1.add_vpp_config()
2896
2897 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002898 self, epg_222, epg_220, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002899 [VppGbpContractRule(
2900 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2901 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2902 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2903 sep1.ip4, sep1.epg.rd),
2904 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2905 sep2.ip4, sep2.epg.rd)]),
2906 VppGbpContractRule(
2907 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2908 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2909 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2910 sep3.ip6, sep3.epg.rd),
2911 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002912 sep4.ip6, sep4.epg.rd)])],
2913 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002914 c2.add_vpp_config()
2915
2916 #
2917 # send again with the contract preset, now packets arrive
2918 # at SEP1 for both directions
2919 #
2920 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2921
2922 for rx in rxs:
2923 self.assertEqual(rx[Ether].src, routed_src_mac)
2924 self.assertEqual(rx[Ether].dst, sep1.mac)
2925 self.assertEqual(rx[IP].src, ep1.ip4.address)
2926 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2927
2928 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2929
2930 for rx in rxs:
2931 self.assertEqual(rx[Ether].src, routed_src_mac)
2932 self.assertEqual(rx[Ether].dst, sep1.mac)
2933 self.assertEqual(rx[IP].src, ep3.ip4.address)
2934 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2935
Neale Ranns13a08cc2018-11-07 09:25:54 -08002936 #
2937 # programme the unknown EP for the L3 tests
2938 #
2939 sep4.add_vpp_config()
2940
2941 #
2942 # an L3 switch packet between local EPs in different EPGs
2943 # different dest ports on each so the are LB hashed differently
2944 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002945 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002946 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2947 UDP(sport=1234, dport=1234) /
2948 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002949 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002950 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2951 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002952 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002953 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002954 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2955 UDP(sport=1234, dport=1234) /
2956 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002957 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002958 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2959 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002960 Raw('\xa5' * 100))]
2961
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002962 c3 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002963 self, epg_220, epg_221, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002964 [VppGbpContractRule(
2965 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2966 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2967 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2968 sep1.ip4, sep1.epg.rd),
2969 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2970 sep2.ip4, sep2.epg.rd)]),
2971 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002972 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002973 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002974 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2975 sep3.ip6, sep3.epg.rd),
2976 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2977 sep4.ip6, sep4.epg.rd)])],
2978 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002979 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002980
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002981 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002982
2983 for rx in rxs:
2984 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002985 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002986 self.assertEqual(rx[IP].src, ep1.ip4.address)
2987 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2988
2989 #
2990 # learn a remote EP in EPG 221
2991 #
2992 vx_tun_l3 = VppGbpVxlanTunnel(
2993 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002994 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2995 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002996 vx_tun_l3.add_vpp_config()
2997
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002998 c4 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002999 self, epg_221, epg_220, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003000 [VppGbpContractRule(
3001 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3002 []),
3003 VppGbpContractRule(
3004 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003005 [])],
3006 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003007 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003008
3009 p = (Ether(src=self.pg7.remote_mac,
3010 dst=self.pg7.local_mac) /
3011 IP(src=self.pg7.remote_ip4,
3012 dst=self.pg7.local_ip4) /
3013 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003014 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003015 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003016 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3017 UDP(sport=1234, dport=1234) /
3018 Raw('\xa5' * 100))
3019
3020 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3021
3022 # endpoint learnt via the parent GBP-vxlan interface
3023 self.assertTrue(find_gbp_endpoint(self,
3024 vx_tun_l3._sw_if_index,
3025 ip="10.0.0.88"))
3026
3027 p = (Ether(src=self.pg7.remote_mac,
3028 dst=self.pg7.local_mac) /
3029 IP(src=self.pg7.remote_ip4,
3030 dst=self.pg7.local_ip4) /
3031 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003032 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003033 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003034 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3035 UDP(sport=1234, dport=1234) /
3036 Raw('\xa5' * 100))
3037
3038 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3039
3040 # endpoint learnt via the parent GBP-vxlan interface
3041 self.assertTrue(find_gbp_endpoint(self,
3042 vx_tun_l3._sw_if_index,
3043 ip="2001:10::88"))
3044
3045 #
3046 # L3 switch from local to remote EP
3047 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003048 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003049 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3050 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003051 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003052 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003053 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3054 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003055 Raw('\xa5' * 100))]
3056
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003057 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003058
3059 for rx in rxs:
3060 self.assertEqual(rx[Ether].src, routed_src_mac)
3061 self.assertEqual(rx[Ether].dst, sep1.mac)
3062 self.assertEqual(rx[IP].src, ep1.ip4.address)
3063 self.assertEqual(rx[IP].dst, "10.0.0.88")
3064
3065 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3066
3067 for rx in rxs:
3068 self.assertEqual(rx[Ether].src, routed_src_mac)
3069 self.assertEqual(rx[Ether].dst, sep4.mac)
3070 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3071 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3072
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003073 #
3074 # test the dst-ip hash mode
3075 #
3076 c5 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00003077 self, epg_220, epg_221, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003078 [VppGbpContractRule(
3079 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3080 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3081 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3082 sep1.ip4, sep1.epg.rd),
3083 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3084 sep2.ip4, sep2.epg.rd)]),
3085 VppGbpContractRule(
3086 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3087 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3088 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3089 sep3.ip6, sep3.epg.rd),
3090 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003091 sep4.ip6, sep4.epg.rd)])],
3092 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003093 c5.add_vpp_config()
3094
3095 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3096
3097 for rx in rxs:
3098 self.assertEqual(rx[Ether].src, routed_src_mac)
3099 self.assertEqual(rx[Ether].dst, sep1.mac)
3100 self.assertEqual(rx[IP].src, ep1.ip4.address)
3101 self.assertEqual(rx[IP].dst, "10.0.0.88")
3102
3103 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003104
3105 for rx in rxs:
3106 self.assertEqual(rx[Ether].src, routed_src_mac)
3107 self.assertEqual(rx[Ether].dst, sep3.mac)
3108 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3109 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3110
Neale Rannsb6a47952018-11-21 05:44:35 -08003111 #
3112 # cleanup
3113 #
3114 self.pg7.unconfig_ip4()
3115
3116 def test_gbp_l3_out(self):
3117 """ GBP L3 Out """
3118
3119 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3120 self.vapi.cli("set logging class gbp debug")
3121
3122 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3123 routed_src_mac = "00:22:bd:f8:19:ff"
3124
3125 #
3126 # IP tables
3127 #
3128 t4 = VppIpTable(self, 1)
3129 t4.add_vpp_config()
3130 t6 = VppIpTable(self, 1, True)
3131 t6.add_vpp_config()
3132
3133 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3134 rd1.add_vpp_config()
3135
Ole Troan8006c6a2018-12-17 12:02:26 +01003136 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003137
3138 #
3139 # Bind the BVI to the RD
3140 #
3141 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3142 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3143
3144 #
3145 # Pg7 hosts a BD's BUM
3146 # Pg1 some other l3 interface
3147 #
3148 self.pg7.config_ip4()
3149 self.pg7.resolve_arp()
3150
3151 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003152 # a multicast vxlan-gbp tunnel for broadcast in the BD
3153 #
3154 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3155 "239.1.1.1", 88,
3156 mcast_itf=self.pg7)
3157 tun_bm.add_vpp_config()
3158
3159 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003160 # a GBP external bridge domains for the EPs
3161 #
3162 bd1 = VppBridgeDomain(self, 1)
3163 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003164 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003165 gbd1.add_vpp_config()
3166
3167 #
3168 # The Endpoint-groups in which the external endpoints exist
3169 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003170 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003171 None, gbd1.bvi,
3172 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003173 "2001:10::128",
3174 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003175 epg_220.add_vpp_config()
3176
3177 # the BVIs have the subnets applied ...
3178 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3179 ip4_addr.add_vpp_config()
3180 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3181 ip6_addr.add_vpp_config()
3182
3183 # ... which are L3-out subnets
3184 l3o_1 = VppGbpSubnet(
3185 self, rd1, "10.0.0.0", 24,
3186 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4ba67722019-02-28 11:11:39 +00003187 epg=epg_220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003188 l3o_1.add_vpp_config()
3189
3190 #
3191 # an external interface attached to the outside world and the
3192 # external BD
3193 #
3194 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3195 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003196 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3197 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3198 vlan_101.admin_up()
3199 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3200
3201 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003202 ext_itf.add_vpp_config()
3203
3204 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003205 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003206 #
3207 vx_tun_l3 = VppGbpVxlanTunnel(
3208 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003209 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3210 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003211 vx_tun_l3.add_vpp_config()
3212
3213 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003214 # External Endpoints
3215 #
3216 eep1 = VppGbpEndpoint(self, vlan_100,
3217 epg_220, None,
3218 "10.0.0.1", "11.0.0.1",
3219 "2001:10::1", "3001::1",
3220 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3221 eep1.add_vpp_config()
3222 eep2 = VppGbpEndpoint(self, vlan_101,
3223 epg_220, None,
3224 "10.0.0.2", "11.0.0.2",
3225 "2001:10::2", "3001::2",
3226 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3227 eep2.add_vpp_config()
3228
3229 #
3230 # A remote endpoint
3231 #
3232 rep = VppGbpEndpoint(self, vx_tun_l3,
3233 epg_220, None,
3234 "10.0.0.101", "11.0.0.101",
3235 "2001:10::101", "3001::101",
3236 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3237 self.pg7.local_ip4,
3238 self.pg7.remote_ip4,
3239 mac=None)
3240 rep.add_vpp_config()
3241
3242 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003243 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003244 # are ARP'd for
3245 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003246 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003247 Dot1Q(vlan=100) /
3248 IP(src="10.0.0.1", dst="10.0.0.88") /
3249 UDP(sport=1234, dport=1234) /
3250 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003251 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003252 Dot1Q(vlan=100) /
3253 IPv6(src="2001:10::1", dst="2001:10::88") /
3254 UDP(sport=1234, dport=1234) /
3255 Raw('\xa5' * 100))
3256
3257 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3258
3259 for rx in rxs:
3260 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3261 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3262 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3263 self.assertEqual(rx[IP].dst, "239.1.1.1")
3264 self.assertEqual(rx[VXLAN].vni, 88)
3265 self.assertTrue(rx[VXLAN].flags.G)
3266 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003267 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003268 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003269 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003270 self.assertFalse(rx[VXLAN].gpflags.D)
3271
3272 inner = rx[VXLAN].payload
3273
3274 self.assertTrue(inner.haslayer(ARP))
3275
3276 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003277 # remote to external
3278 #
3279 p = (Ether(src=self.pg7.remote_mac,
3280 dst=self.pg7.local_mac) /
3281 IP(src=self.pg7.remote_ip4,
3282 dst=self.pg7.local_ip4) /
3283 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003284 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003285 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003286 IP(src="10.0.0.101", dst="10.0.0.1") /
3287 UDP(sport=1234, dport=1234) /
3288 Raw('\xa5' * 100))
3289
3290 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3291
3292 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003293 # local EP pings router
3294 #
3295 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3296 Dot1Q(vlan=100) /
3297 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3298 ICMP(type='echo-request'))
3299
3300 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3301
3302 for rx in rxs:
3303 self.assertEqual(rx[Ether].src, str(self.router_mac))
3304 self.assertEqual(rx[Ether].dst, eep1.mac)
3305 self.assertEqual(rx[Dot1Q].vlan, 100)
3306
3307 #
3308 # local EP pings other local EP
3309 #
3310 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3311 Dot1Q(vlan=100) /
3312 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3313 ICMP(type='echo-request'))
3314
3315 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3316
3317 for rx in rxs:
3318 self.assertEqual(rx[Ether].src, eep1.mac)
3319 self.assertEqual(rx[Ether].dst, eep2.mac)
3320 self.assertEqual(rx[Dot1Q].vlan, 101)
3321
3322 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003323 # A subnet reachable through the external EP
3324 #
3325 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003326 [VppRoutePath(eep1.ip4.address,
3327 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003328 table_id=t4.table_id)
3329 ip_220.add_vpp_config()
3330
3331 l3o_220 = VppGbpSubnet(
3332 self, rd1, "10.220.0.0", 24,
3333 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4ba67722019-02-28 11:11:39 +00003334 epg=epg_220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003335 l3o_220.add_vpp_config()
3336
3337 p = (Ether(src=self.pg7.remote_mac,
3338 dst=self.pg7.local_mac) /
3339 IP(src=self.pg7.remote_ip4,
3340 dst=self.pg7.local_ip4) /
3341 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003342 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003343 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003344 IP(src="10.0.0.101", dst="10.220.0.1") /
3345 UDP(sport=1234, dport=1234) /
3346 Raw('\xa5' * 100))
3347
3348 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3349
3350 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003351 # A subnet reachable through the external EP
3352 #
3353 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3354 [VppRoutePath(eep2.ip4.address,
3355 eep2.epg.bvi.sw_if_index)],
3356 table_id=t4.table_id)
3357 ip_221.add_vpp_config()
3358
3359 l3o_221 = VppGbpSubnet(
3360 self, rd1, "10.221.0.0", 24,
3361 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3362 epg=epg_220)
3363 l3o_221.add_vpp_config()
3364
3365 #
3366 # ping between hosts in remote subnets
3367 #
3368 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3369 Dot1Q(vlan=100) /
3370 IP(src="10.220.0.1", dst="10.221.0.1") /
3371 ICMP(type='echo-request'))
3372
3373 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3374
3375 for rx in rxs:
3376 self.assertEqual(rx[Ether].src, str(self.router_mac))
3377 self.assertEqual(rx[Ether].dst, eep2.mac)
3378 self.assertEqual(rx[Dot1Q].vlan, 101)
3379
3380 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003381 # cleanup
3382 #
3383 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003384 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003385
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003386
3387if __name__ == '__main__':
3388 unittest.main(testRunner=VppTestRunner)