blob: 09d218d8ac3cea6c92a2a915c16faf3625da27a5 [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 Rannsbc27d1b2018-02-05 01:13:38 -08008from scapy.layers.inet import IP, UDP
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, \
22 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port
23from 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
71 def mac(self):
72 return self.itf.remote_mac
73
Neale Rannsc0a93142018-09-05 15:42:26 -070074 @property
75 def ip4(self):
76 return self._ip4
77
78 @property
79 def fip4(self):
80 return self._fip4
81
82 @property
83 def ip6(self):
84 return self._ip6
85
86 @property
87 def fip6(self):
88 return self._fip6
89
90 @property
91 def ips(self):
92 return [self.ip4, self.ip6]
93
94 @property
95 def fips(self):
96 return [self.fip4, self.fip6]
97
Neale Ranns93cc3ee2018-10-10 07:22:51 -070098 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
99 flags=0,
100 tun_src="0.0.0.0",
101 tun_dst="0.0.0.0",
102 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800103 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700104 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800105 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700106 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700107
108 self._ip4 = VppIpAddress(ip4)
109 self._fip4 = VppIpAddress(fip4)
110 self._ip6 = VppIpAddress(ip6)
111 self._fip6 = VppIpAddress(fip6)
112
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700113 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100114 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700115 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100116 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700117
118 self.flags = flags
119 self.tun_src = VppIpAddress(tun_src)
120 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800121
122 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700123 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700124 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700125 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100126 self.vmac.packed,
Neale Ranns4ba67722019-02-28 11:11:39 +0000127 self.epg.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700128 self.flags,
129 self.tun_src.encode(),
130 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700131 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800132 self._test.registry.register(self, self._test.logger)
133
134 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700135 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800136
137 def __str__(self):
138 return self.object_id()
139
140 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700141 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
142 self.itf.sw_if_index,
143 self.ip4.address,
Neale Ranns4ba67722019-02-28 11:11:39 +0000144 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800145
146 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700147 return find_gbp_endpoint(self._test,
148 self.itf.sw_if_index,
149 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700150
151
152class VppGbpRecirc(VppObject):
153 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200154 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700155 """
156
157 def __init__(self, test, epg, recirc, is_ext=False):
158 self._test = test
159 self.recirc = recirc
160 self.epg = epg
161 self.is_ext = is_ext
162
163 def add_vpp_config(self):
164 self._test.vapi.gbp_recirc_add_del(
165 1,
166 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000167 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700168 self.is_ext)
169 self._test.registry.register(self, self._test.logger)
170
171 def remove_vpp_config(self):
172 self._test.vapi.gbp_recirc_add_del(
173 0,
174 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000175 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700176 self.is_ext)
177
178 def __str__(self):
179 return self.object_id()
180
181 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700182 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700183
184 def query_vpp_config(self):
185 rs = self._test.vapi.gbp_recirc_dump()
186 for r in rs:
187 if r.recirc.sw_if_index == self.recirc.sw_if_index:
188 return True
189 return False
190
191
Neale Rannsb6a47952018-11-21 05:44:35 -0800192class VppGbpExtItf(VppObject):
193 """
194 GBP ExtItfulation Interface
195 """
196
197 def __init__(self, test, itf, bd, rd):
198 self._test = test
199 self.itf = itf
200 self.bd = bd
201 self.rd = rd
202
203 def add_vpp_config(self):
204 self._test.vapi.gbp_ext_itf_add_del(
205 1,
206 self.itf.sw_if_index,
207 self.bd.bd_id,
208 self.rd.rd_id)
209 self._test.registry.register(self, self._test.logger)
210
211 def remove_vpp_config(self):
212 self._test.vapi.gbp_ext_itf_add_del(
213 0,
214 self.itf.sw_if_index,
215 self.bd.bd_id,
216 self.rd.rd_id)
217
218 def __str__(self):
219 return self.object_id()
220
221 def object_id(self):
222 return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index)
223
224 def query_vpp_config(self):
225 rs = self._test.vapi.gbp_ext_itf_dump()
226 for r in rs:
227 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
228 return True
229 return False
230
231
Neale Ranns25b04942018-04-04 09:34:50 -0700232class VppGbpSubnet(VppObject):
233 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200234 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700235 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700236 def __init__(self, test, rd, address, address_len,
237 type, sw_if_index=None, epg=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700238 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700239 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200240 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700241 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700242 self.sw_if_index = sw_if_index
243 self.epg = epg
244
245 def add_vpp_config(self):
246 self._test.vapi.gbp_subnet_add_del(
247 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700248 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200249 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700250 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700251 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4ba67722019-02-28 11:11:39 +0000252 sclass=self.epg.sclass if self.epg else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700253 self._test.registry.register(self, self._test.logger)
254
255 def remove_vpp_config(self):
256 self._test.vapi.gbp_subnet_add_del(
257 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700258 self.rd_id,
259 self.prefix.encode(),
260 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700261
262 def __str__(self):
263 return self.object_id()
264
265 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700266 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700267
268 def query_vpp_config(self):
269 ss = self._test.vapi.gbp_subnet_dump()
270 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700271 if s.subnet.rd_id == self.rd_id and \
272 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200273 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700274 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700275 return False
276
277
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800278class VppGbpEndpointRetention(object):
279 def __init__(self, remote_ep_timeout=0xffffffff):
280 self.remote_ep_timeout = remote_ep_timeout
281
282 def encode(self):
283 return {'remote_ep_timeout': self.remote_ep_timeout}
284
285
Neale Ranns25b04942018-04-04 09:34:50 -0700286class VppGbpEndpointGroup(VppObject):
287 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200288 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700289 """
290
Neale Ranns4ba67722019-02-28 11:11:39 +0000291 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800292 bvi, bvi_ip4, bvi_ip6=None,
293 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700294 self._test = test
295 self.uplink = uplink
296 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700297 self.bvi_ip4 = VppIpAddress(bvi_ip4)
298 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000299 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700300 self.bd = bd
301 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800302 self.sclass = sclass
303 if 0 == self.sclass:
304 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800305 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700306
307 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700308 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000309 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800310 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700311 self.bd.bd.bd_id,
312 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800313 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
314 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700315 self._test.registry.register(self, self._test.logger)
316
317 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000318 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700319
320 def __str__(self):
321 return self.object_id()
322
323 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000324 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700325
326 def query_vpp_config(self):
327 epgs = self._test.vapi.gbp_endpoint_group_dump()
328 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000329 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800330 return True
331 return False
332
333
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700334class VppGbpBridgeDomain(VppObject):
335 """
336 GBP Bridge Domain
337 """
338
Neale Ranns879d11c2019-01-21 23:34:18 -0800339 def __init__(self, test, bd, bvi, uu_fwd=None,
340 bm_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700341 self._test = test
342 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800343 self.uu_fwd = uu_fwd
344 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700345 self.bd = bd
346
Neale Rannsc29c0af2018-11-07 04:21:12 -0800347 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
348 if (learn):
349 self.learn = e.GBP_BD_API_FLAG_NONE
350 else:
351 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
352
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700353 def add_vpp_config(self):
354 self._test.vapi.gbp_bridge_domain_add(
355 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800356 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700357 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800358 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
359 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700360 self._test.registry.register(self, self._test.logger)
361
362 def remove_vpp_config(self):
363 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
364
365 def __str__(self):
366 return self.object_id()
367
368 def object_id(self):
369 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
370
371 def query_vpp_config(self):
372 bds = self._test.vapi.gbp_bridge_domain_dump()
373 for bd in bds:
374 if bd.bd.bd_id == self.bd.bd_id:
375 return True
376 return False
377
378
379class VppGbpRouteDomain(VppObject):
380 """
381 GBP Route Domain
382 """
383
384 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
385 self._test = test
386 self.rd_id = rd_id
387 self.t4 = t4
388 self.t6 = t6
389 self.ip4_uu = ip4_uu
390 self.ip6_uu = ip6_uu
391
392 def add_vpp_config(self):
393 self._test.vapi.gbp_route_domain_add(
394 self.rd_id,
395 self.t4.table_id,
396 self.t6.table_id,
397 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
398 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
399 self._test.registry.register(self, self._test.logger)
400
401 def remove_vpp_config(self):
402 self._test.vapi.gbp_route_domain_del(self.rd_id)
403
404 def __str__(self):
405 return self.object_id()
406
407 def object_id(self):
408 return "gbp-route-domain:[%d]" % (self.rd_id)
409
410 def query_vpp_config(self):
411 rds = self._test.vapi.gbp_route_domain_dump()
412 for rd in rds:
413 if rd.rd.rd_id == self.rd_id:
414 return True
415 return False
416
417
Neale Ranns13a08cc2018-11-07 09:25:54 -0800418class VppGbpContractNextHop():
419 def __init__(self, mac, bd, ip, rd):
420 self.mac = mac
421 self.ip = ip
422 self.bd = bd
423 self.rd = rd
424
425 def encode(self):
426 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100427 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800428 'bd_id': self.bd.bd.bd_id,
429 'rd_id': self.rd.rd_id}
430
431
432class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100433 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800434 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100435 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800436 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800437
438 def encode(self):
439 nhs = []
440 for nh in self.nhs:
441 nhs.append(nh.encode())
442 while len(nhs) < 8:
443 nhs.append({})
444 return {'action': self.action,
445 'nh_set': {
446 'hash_mode': self.hash_mode,
447 'n_nhs': len(self.nhs),
448 'nhs': nhs}}
449
450
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800451class VppGbpContract(VppObject):
452 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200453 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800454 """
455
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800456 def __init__(self, test, src_epg, dst_epg, acl_index,
457 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800458 self._test = test
459 self.acl_index = acl_index
460 self.src_epg = src_epg
461 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800462 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800463 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800464
465 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800466 rules = []
467 for r in self.rules:
468 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800469 self._test.vapi.gbp_contract_add_del(
470 1,
Neale Ranns4ba67722019-02-28 11:11:39 +0000471 self.src_epg.sclass,
472 self.dst_epg.sclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800473 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800474 rules,
475 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800476 self._test.registry.register(self, self._test.logger)
477
478 def remove_vpp_config(self):
479 self._test.vapi.gbp_contract_add_del(
480 0,
Neale Ranns4ba67722019-02-28 11:11:39 +0000481 self.src_epg.sclass,
482 self.dst_epg.sclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800483 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800484 [], [])
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800485
486 def __str__(self):
487 return self.object_id()
488
489 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000490 return "gbp-contract:[%d:%s:%d]" % (self.src_epg.sclass,
491 self.dst_epg.sclass,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800492 self.acl_index)
493
494 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700495 cs = self._test.vapi.gbp_contract_dump()
496 for c in cs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000497 if c.contract.sclass == self.src_epg.sclass \
498 and c.contract.dclass == self.dst_epg.sclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800499 return True
500 return False
501
502
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700503class VppGbpVxlanTunnel(VppInterface):
504 """
505 GBP VXLAN tunnel
506 """
507
Neale Ranns8da9fc62019-03-04 14:08:11 -0800508 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700509 super(VppGbpVxlanTunnel, self).__init__(test)
510 self._test = test
511 self.vni = vni
512 self.bd_rd_id = bd_rd_id
513 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800514 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700515
516 def add_vpp_config(self):
517 r = self._test.vapi.gbp_vxlan_tunnel_add(
518 self.vni,
519 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800520 self.mode,
521 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700522 self.set_sw_if_index(r.sw_if_index)
523 self._test.registry.register(self, self._test.logger)
524
525 def remove_vpp_config(self):
526 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
527
528 def __str__(self):
529 return self.object_id()
530
531 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800532 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700533
534 def query_vpp_config(self):
535 return find_gbp_vxlan(self._test, self.vni)
536
537
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200538class VppGbpAcl(VppObject):
539 """
540 GBP Acl
541 """
542
543 def __init__(self, test):
544 self._test = test
545 self.acl_index = 4294967295
546
547 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800548 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
549 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200550 dport_from=0, dport_to=65535):
551 if proto == -1 or proto == 0:
552 sport_to = 0
553 dport_to = sport_to
554 elif proto == 1 or proto == 58:
555 sport_to = 255
556 dport_to = sport_to
557 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
558 'srcport_or_icmptype_first': sport_from,
559 'srcport_or_icmptype_last': sport_to,
560 'src_ip_prefix_len': s_prefix,
561 'src_ip_addr': s_ip,
562 'dstport_or_icmpcode_first': dport_from,
563 'dstport_or_icmpcode_last': dport_to,
564 'dst_ip_prefix_len': d_prefix,
565 'dst_ip_addr': d_ip})
566 return rule
567
568 def add_vpp_config(self, rules):
569
570 reply = self._test.vapi.acl_add_replace(self.acl_index,
571 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800572 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200573 self.acl_index = reply.acl_index
574 return self.acl_index
575
576 def remove_vpp_config(self):
577 self._test.vapi.acl_del(self.acl_index)
578
579 def __str__(self):
580 return self.object_id()
581
582 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700583 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200584
585 def query_vpp_config(self):
586 cs = self._test.vapi.acl_dump()
587 for c in cs:
588 if c.acl_index == self.acl_index:
589 return True
590 return False
591
592
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800593class TestGBP(VppTestCase):
594 """ GBP Test Case """
595
596 def setUp(self):
597 super(TestGBP, self).setUp()
598
Neale Ranns25b04942018-04-04 09:34:50 -0700599 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700600 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700601
Ole Troan8006c6a2018-12-17 12:02:26 +0100602 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800603
604 for i in self.pg_interfaces:
605 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700606 for i in self.lo_interfaces:
607 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800608
609 def tearDown(self):
610 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700611 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800612
613 super(TestGBP, self).tearDown()
614
Neale Ranns25b04942018-04-04 09:34:50 -0700615 def send_and_expect_bridged(self, src, tx, dst):
616 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800617
Neale Ranns25b04942018-04-04 09:34:50 -0700618 for r in rx:
619 self.assertEqual(r[Ether].src, tx[0][Ether].src)
620 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
621 self.assertEqual(r[IP].src, tx[0][IP].src)
622 self.assertEqual(r[IP].dst, tx[0][IP].dst)
623 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800624
Neale Ranns25b04942018-04-04 09:34:50 -0700625 def send_and_expect_bridged6(self, src, tx, dst):
626 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800627
Neale Ranns25b04942018-04-04 09:34:50 -0700628 for r in rx:
629 self.assertEqual(r[Ether].src, tx[0][Ether].src)
630 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
631 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
632 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
633 return rx
634
635 def send_and_expect_routed(self, src, tx, dst, src_mac):
636 rx = self.send_and_expect(src, tx, dst)
637
638 for r in rx:
639 self.assertEqual(r[Ether].src, src_mac)
640 self.assertEqual(r[Ether].dst, dst.remote_mac)
641 self.assertEqual(r[IP].src, tx[0][IP].src)
642 self.assertEqual(r[IP].dst, tx[0][IP].dst)
643 return rx
644
645 def send_and_expect_natted(self, src, tx, dst, src_ip):
646 rx = self.send_and_expect(src, tx, dst)
647
648 for r in rx:
649 self.assertEqual(r[Ether].src, tx[0][Ether].src)
650 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
651 self.assertEqual(r[IP].src, src_ip)
652 self.assertEqual(r[IP].dst, tx[0][IP].dst)
653 return rx
654
Neale Ranns4a6d0232018-04-24 07:45:33 -0700655 def send_and_expect_natted6(self, src, tx, dst, src_ip):
656 rx = self.send_and_expect(src, tx, dst)
657
658 for r in rx:
659 self.assertEqual(r[Ether].src, tx[0][Ether].src)
660 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
661 self.assertEqual(r[IPv6].src, src_ip)
662 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
663 return rx
664
Neale Ranns25b04942018-04-04 09:34:50 -0700665 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
666 rx = self.send_and_expect(src, tx, dst)
667
668 for r in rx:
669 self.assertEqual(r[Ether].src, tx[0][Ether].src)
670 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
671 self.assertEqual(r[IP].dst, dst_ip)
672 self.assertEqual(r[IP].src, tx[0][IP].src)
673 return rx
674
Neale Ranns4a6d0232018-04-24 07:45:33 -0700675 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
676 rx = self.send_and_expect(src, tx, dst)
677
678 for r in rx:
679 self.assertEqual(r[Ether].src, tx[0][Ether].src)
680 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
681 self.assertEqual(r[IPv6].dst, dst_ip)
682 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
683 return rx
684
Neale Ranns25b04942018-04-04 09:34:50 -0700685 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
686 rx = self.send_and_expect(src, tx, dst)
687
688 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100689 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700690 self.assertEqual(r[Ether].dst, dst.remote_mac)
691 self.assertEqual(r[IP].dst, dst_ip)
692 self.assertEqual(r[IP].src, src_ip)
693 return rx
694
Neale Ranns4a6d0232018-04-24 07:45:33 -0700695 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
696 rx = self.send_and_expect(src, tx, dst)
697
698 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100699 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700700 self.assertEqual(r[Ether].dst, dst.remote_mac)
701 self.assertEqual(r[IPv6].dst, dst_ip)
702 self.assertEqual(r[IPv6].src, src_ip)
703 return rx
704
Neale Ranns25b04942018-04-04 09:34:50 -0700705 def test_gbp(self):
706 """ Group Based Policy """
707
Neale Rannsb6a47952018-11-21 05:44:35 -0800708 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
709
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800710 #
Neale Ranns25b04942018-04-04 09:34:50 -0700711 # Bridge Domains
712 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700713 bd1 = VppBridgeDomain(self, 1)
714 bd2 = VppBridgeDomain(self, 2)
715 bd20 = VppBridgeDomain(self, 20)
716
717 bd1.add_vpp_config()
718 bd2.add_vpp_config()
719 bd20.add_vpp_config()
720
721 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
722 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
723 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
724
725 gbd1.add_vpp_config()
726 gbd2.add_vpp_config()
727 gbd20.add_vpp_config()
728
729 #
730 # Route Domains
731 #
732 gt4 = VppIpTable(self, 0)
733 gt4.add_vpp_config()
734 gt6 = VppIpTable(self, 0, is_ip6=True)
735 gt6.add_vpp_config()
736 nt4 = VppIpTable(self, 20)
737 nt4.add_vpp_config()
738 nt6 = VppIpTable(self, 20, is_ip6=True)
739 nt6.add_vpp_config()
740
741 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
742 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
743
744 rd0.add_vpp_config()
745 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700746
747 #
748 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700749 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
750 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000751 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
752 self.pg4, self.loop0,
753 "10.0.0.128", "2001:10::128"),
754 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
755 self.pg5, self.loop0,
756 "10.0.1.128", "2001:10:1::128"),
757 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
758 self.pg6, self.loop1,
759 "10.0.2.128", "2001:10:2::128"),
760 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
761 self.pg7, self.loop2,
762 "11.0.0.128", "3001::128"),
763 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
764 self.pg8, self.loop2,
765 "11.0.0.129", "3001::129")]
766 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
767 VppGbpRecirc(self, epgs[1], self.loop4),
768 VppGbpRecirc(self, epgs[2], self.loop5),
769 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
770 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700771
772 epg_nat = epgs[3]
773 recirc_nat = recircs[3]
774
775 #
776 # 4 end-points, 2 in the same subnet, 3 in the same BD
777 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700778 eps = [VppGbpEndpoint(self, self.pg0,
779 epgs[0], recircs[0],
780 "10.0.0.1", "11.0.0.1",
781 "2001:10::1", "3001::1"),
782 VppGbpEndpoint(self, self.pg1,
783 epgs[0], recircs[0],
784 "10.0.0.2", "11.0.0.2",
785 "2001:10::2", "3001::2"),
786 VppGbpEndpoint(self, self.pg2,
787 epgs[1], recircs[1],
788 "10.0.1.1", "11.0.0.3",
789 "2001:10:1::1", "3001::3"),
790 VppGbpEndpoint(self, self.pg3,
791 epgs[2], recircs[2],
792 "10.0.2.1", "11.0.0.4",
793 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700794
795 #
796 # Config related to each of the EPGs
797 #
798 for epg in epgs:
799 # IP config on the BVI interfaces
800 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700801 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
802 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
803 self.vapi.sw_interface_set_mac_address(
804 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100805 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700806
807 # The BVIs are NAT inside interfaces
808 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
809 is_inside=1,
810 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700811 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
812 is_inside=1,
813 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700814
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700815 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
816 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
817 if_ip4.add_vpp_config()
818 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700819
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700820 # EPG uplink interfaces in the RD
821 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
822 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700823
824 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700825 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100826 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700827 epg.bvi_ip4)
828 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100829 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700830 epg.bvi_ip6)
831 epg.bd_arp_ip4.add_vpp_config()
832 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700833
834 # EPG in VPP
835 epg.add_vpp_config()
836
837 for recirc in recircs:
838 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700839 VppIpInterfaceBind(self, recirc.recirc,
840 recirc.epg.rd.t4).add_vpp_config()
841 VppIpInterfaceBind(self, recirc.recirc,
842 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700843
Neale Ranns4a6d0232018-04-24 07:45:33 -0700844 self.vapi.nat44_interface_add_del_feature(
845 recirc.recirc.sw_if_index,
846 is_inside=0,
847 is_add=1)
848 self.vapi.nat66_add_del_interface(
849 recirc.recirc.sw_if_index,
850 is_inside=0,
851 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700852
853 recirc.add_vpp_config()
854
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700855 for recirc in recircs:
856 self.assertTrue(find_bridge_domain_port(self,
857 recirc.epg.bd.bd.bd_id,
858 recirc.recirc.sw_if_index))
859
Neale Ranns25b04942018-04-04 09:34:50 -0700860 for ep in eps:
861 self.pg_enable_capture(self.pg_interfaces)
862 self.pg_start()
863 #
864 # routes to the endpoints. We need these since there are no
865 # adj-fibs due to the fact the the BVI address has /32 and
866 # the subnet is not attached.
867 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700868 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700869 # Add static mappings for each EP from the 10/8 to 11/8 network
870 if ip.af == AF_INET:
871 self.vapi.nat44_add_del_static_mapping(ip.bytes,
872 fip.bytes,
873 vrf_id=0,
874 addr_only=1)
875 else:
876 self.vapi.nat66_add_del_static_mapping(ip.bytes,
877 fip.bytes,
878 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700879
Neale Ranns25b04942018-04-04 09:34:50 -0700880 # VPP EP create ...
881 ep.add_vpp_config()
882
Neale Rannsc0a93142018-09-05 15:42:26 -0700883 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700884
Neale Rannsc0a93142018-09-05 15:42:26 -0700885 # ... results in a Gratuitous ARP/ND on the EPG's uplink
886 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
887
888 for ii, ip in enumerate(ep.ips):
889 p = rx[ii]
890
891 if ip.is_ip6:
892 self.assertTrue(p.haslayer(ICMPv6ND_NA))
893 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
894 else:
895 self.assertTrue(p.haslayer(ARP))
896 self.assertEqual(p[ARP].psrc, ip.address)
897 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700898
899 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700900 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700901 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
902 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700903
Neale Rannsc0a93142018-09-05 15:42:26 -0700904 # floating IPs route via EPG recirc
905 r = VppIpRoute(self, fip.address, fip.length,
906 [VppRoutePath(fip.address,
907 ep.recirc.recirc.sw_if_index,
908 is_dvr=1,
909 proto=fip.dpo_proto)],
910 table_id=20,
911 is_ip6=fip.is_ip6)
912 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700913
914 # L2 FIB entries in the NAT EPG BD to bridge the packets from
915 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700916 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
917 ep.recirc.recirc, bvi_mac=0)
918 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700919
920 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700921 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700922 #
923 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
924 src=self.pg0.remote_mac) /
925 ARP(op="who-has",
926 hwdst="ff:ff:ff:ff:ff:ff",
927 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700928 pdst="10.0.0.88",
929 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700930
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700931 self.vapi.cli("clear trace")
932 self.pg0.add_stream(pkt_arp)
933
934 self.pg_enable_capture(self.pg_interfaces)
935 self.pg_start()
936
937 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700938
939 #
940 # ARP/ND packets get a response
941 #
942 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
943 src=self.pg0.remote_mac) /
944 ARP(op="who-has",
945 hwdst="ff:ff:ff:ff:ff:ff",
946 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700947 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700948 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700949
950 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
951
Neale Rannsc0a93142018-09-05 15:42:26 -0700952 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700953 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700954 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
955 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700956 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700957 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700958 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
959 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
960
961 #
962 # broadcast packets are flooded
963 #
964 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
965 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700966 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700967 UDP(sport=1234, dport=1234) /
968 Raw('\xa5' * 100))
969
970 self.vapi.cli("clear trace")
971 self.pg0.add_stream(pkt_bcast)
972
973 self.pg_enable_capture(self.pg_interfaces)
974 self.pg_start()
975
976 rxd = eps[1].itf.get_capture(1)
977 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
978 rxd = epgs[0].uplink.get_capture(1)
979 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
980
981 #
982 # packets to non-local L3 destinations dropped
983 #
984 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100985 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700986 IP(src=eps[0].ip4.address,
987 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700988 UDP(sport=1234, dport=1234) /
989 Raw('\xa5' * 100))
990 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100991 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700992 IP(src=eps[0].ip4.address,
993 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700994 UDP(sport=1234, dport=1234) /
995 Raw('\xa5' * 100))
996
997 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
998
999 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001000 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001001 IPv6(src=eps[0].ip6.address,
1002 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001003 UDP(sport=1234, dport=1234) /
1004 Raw('\xa5' * 100))
1005 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
1006
1007 #
1008 # Add the subnet routes
1009 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001010 s41 = VppGbpSubnet(
1011 self, rd0, "10.0.0.0", 24,
1012 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1013 s42 = VppGbpSubnet(
1014 self, rd0, "10.0.1.0", 24,
1015 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1016 s43 = VppGbpSubnet(
1017 self, rd0, "10.0.2.0", 24,
1018 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1019 s61 = VppGbpSubnet(
1020 self, rd0, "2001:10::1", 64,
1021 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1022 s62 = VppGbpSubnet(
1023 self, rd0, "2001:10:1::1", 64,
1024 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1025 s63 = VppGbpSubnet(
1026 self, rd0, "2001:10:2::1", 64,
1027 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001028 s41.add_vpp_config()
1029 s42.add_vpp_config()
1030 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001031 s61.add_vpp_config()
1032 s62.add_vpp_config()
1033 s63.add_vpp_config()
1034
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001035 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001036 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001037 eps[0].epg.uplink)
1038 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001039 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001040 eps[0].epg.uplink)
1041 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001042 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001043 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001044
1045 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1046 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1047 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1048 self.logger.info(self.vapi.cli("sh gbp recirc"))
1049 self.logger.info(self.vapi.cli("sh int"))
1050 self.logger.info(self.vapi.cli("sh int addr"))
1051 self.logger.info(self.vapi.cli("sh int feat loop6"))
1052 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1053 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001054 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001055
1056 #
1057 # Packet destined to unknown unicast is sent on the epg uplink ...
1058 #
1059 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1060 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001061 IP(src=eps[0].ip4.address,
1062 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001063 UDP(sport=1234, dport=1234) /
1064 Raw('\xa5' * 100))
1065
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001066 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001067 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001068 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001069 # ... and nowhere else
1070 self.pg1.get_capture(0, timeout=0.1)
1071 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1072
1073 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1074 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001075 IP(src=eps[0].ip4.address,
1076 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001077 UDP(sport=1234, dport=1234) /
1078 Raw('\xa5' * 100))
1079
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001080 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001081 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001082 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001083
1084 #
1085 # Packets from the uplink are forwarded in the absence of a contract
1086 #
1087 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1088 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001089 IP(src=eps[0].ip4.address,
1090 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001091 UDP(sport=1234, dport=1234) /
1092 Raw('\xa5' * 100))
1093
1094 self.send_and_expect_bridged(self.pg4,
1095 pkt_intra_epg_220_from_uplink * 65,
1096 self.pg0)
1097
1098 #
1099 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001100 # can communicate
1101 #
1102 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001103 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001104 IP(src=eps[0].ip4.address,
1105 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001106 UDP(sport=1234, dport=1234) /
1107 Raw('\xa5' * 100))
1108
Neale Ranns25b04942018-04-04 09:34:50 -07001109 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001110
1111 #
1112 # in the abscense of policy, endpoints in the different EPG
1113 # cannot communicate
1114 #
1115 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001116 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001117 IP(src=eps[0].ip4.address,
1118 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001119 UDP(sport=1234, dport=1234) /
1120 Raw('\xa5' * 100))
1121 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001122 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001123 IP(src=eps[2].ip4.address,
1124 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001125 UDP(sport=1234, dport=1234) /
1126 Raw('\xa5' * 100))
1127 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001128 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001129 IP(src=eps[0].ip4.address,
1130 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001131 UDP(sport=1234, dport=1234) /
1132 Raw('\xa5' * 100))
1133
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001134 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001135 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001136 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001137 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001138
1139 #
1140 # A uni-directional contract from EPG 220 -> 221
1141 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001142 acl = VppGbpAcl(self)
1143 rule = acl.create_rule(permit_deny=1, proto=17)
1144 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1145 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001146 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001147 self, epgs[0], epgs[1], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001148 [VppGbpContractRule(
1149 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1150 []),
1151 VppGbpContractRule(
1152 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001153 [])],
1154 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001155 c1.add_vpp_config()
1156
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001157 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001158 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001159 eps[2].itf)
1160 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001161 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001162
1163 #
1164 # contract for the return direction
1165 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001166 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001167 self, epgs[1], epgs[0], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001168 [VppGbpContractRule(
1169 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1170 []),
1171 VppGbpContractRule(
1172 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001173 [])],
1174 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001175 c2.add_vpp_config()
1176
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001177 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001178 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001179 eps[2].itf)
1180 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001181 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001182 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001183
1184 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001185 # the contract does not allow non-IP
1186 #
1187 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1188 dst=self.pg2.remote_mac) /
1189 ARP())
1190 self.send_and_assert_no_replies(eps[0].itf,
1191 pkt_non_ip_inter_epg_220_to_221 * 17)
1192
1193 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001194 # check that inter group is still disabled for the groups
1195 # not in the contract.
1196 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001197 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001198 pkt_inter_epg_220_to_222 * 65)
1199
Neale Ranns25b04942018-04-04 09:34:50 -07001200 #
1201 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1202 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001203 c3 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001204 self, epgs[0], epgs[2], acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001205 [VppGbpContractRule(
1206 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1207 []),
1208 VppGbpContractRule(
1209 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001210 [])],
1211 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001212 c3.add_vpp_config()
1213
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001214 self.logger.info(self.vapi.cli("sh gbp contract"))
1215
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001216 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001217 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001218 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001219 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001220
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001221 #
1222 # remove both contracts, traffic stops in both directions
1223 #
1224 c2.remove_vpp_config()
1225 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001226 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001227 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001228
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001229 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001230 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001231 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001232 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001233 self.send_and_expect_bridged(eps[0].itf,
1234 pkt_intra_epg * 65,
1235 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001236
1237 #
Neale Ranns25b04942018-04-04 09:34:50 -07001238 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001239 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001240
Neale Ranns25b04942018-04-04 09:34:50 -07001241 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001242 se1 = VppGbpSubnet(
1243 self, rd0, "0.0.0.0", 0,
1244 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1245 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001246 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001247 se2 = VppGbpSubnet(
1248 self, rd0, "11.0.0.0", 8,
1249 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1250 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001251 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001252 se16 = VppGbpSubnet(
1253 self, rd0, "::", 0,
1254 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1255 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001256 epg=epg_nat)
Neale Ranns25b04942018-04-04 09:34:50 -07001257 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001258 se3 = VppGbpSubnet(
1259 self, rd20, "0.0.0.0", 0,
1260 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1261 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001262 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001263 se36 = VppGbpSubnet(
1264 self, rd20, "::", 0,
1265 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1266 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001267 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001268 se4 = VppGbpSubnet(
1269 self, rd20, "11.0.0.0", 8,
1270 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1271 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +00001272 epg=epg_nat)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001273 se1.add_vpp_config()
1274 se2.add_vpp_config()
1275 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001276 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001277 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001278 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001279
Neale Ranns25b04942018-04-04 09:34:50 -07001280 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1281 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001282 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1283 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001284 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001285
Neale Ranns4a6d0232018-04-24 07:45:33 -07001286 #
1287 # From an EP to an outside addess: IN2OUT
1288 #
Neale Ranns25b04942018-04-04 09:34:50 -07001289 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001290 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001291 IP(src=eps[0].ip4.address,
1292 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001293 UDP(sport=1234, dport=1234) /
1294 Raw('\xa5' * 100))
1295
1296 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001297 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001298 pkt_inter_epg_220_to_global * 65)
1299
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001300 acl2 = VppGbpAcl(self)
1301 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1302 sport_to=1234, dport_from=1234, dport_to=1234)
1303 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1304 sport_from=1234, sport_to=1234,
1305 dport_from=1234, dport_to=1234)
1306
1307 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001308 c4 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001309 self, epgs[0], epgs[3], acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001310 [VppGbpContractRule(
1311 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1312 []),
1313 VppGbpContractRule(
1314 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001315 [])],
1316 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001317 c4.add_vpp_config()
1318
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001319 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001320 pkt_inter_epg_220_to_global * 65,
1321 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001322 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001323
Neale Ranns4a6d0232018-04-24 07:45:33 -07001324 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001325 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001326 IPv6(src=eps[0].ip6.address,
1327 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001328 UDP(sport=1234, dport=1234) /
1329 Raw('\xa5' * 100))
1330
1331 self.send_and_expect_natted6(self.pg0,
1332 pkt_inter_epg_220_to_global * 65,
1333 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001334 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001335
1336 #
1337 # From a global address to an EP: OUT2IN
1338 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001339 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001340 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001341 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001342 src="1.1.1.1") /
1343 UDP(sport=1234, dport=1234) /
1344 Raw('\xa5' * 100))
1345
1346 self.send_and_assert_no_replies(self.pg7,
1347 pkt_inter_epg_220_from_global * 65)
1348
Neale Ranns13a08cc2018-11-07 09:25:54 -08001349 c5 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001350 self, epgs[3], epgs[0], acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001351 [VppGbpContractRule(
1352 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1353 []),
1354 VppGbpContractRule(
1355 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001356 [])],
1357 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001358 c5.add_vpp_config()
1359
1360 self.send_and_expect_unnatted(self.pg7,
1361 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001362 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001363 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001364
Ole Troan8006c6a2018-12-17 12:02:26 +01001365 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001366 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001367 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001368 src="6001::1") /
1369 UDP(sport=1234, dport=1234) /
1370 Raw('\xa5' * 100))
1371
1372 self.send_and_expect_unnatted6(self.pg7,
1373 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001374 eps[0].itf,
1375 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001376
1377 #
1378 # From a local VM to another local VM using resp. public addresses:
1379 # IN2OUT2IN
1380 #
Neale Ranns25b04942018-04-04 09:34:50 -07001381 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001382 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001383 IP(src=eps[0].ip4.address,
1384 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001385 UDP(sport=1234, dport=1234) /
1386 Raw('\xa5' * 100))
1387
Neale Ranns4a6d0232018-04-24 07:45:33 -07001388 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001389 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001390 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001391 eps[0].fip4.address,
1392 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001393
Neale Rannsc0a93142018-09-05 15:42:26 -07001394 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001395 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001396 IPv6(src=eps[0].ip6.address,
1397 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001398 UDP(sport=1234, dport=1234) /
1399 Raw('\xa5' * 100))
1400
Neale Rannsc0a93142018-09-05 15:42:26 -07001401 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001402 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001403 eps[1].itf,
1404 eps[0].fip6.address,
1405 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001406
1407 #
Neale Ranns25b04942018-04-04 09:34:50 -07001408 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001409 #
Neale Ranns25b04942018-04-04 09:34:50 -07001410 for ep in eps:
1411 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001412 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1413 ep.fip4.bytes,
1414 vrf_id=0,
1415 addr_only=1,
1416 is_add=0)
1417 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1418 ep.fip6.bytes,
1419 vrf_id=0,
1420 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001421
Neale Ranns25b04942018-04-04 09:34:50 -07001422 for epg in epgs:
1423 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001424 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001425 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1426 is_inside=1,
1427 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001428 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1429 is_inside=1,
1430 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001431
Neale Ranns25b04942018-04-04 09:34:50 -07001432 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001433 self.vapi.nat44_interface_add_del_feature(
1434 recirc.recirc.sw_if_index,
1435 is_inside=0,
1436 is_add=0)
1437 self.vapi.nat66_add_del_interface(
1438 recirc.recirc.sw_if_index,
1439 is_inside=0,
1440 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001441
Neale Ranns774356a2018-11-29 12:02:16 +00001442 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1443 n_tries=100, s_time=1):
1444 while (n_tries):
1445 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1446 return True
1447 n_tries = n_tries - 1
1448 self.sleep(s_time)
1449 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1450 return False
1451
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001452 def test_gbp_learn_l2(self):
1453 """ GBP L2 Endpoint Learning """
1454
Neale Rannsb6a47952018-11-21 05:44:35 -08001455 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001456 learnt = [{'mac': '00:00:11:11:11:01',
1457 'ip': '10.0.0.1',
1458 'ip6': '2001:10::2'},
1459 {'mac': '00:00:11:11:11:02',
1460 'ip': '10.0.0.2',
1461 'ip6': '2001:10::3'}]
1462
1463 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001464 # IP tables
1465 #
1466 gt4 = VppIpTable(self, 1)
1467 gt4.add_vpp_config()
1468 gt6 = VppIpTable(self, 1, is_ip6=True)
1469 gt6.add_vpp_config()
1470
1471 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1472 rd1.add_vpp_config()
1473
1474 #
1475 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1476 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1477 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1478 #
1479 self.pg2.config_ip4()
1480 self.pg2.resolve_arp()
1481 self.pg2.generate_remote_hosts(4)
1482 self.pg2.configure_ipv4_neighbors()
1483 self.pg3.config_ip4()
1484 self.pg3.resolve_arp()
1485 self.pg4.config_ip4()
1486 self.pg4.resolve_arp()
1487
1488 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001489 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1490 #
1491 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1492 "239.1.1.1", 88,
1493 mcast_itf=self.pg4)
1494 tun_bm.add_vpp_config()
1495
1496 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001497 # a GBP bridge domain with a BVI and a UU-flood interface
1498 #
1499 bd1 = VppBridgeDomain(self, 1)
1500 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001501 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001502 gbd1.add_vpp_config()
1503
1504 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1505 self.logger.info(self.vapi.cli("sh gbp bridge"))
1506
1507 # ... and has a /32 applied
1508 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1509 ip_addr.add_vpp_config()
1510
1511 #
1512 # The Endpoint-group in which we are learning endpoints
1513 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001514 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001515 None, self.loop0,
1516 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001517 "2001:10::128",
1518 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001519 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001520 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001521 None, self.loop1,
1522 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001523 "2001:11::128",
1524 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001525 epg_330.add_vpp_config()
1526
1527 #
1528 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1529 # leanring enabled
1530 #
1531 vx_tun_l2_1 = VppGbpVxlanTunnel(
1532 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001533 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1534 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001535 vx_tun_l2_1.add_vpp_config()
1536
1537 #
1538 # A static endpoint that the learnt endpoints are trying to
1539 # talk to
1540 #
1541 ep = VppGbpEndpoint(self, self.pg0,
1542 epg_220, None,
1543 "10.0.0.127", "11.0.0.127",
1544 "2001:10::1", "3001::1")
1545 ep.add_vpp_config()
1546
1547 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1548
1549 # a packet with an sclass from an unknwon EPG
1550 p = (Ether(src=self.pg2.remote_mac,
1551 dst=self.pg2.local_mac) /
1552 IP(src=self.pg2.remote_hosts[0].ip4,
1553 dst=self.pg2.local_ip4) /
1554 UDP(sport=1234, dport=48879) /
1555 VXLAN(vni=99, gpid=88, flags=0x88) /
1556 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1557 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1558 UDP(sport=1234, dport=1234) /
1559 Raw('\xa5' * 100))
1560
1561 self.send_and_assert_no_replies(self.pg2, p)
1562
1563 #
1564 # we should not have learnt a new tunnel endpoint, since
1565 # the EPG was not learnt.
1566 #
1567 self.assertEqual(INDEX_INVALID,
1568 find_vxlan_gbp_tunnel(self,
1569 self.pg2.local_ip4,
1570 self.pg2.remote_hosts[0].ip4,
1571 99))
1572
1573 # epg is not learnt, becasue the EPG is unknwon
1574 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1575
Neale Ranns8da9fc62019-03-04 14:08:11 -08001576 #
1577 # Learn new EPs from IP packets
1578 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001579 for ii, l in enumerate(learnt):
1580 # a packet with an sclass from a knwon EPG
1581 # arriving on an unknown TEP
1582 p = (Ether(src=self.pg2.remote_mac,
1583 dst=self.pg2.local_mac) /
1584 IP(src=self.pg2.remote_hosts[1].ip4,
1585 dst=self.pg2.local_ip4) /
1586 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001587 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001588 Ether(src=l['mac'], dst=ep.mac) /
1589 IP(src=l['ip'], dst=ep.ip4.address) /
1590 UDP(sport=1234, dport=1234) /
1591 Raw('\xa5' * 100))
1592
1593 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1594
1595 # the new TEP
1596 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1597 self,
1598 self.pg2.local_ip4,
1599 self.pg2.remote_hosts[1].ip4,
1600 99)
1601 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1602
1603 #
1604 # the EP is learnt via the learnt TEP
1605 # both from its MAC and its IP
1606 #
1607 self.assertTrue(find_gbp_endpoint(self,
1608 vx_tun_l2_1.sw_if_index,
1609 mac=l['mac']))
1610 self.assertTrue(find_gbp_endpoint(self,
1611 vx_tun_l2_1.sw_if_index,
1612 ip=l['ip']))
1613
1614 self.logger.info(self.vapi.cli("show gbp endpoint"))
1615 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001616 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001617
1618 #
1619 # If we sleep for the threshold time, the learnt endpoints should
1620 # age out
1621 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001622 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001623 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1624 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001625
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001626 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001627 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1628 #
1629 for ii, l in enumerate(learnt):
1630 # a packet with an sclass from a knwon EPG
1631 # arriving on an unknown TEP
1632 p = (Ether(src=self.pg2.remote_mac,
1633 dst=self.pg2.local_mac) /
1634 IP(src=self.pg2.remote_hosts[1].ip4,
1635 dst="239.1.1.1") /
1636 UDP(sport=1234, dport=48879) /
1637 VXLAN(vni=88, gpid=112, flags=0x88) /
1638 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1639 ARP(op="who-has",
1640 psrc=l['ip'], pdst=l['ip'],
1641 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1642
1643 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1644
1645 # the new TEP
1646 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1647 self,
1648 self.pg2.local_ip4,
1649 self.pg2.remote_hosts[1].ip4,
1650 99)
1651 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1652
1653 #
1654 # the EP is learnt via the learnt TEP
1655 # both from its MAC and its IP
1656 #
1657 self.assertTrue(find_gbp_endpoint(self,
1658 vx_tun_l2_1.sw_if_index,
1659 mac=l['mac']))
1660 self.assertTrue(find_gbp_endpoint(self,
1661 vx_tun_l2_1.sw_if_index,
1662 ip=l['ip']))
1663
1664 #
1665 # wait for the learnt endpoints to age out
1666 #
1667 for l in learnt:
1668 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1669 mac=l['mac'])
1670
1671 #
1672 # Learn new EPs from L2 packets
1673 #
1674 for ii, l in enumerate(learnt):
1675 # a packet with an sclass from a knwon EPG
1676 # arriving on an unknown TEP
1677 p = (Ether(src=self.pg2.remote_mac,
1678 dst=self.pg2.local_mac) /
1679 IP(src=self.pg2.remote_hosts[1].ip4,
1680 dst=self.pg2.local_ip4) /
1681 UDP(sport=1234, dport=48879) /
1682 VXLAN(vni=99, gpid=112, flags=0x88) /
1683 Ether(src=l['mac'], dst=ep.mac) /
1684 Raw('\xa5' * 100))
1685
1686 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1687
1688 # the new TEP
1689 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1690 self,
1691 self.pg2.local_ip4,
1692 self.pg2.remote_hosts[1].ip4,
1693 99)
1694 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1695
1696 #
1697 # the EP is learnt via the learnt TEP
1698 # both from its MAC and its IP
1699 #
1700 self.assertTrue(find_gbp_endpoint(self,
1701 vx_tun_l2_1.sw_if_index,
1702 mac=l['mac']))
1703
1704 self.logger.info(self.vapi.cli("show gbp endpoint"))
1705 self.logger.info(self.vapi.cli("show gbp vxlan"))
1706 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1707
1708 #
1709 # wait for the learnt endpoints to age out
1710 #
1711 for l in learnt:
1712 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1713 mac=l['mac'])
1714
1715 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001716 # repeat. the do not learn bit is set so the EPs are not learnt
1717 #
1718 for l in learnt:
1719 # a packet with an sclass from a knwon EPG
1720 p = (Ether(src=self.pg2.remote_mac,
1721 dst=self.pg2.local_mac) /
1722 IP(src=self.pg2.remote_hosts[1].ip4,
1723 dst=self.pg2.local_ip4) /
1724 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001725 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001726 Ether(src=l['mac'], dst=ep.mac) /
1727 IP(src=l['ip'], dst=ep.ip4.address) /
1728 UDP(sport=1234, dport=1234) /
1729 Raw('\xa5' * 100))
1730
1731 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1732
1733 for l in learnt:
1734 self.assertFalse(find_gbp_endpoint(self,
1735 vx_tun_l2_1.sw_if_index,
1736 mac=l['mac']))
1737
1738 #
1739 # repeat
1740 #
1741 for l in learnt:
1742 # a packet with an sclass from a knwon EPG
1743 p = (Ether(src=self.pg2.remote_mac,
1744 dst=self.pg2.local_mac) /
1745 IP(src=self.pg2.remote_hosts[1].ip4,
1746 dst=self.pg2.local_ip4) /
1747 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001748 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001749 Ether(src=l['mac'], dst=ep.mac) /
1750 IP(src=l['ip'], dst=ep.ip4.address) /
1751 UDP(sport=1234, dport=1234) /
1752 Raw('\xa5' * 100))
1753
1754 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1755
1756 self.assertTrue(find_gbp_endpoint(self,
1757 vx_tun_l2_1.sw_if_index,
1758 mac=l['mac']))
1759
1760 #
1761 # Static EP replies to dynamics
1762 #
1763 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1764 for l in learnt:
1765 p = (Ether(src=ep.mac, dst=l['mac']) /
1766 IP(dst=l['ip'], src=ep.ip4.address) /
1767 UDP(sport=1234, dport=1234) /
1768 Raw('\xa5' * 100))
1769
1770 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1771
1772 for rx in rxs:
1773 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1774 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1775 self.assertEqual(rx[UDP].dport, 48879)
1776 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001777 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001778 self.assertEqual(rx[VXLAN].vni, 99)
1779 self.assertTrue(rx[VXLAN].flags.G)
1780 self.assertTrue(rx[VXLAN].flags.Instance)
1781 self.assertTrue(rx[VXLAN].gpflags.A)
1782 self.assertFalse(rx[VXLAN].gpflags.D)
1783
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001784 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001785 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1786 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001787
1788 #
1789 # repeat in the other EPG
1790 # there's no contract between 220 and 330, but the A-bit is set
1791 # so the packet is cleared for delivery
1792 #
1793 for l in learnt:
1794 # a packet with an sclass from a knwon EPG
1795 p = (Ether(src=self.pg2.remote_mac,
1796 dst=self.pg2.local_mac) /
1797 IP(src=self.pg2.remote_hosts[1].ip4,
1798 dst=self.pg2.local_ip4) /
1799 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001800 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001801 Ether(src=l['mac'], dst=ep.mac) /
1802 IP(src=l['ip'], dst=ep.ip4.address) /
1803 UDP(sport=1234, dport=1234) /
1804 Raw('\xa5' * 100))
1805
1806 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1807
1808 self.assertTrue(find_gbp_endpoint(self,
1809 vx_tun_l2_1.sw_if_index,
1810 mac=l['mac']))
1811
1812 #
1813 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001814 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001815 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001816 p = (Ether(src=ep.mac, dst=l['mac']) /
1817 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1818 UDP(sport=1234, dport=1234) /
1819 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001820
Neale Ranns13a08cc2018-11-07 09:25:54 -08001821 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001822
1823 #
1824 # refresh the entries after the check for no replies above
1825 #
1826 for l in learnt:
1827 # a packet with an sclass from a knwon EPG
1828 p = (Ether(src=self.pg2.remote_mac,
1829 dst=self.pg2.local_mac) /
1830 IP(src=self.pg2.remote_hosts[1].ip4,
1831 dst=self.pg2.local_ip4) /
1832 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001833 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001834 Ether(src=l['mac'], dst=ep.mac) /
1835 IP(src=l['ip'], dst=ep.ip4.address) /
1836 UDP(sport=1234, dport=1234) /
1837 Raw('\xa5' * 100))
1838
1839 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1840
1841 self.assertTrue(find_gbp_endpoint(self,
1842 vx_tun_l2_1.sw_if_index,
1843 mac=l['mac']))
1844
1845 #
1846 # Add the contract so they can talk
1847 #
1848 acl = VppGbpAcl(self)
1849 rule = acl.create_rule(permit_deny=1, proto=17)
1850 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1851 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001852 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00001853 self, epg_220, epg_330, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001854 [VppGbpContractRule(
1855 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1856 []),
1857 VppGbpContractRule(
1858 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001859 [])],
1860 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001861 c1.add_vpp_config()
1862
1863 for l in learnt:
1864 p = (Ether(src=ep.mac, dst=l['mac']) /
1865 IP(dst=l['ip'], src=ep.ip4.address) /
1866 UDP(sport=1234, dport=1234) /
1867 Raw('\xa5' * 100))
1868
1869 self.send_and_expect(self.pg0, [p], self.pg2)
1870
1871 #
1872 # send UU packets from the local EP
1873 #
1874 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1875 self.logger.info(self.vapi.cli("sh gbp bridge"))
1876 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1877 IP(dst="10.0.0.133", src=ep.ip4.address) /
1878 UDP(sport=1234, dport=1234) /
1879 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001880 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001881
1882 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1883
1884 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1885 IP(dst="10.0.0.133", src=ep.ip4.address) /
1886 UDP(sport=1234, dport=1234) /
1887 Raw('\xa5' * 100))
1888 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1889
Neale Ranns879d11c2019-01-21 23:34:18 -08001890 for rx in rxs:
1891 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1892 self.assertEqual(rx[IP].dst, "239.1.1.1")
1893 self.assertEqual(rx[UDP].dport, 48879)
1894 # the UDP source port is a random value for hashing
1895 self.assertEqual(rx[VXLAN].gpid, 112)
1896 self.assertEqual(rx[VXLAN].vni, 88)
1897 self.assertTrue(rx[VXLAN].flags.G)
1898 self.assertTrue(rx[VXLAN].flags.Instance)
1899 self.assertFalse(rx[VXLAN].gpflags.A)
1900 self.assertFalse(rx[VXLAN].gpflags.D)
1901
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001902 #
1903 # Check v6 Endpoints
1904 #
1905 for l in learnt:
1906 # a packet with an sclass from a knwon EPG
1907 p = (Ether(src=self.pg2.remote_mac,
1908 dst=self.pg2.local_mac) /
1909 IP(src=self.pg2.remote_hosts[1].ip4,
1910 dst=self.pg2.local_ip4) /
1911 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001912 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001913 Ether(src=l['mac'], dst=ep.mac) /
1914 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1915 UDP(sport=1234, dport=1234) /
1916 Raw('\xa5' * 100))
1917
1918 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1919
1920 self.assertTrue(find_gbp_endpoint(self,
1921 vx_tun_l2_1.sw_if_index,
1922 mac=l['mac']))
1923
1924 #
1925 # L3 Endpoint Learning
1926 # - configured on the bridge's BVI
1927 #
1928
1929 #
1930 # clean up
1931 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001932 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001933 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1934 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001935
1936 self.pg2.unconfig_ip4()
1937 self.pg3.unconfig_ip4()
1938 self.pg4.unconfig_ip4()
1939
1940 self.logger.info(self.vapi.cli("sh int"))
1941 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1942
Neale Rannsc29c0af2018-11-07 04:21:12 -08001943 def test_gbp_learn_vlan_l2(self):
1944 """ GBP L2 Endpoint w/ VLANs"""
1945
Neale Rannsb6a47952018-11-21 05:44:35 -08001946 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001947 learnt = [{'mac': '00:00:11:11:11:01',
1948 'ip': '10.0.0.1',
1949 'ip6': '2001:10::2'},
1950 {'mac': '00:00:11:11:11:02',
1951 'ip': '10.0.0.2',
1952 'ip6': '2001:10::3'}]
1953
1954 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08001955 # IP tables
1956 #
1957 gt4 = VppIpTable(self, 1)
1958 gt4.add_vpp_config()
1959 gt6 = VppIpTable(self, 1, is_ip6=True)
1960 gt6.add_vpp_config()
1961
1962 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1963 rd1.add_vpp_config()
1964
1965 #
1966 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1967 #
1968 self.pg2.config_ip4()
1969 self.pg2.resolve_arp()
1970 self.pg2.generate_remote_hosts(4)
1971 self.pg2.configure_ipv4_neighbors()
1972 self.pg3.config_ip4()
1973 self.pg3.resolve_arp()
1974
1975 #
1976 # The EP will be on a vlan sub-interface
1977 #
1978 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1979 vlan_11.admin_up()
Ole Troane1ade682019-03-04 23:55:43 +01001980 self.vapi.l2_interface_vlan_tag_rewrite(vlan_11.sw_if_index,
1981 L2_VTR_OP.L2_POP_1,
1982 11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001983
1984 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1985 self.pg3.remote_ip4, 116)
1986 bd_uu_fwd.add_vpp_config()
1987
1988 #
1989 # a GBP bridge domain with a BVI and a UU-flood interface
1990 # The BD is marked as do not learn, so no endpoints are ever
1991 # learnt in this BD.
1992 #
1993 bd1 = VppBridgeDomain(self, 1)
1994 bd1.add_vpp_config()
1995 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1996 learn=False)
1997 gbd1.add_vpp_config()
1998
1999 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2000 self.logger.info(self.vapi.cli("sh gbp bridge"))
2001
2002 # ... and has a /32 applied
2003 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2004 ip_addr.add_vpp_config()
2005
2006 #
2007 # The Endpoint-group in which we are learning endpoints
2008 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002009 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002010 None, self.loop0,
2011 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002012 "2001:10::128",
2013 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002014 epg_220.add_vpp_config()
2015
2016 #
2017 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2018 # leanring enabled
2019 #
2020 vx_tun_l2_1 = VppGbpVxlanTunnel(
2021 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002022 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2023 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002024 vx_tun_l2_1.add_vpp_config()
2025
2026 #
2027 # A static endpoint that the learnt endpoints are trying to
2028 # talk to
2029 #
2030 ep = VppGbpEndpoint(self, vlan_11,
2031 epg_220, None,
2032 "10.0.0.127", "11.0.0.127",
2033 "2001:10::1", "3001::1")
2034 ep.add_vpp_config()
2035
2036 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2037
2038 #
2039 # Send to the static EP
2040 #
2041 for ii, l in enumerate(learnt):
2042 # a packet with an sclass from a knwon EPG
2043 # arriving on an unknown TEP
2044 p = (Ether(src=self.pg2.remote_mac,
2045 dst=self.pg2.local_mac) /
2046 IP(src=self.pg2.remote_hosts[1].ip4,
2047 dst=self.pg2.local_ip4) /
2048 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002049 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002050 Ether(src=l['mac'], dst=ep.mac) /
2051 IP(src=l['ip'], dst=ep.ip4.address) /
2052 UDP(sport=1234, dport=1234) /
2053 Raw('\xa5' * 100))
2054
2055 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2056
2057 #
2058 # packet to EP has the EP's vlan tag
2059 #
2060 for rx in rxs:
2061 self.assertEqual(rx[Dot1Q].vlan, 11)
2062
2063 #
2064 # the EP is not learnt since the BD setting prevents it
2065 # also no TEP too
2066 #
2067 self.assertFalse(find_gbp_endpoint(self,
2068 vx_tun_l2_1.sw_if_index,
2069 mac=l['mac']))
2070 self.assertEqual(INDEX_INVALID,
2071 find_vxlan_gbp_tunnel(
2072 self,
2073 self.pg2.local_ip4,
2074 self.pg2.remote_hosts[1].ip4,
2075 99))
2076
2077 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2078
2079 #
2080 # static to remotes
2081 # we didn't learn the remotes so they are sent to the UU-fwd
2082 #
2083 for l in learnt:
2084 p = (Ether(src=ep.mac, dst=l['mac']) /
2085 Dot1Q(vlan=11) /
2086 IP(dst=l['ip'], src=ep.ip4.address) /
2087 UDP(sport=1234, dport=1234) /
2088 Raw('\xa5' * 100))
2089
2090 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2091
2092 for rx in rxs:
2093 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2094 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2095 self.assertEqual(rx[UDP].dport, 48879)
2096 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002097 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002098 self.assertEqual(rx[VXLAN].vni, 116)
2099 self.assertTrue(rx[VXLAN].flags.G)
2100 self.assertTrue(rx[VXLAN].flags.Instance)
2101 self.assertFalse(rx[VXLAN].gpflags.A)
2102 self.assertFalse(rx[VXLAN].gpflags.D)
2103
2104 self.pg2.unconfig_ip4()
2105 self.pg3.unconfig_ip4()
2106
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002107 def test_gbp_learn_l3(self):
2108 """ GBP L3 Endpoint Learning """
2109
Neale Ranns13a08cc2018-11-07 09:25:54 -08002110 self.vapi.cli("set logging class gbp debug")
2111
Neale Rannsb6a47952018-11-21 05:44:35 -08002112 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002113 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2114 routed_src_mac = "00:22:bd:f8:19:ff"
2115
2116 learnt = [{'mac': '00:00:11:11:11:02',
2117 'ip': '10.0.1.2',
2118 'ip6': '2001:10::2'},
2119 {'mac': '00:00:11:11:11:03',
2120 'ip': '10.0.1.3',
2121 'ip6': '2001:10::3'}]
2122
2123 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002124 # IP tables
2125 #
2126 t4 = VppIpTable(self, 1)
2127 t4.add_vpp_config()
2128 t6 = VppIpTable(self, 1, True)
2129 t6.add_vpp_config()
2130
2131 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2132 self.pg4.remote_ip4, 114)
2133 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2134 self.pg4.remote_ip4, 116)
2135 tun_ip4_uu.add_vpp_config()
2136 tun_ip6_uu.add_vpp_config()
2137
2138 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2139 rd1.add_vpp_config()
2140
Ole Troan8006c6a2018-12-17 12:02:26 +01002141 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002142
2143 #
2144 # Bind the BVI to the RD
2145 #
2146 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2147 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2148
2149 #
2150 # Pg2 hosts the vxlan tunnel
2151 # hosts on pg2 to act as TEPs
2152 # pg3 is BD uu-fwd
2153 # pg4 is RD uu-fwd
2154 #
2155 self.pg2.config_ip4()
2156 self.pg2.resolve_arp()
2157 self.pg2.generate_remote_hosts(4)
2158 self.pg2.configure_ipv4_neighbors()
2159 self.pg3.config_ip4()
2160 self.pg3.resolve_arp()
2161 self.pg4.config_ip4()
2162 self.pg4.resolve_arp()
2163
2164 #
2165 # a GBP bridge domain with a BVI and a UU-flood interface
2166 #
2167 bd1 = VppBridgeDomain(self, 1)
2168 bd1.add_vpp_config()
2169 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2170 gbd1.add_vpp_config()
2171
2172 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2173 self.logger.info(self.vapi.cli("sh gbp bridge"))
2174 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002175
2176 # ... and has a /32 and /128 applied
2177 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2178 ip4_addr.add_vpp_config()
2179 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2180 ip6_addr.add_vpp_config()
2181
2182 #
2183 # The Endpoint-group in which we are learning endpoints
2184 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002185 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002186 None, self.loop0,
2187 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002188 "2001:10::128",
2189 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002190 epg_220.add_vpp_config()
2191
2192 #
2193 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2194 # leanring enabled
2195 #
2196 vx_tun_l3 = VppGbpVxlanTunnel(
2197 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002198 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2199 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002200 vx_tun_l3.add_vpp_config()
2201
2202 #
2203 # A static endpoint that the learnt endpoints are trying to
2204 # talk to
2205 #
2206 ep = VppGbpEndpoint(self, self.pg0,
2207 epg_220, None,
2208 "10.0.0.127", "11.0.0.127",
2209 "2001:10::1", "3001::1")
2210 ep.add_vpp_config()
2211
2212 #
2213 # learn some remote IPv4 EPs
2214 #
2215 for ii, l in enumerate(learnt):
2216 # a packet with an sclass from a knwon EPG
2217 # arriving on an unknown TEP
2218 p = (Ether(src=self.pg2.remote_mac,
2219 dst=self.pg2.local_mac) /
2220 IP(src=self.pg2.remote_hosts[1].ip4,
2221 dst=self.pg2.local_ip4) /
2222 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002223 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002224 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2225 IP(src=l['ip'], dst=ep.ip4.address) /
2226 UDP(sport=1234, dport=1234) /
2227 Raw('\xa5' * 100))
2228
2229 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2230
2231 # the new TEP
2232 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2233 self,
2234 self.pg2.local_ip4,
2235 self.pg2.remote_hosts[1].ip4,
2236 vx_tun_l3.vni)
2237 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2238
2239 # endpoint learnt via the parent GBP-vxlan interface
2240 self.assertTrue(find_gbp_endpoint(self,
2241 vx_tun_l3._sw_if_index,
2242 ip=l['ip']))
2243
2244 #
2245 # Static IPv4 EP replies to learnt
2246 #
2247 for l in learnt:
2248 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2249 IP(dst=l['ip'], src=ep.ip4.address) /
2250 UDP(sport=1234, dport=1234) /
2251 Raw('\xa5' * 100))
2252
2253 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2254
2255 for rx in rxs:
2256 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2257 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2258 self.assertEqual(rx[UDP].dport, 48879)
2259 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002260 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002261 self.assertEqual(rx[VXLAN].vni, 101)
2262 self.assertTrue(rx[VXLAN].flags.G)
2263 self.assertTrue(rx[VXLAN].flags.Instance)
2264 self.assertTrue(rx[VXLAN].gpflags.A)
2265 self.assertFalse(rx[VXLAN].gpflags.D)
2266
2267 inner = rx[VXLAN].payload
2268
2269 self.assertEqual(inner[Ether].src, routed_src_mac)
2270 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2271 self.assertEqual(inner[IP].src, ep.ip4.address)
2272 self.assertEqual(inner[IP].dst, l['ip'])
2273
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002274 for l in learnt:
2275 self.assertFalse(find_gbp_endpoint(self,
2276 tep1_sw_if_index,
2277 ip=l['ip']))
2278
2279 #
2280 # learn some remote IPv6 EPs
2281 #
2282 for ii, l in enumerate(learnt):
2283 # a packet with an sclass from a knwon EPG
2284 # arriving on an unknown TEP
2285 p = (Ether(src=self.pg2.remote_mac,
2286 dst=self.pg2.local_mac) /
2287 IP(src=self.pg2.remote_hosts[1].ip4,
2288 dst=self.pg2.local_ip4) /
2289 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002290 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002291 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2292 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2293 UDP(sport=1234, dport=1234) /
2294 Raw('\xa5' * 100))
2295
2296 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2297
2298 # the new TEP
2299 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2300 self,
2301 self.pg2.local_ip4,
2302 self.pg2.remote_hosts[1].ip4,
2303 vx_tun_l3.vni)
2304 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2305
2306 self.logger.info(self.vapi.cli("show gbp bridge"))
2307 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2308 self.logger.info(self.vapi.cli("show gbp vxlan"))
2309 self.logger.info(self.vapi.cli("show int addr"))
2310
2311 # endpoint learnt via the TEP
2312 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2313
2314 self.logger.info(self.vapi.cli("show gbp endpoint"))
2315 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2316
2317 #
2318 # Static EP replies to learnt
2319 #
2320 for l in learnt:
2321 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2322 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2323 UDP(sport=1234, dport=1234) /
2324 Raw('\xa5' * 100))
2325
2326 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2327
2328 for rx in rxs:
2329 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2330 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2331 self.assertEqual(rx[UDP].dport, 48879)
2332 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002333 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002334 self.assertEqual(rx[VXLAN].vni, 101)
2335 self.assertTrue(rx[VXLAN].flags.G)
2336 self.assertTrue(rx[VXLAN].flags.Instance)
2337 self.assertTrue(rx[VXLAN].gpflags.A)
2338 self.assertFalse(rx[VXLAN].gpflags.D)
2339
2340 inner = rx[VXLAN].payload
2341
2342 self.assertEqual(inner[Ether].src, routed_src_mac)
2343 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2344 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2345 self.assertEqual(inner[IPv6].dst, l['ip6'])
2346
2347 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002348 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002349 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002350
2351 #
2352 # Static sends to unknown EP with no route
2353 #
2354 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2355 IP(dst="10.0.0.99", src=ep.ip4.address) /
2356 UDP(sport=1234, dport=1234) /
2357 Raw('\xa5' * 100))
2358
2359 self.send_and_assert_no_replies(self.pg0, [p])
2360
2361 #
2362 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002363 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002364 #
2365 se_10_24 = VppGbpSubnet(
2366 self, rd1, "10.0.0.0", 24,
2367 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2368 se_10_24.add_vpp_config()
2369
2370 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2371 IP(dst="10.0.0.99", src=ep.ip4.address) /
2372 UDP(sport=1234, dport=1234) /
2373 Raw('\xa5' * 100))
2374
2375 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2376 for rx in rxs:
2377 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2378 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2379 self.assertEqual(rx[UDP].dport, 48879)
2380 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002381 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002382 self.assertEqual(rx[VXLAN].vni, 114)
2383 self.assertTrue(rx[VXLAN].flags.G)
2384 self.assertTrue(rx[VXLAN].flags.Instance)
2385 # policy is not applied to packets sent to the uu-fwd interfaces
2386 self.assertFalse(rx[VXLAN].gpflags.A)
2387 self.assertFalse(rx[VXLAN].gpflags.D)
2388
2389 #
2390 # learn some remote IPv4 EPs
2391 #
2392 for ii, l in enumerate(learnt):
2393 # a packet with an sclass from a knwon EPG
2394 # arriving on an unknown TEP
2395 p = (Ether(src=self.pg2.remote_mac,
2396 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002397 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002398 dst=self.pg2.local_ip4) /
2399 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002400 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002401 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2402 IP(src=l['ip'], dst=ep.ip4.address) /
2403 UDP(sport=1234, dport=1234) /
2404 Raw('\xa5' * 100))
2405
2406 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2407
2408 # the new TEP
2409 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2410 self,
2411 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002412 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002413 vx_tun_l3.vni)
2414 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2415
2416 # endpoint learnt via the parent GBP-vxlan interface
2417 self.assertTrue(find_gbp_endpoint(self,
2418 vx_tun_l3._sw_if_index,
2419 ip=l['ip']))
2420
2421 #
2422 # Add a remote endpoint from the API
2423 #
2424 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2425 epg_220, None,
2426 "10.0.0.88", "11.0.0.88",
2427 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002428 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002429 self.pg2.local_ip4,
2430 self.pg2.remote_hosts[1].ip4,
2431 mac=None)
2432 rep_88.add_vpp_config()
2433
2434 #
2435 # Add a remote endpoint from the API that matches an existing one
2436 #
2437 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2438 epg_220, None,
2439 learnt[0]['ip'], "11.0.0.101",
2440 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002441 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002442 self.pg2.local_ip4,
2443 self.pg2.remote_hosts[1].ip4,
2444 mac=None)
2445 rep_2.add_vpp_config()
2446
2447 #
2448 # Add a route to the leanred EP's v4 subnet
2449 # packets should be send on the v4/v6 uu=fwd interface resp.
2450 #
2451 se_10_1_24 = VppGbpSubnet(
2452 self, rd1, "10.0.1.0", 24,
2453 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2454 se_10_1_24.add_vpp_config()
2455
2456 self.logger.info(self.vapi.cli("show gbp endpoint"))
2457
2458 ips = ["10.0.0.88", learnt[0]['ip']]
2459 for ip in ips:
2460 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2461 IP(dst=ip, src=ep.ip4.address) /
2462 UDP(sport=1234, dport=1234) /
2463 Raw('\xa5' * 100))
2464
2465 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2466
2467 for rx in rxs:
2468 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2469 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2470 self.assertEqual(rx[UDP].dport, 48879)
2471 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002472 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002473 self.assertEqual(rx[VXLAN].vni, 101)
2474 self.assertTrue(rx[VXLAN].flags.G)
2475 self.assertTrue(rx[VXLAN].flags.Instance)
2476 self.assertTrue(rx[VXLAN].gpflags.A)
2477 self.assertFalse(rx[VXLAN].gpflags.D)
2478
2479 inner = rx[VXLAN].payload
2480
2481 self.assertEqual(inner[Ether].src, routed_src_mac)
2482 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2483 self.assertEqual(inner[IP].src, ep.ip4.address)
2484 self.assertEqual(inner[IP].dst, ip)
2485
2486 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002487 # remove the API remote EPs, only API sourced is gone, the DP
2488 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002489 #
2490 rep_88.remove_vpp_config()
2491 rep_2.remove_vpp_config()
2492
Neale Ranns00a469d2018-12-20 06:12:19 -08002493 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2494
2495 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2496 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2497 UDP(sport=1234, dport=1234) /
2498 Raw('\xa5' * 100))
2499 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002500
Neale Ranns13a08cc2018-11-07 09:25:54 -08002501 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002502
Neale Ranns13a08cc2018-11-07 09:25:54 -08002503 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2504 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2505 UDP(sport=1234, dport=1234) /
2506 Raw('\xa5' * 100))
2507 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002508
Neale Ranns13a08cc2018-11-07 09:25:54 -08002509 #
2510 # to appease the testcase we cannot have the registered EP stll
2511 # present (because it's DP learnt) when the TC ends so wait until
2512 # it is removed
2513 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002514 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2515 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002516
2517 #
2518 # shutdown with learnt endpoint present
2519 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002520 p = (Ether(src=self.pg2.remote_mac,
2521 dst=self.pg2.local_mac) /
2522 IP(src=self.pg2.remote_hosts[1].ip4,
2523 dst=self.pg2.local_ip4) /
2524 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002525 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002526 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2527 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2528 UDP(sport=1234, dport=1234) /
2529 Raw('\xa5' * 100))
2530
2531 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2532
2533 # endpoint learnt via the parent GBP-vxlan interface
2534 self.assertTrue(find_gbp_endpoint(self,
2535 vx_tun_l3._sw_if_index,
2536 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002537
2538 #
2539 # TODO
2540 # remote endpoint becomes local
2541 #
2542 self.pg2.unconfig_ip4()
2543 self.pg3.unconfig_ip4()
2544 self.pg4.unconfig_ip4()
2545
Neale Ranns13a08cc2018-11-07 09:25:54 -08002546 def test_gbp_redirect(self):
2547 """ GBP Endpoint Redirect """
2548
2549 self.vapi.cli("set logging class gbp debug")
2550
Neale Rannsb6a47952018-11-21 05:44:35 -08002551 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002552 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2553 routed_src_mac = "00:22:bd:f8:19:ff"
2554
2555 learnt = [{'mac': '00:00:11:11:11:02',
2556 'ip': '10.0.1.2',
2557 'ip6': '2001:10::2'},
2558 {'mac': '00:00:11:11:11:03',
2559 'ip': '10.0.1.3',
2560 'ip6': '2001:10::3'}]
2561
2562 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002563 # IP tables
2564 #
2565 t4 = VppIpTable(self, 1)
2566 t4.add_vpp_config()
2567 t6 = VppIpTable(self, 1, True)
2568 t6.add_vpp_config()
2569
2570 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2571 rd1.add_vpp_config()
2572
Ole Troan8006c6a2018-12-17 12:02:26 +01002573 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002574
2575 #
2576 # Bind the BVI to the RD
2577 #
2578 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2579 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2580
2581 #
2582 # Pg7 hosts a BD's UU-fwd
2583 #
2584 self.pg7.config_ip4()
2585 self.pg7.resolve_arp()
2586
2587 #
2588 # a GBP bridge domains for the EPs
2589 #
2590 bd1 = VppBridgeDomain(self, 1)
2591 bd1.add_vpp_config()
2592 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2593 gbd1.add_vpp_config()
2594
2595 bd2 = VppBridgeDomain(self, 2)
2596 bd2.add_vpp_config()
2597 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2598 gbd2.add_vpp_config()
2599
2600 # ... and has a /32 and /128 applied
2601 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2602 ip4_addr.add_vpp_config()
2603 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2604 ip6_addr.add_vpp_config()
2605 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2606 ip4_addr.add_vpp_config()
2607 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2608 ip6_addr.add_vpp_config()
2609
2610 #
2611 # The Endpoint-groups in which we are learning endpoints
2612 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002613 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002614 None, gbd1.bvi,
2615 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002616 "2001:10::128",
2617 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002618 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002619 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002620 None, gbd2.bvi,
2621 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002622 "2001:11::128",
2623 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002624 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002625 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002626 None, gbd1.bvi,
2627 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002628 "2001:12::128",
2629 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002630 epg_222.add_vpp_config()
2631
2632 #
2633 # a GBP bridge domains for the SEPs
2634 #
2635 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2636 self.pg7.remote_ip4, 116)
2637 bd_uu1.add_vpp_config()
2638 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2639 self.pg7.remote_ip4, 117)
2640 bd_uu2.add_vpp_config()
2641
2642 bd3 = VppBridgeDomain(self, 3)
2643 bd3.add_vpp_config()
2644 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2645 gbd3.add_vpp_config()
2646 bd4 = VppBridgeDomain(self, 4)
2647 bd4.add_vpp_config()
2648 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2649 gbd4.add_vpp_config()
2650
2651 #
2652 # EPGs in which the service endpoints exist
2653 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002654 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002655 None, gbd1.bvi,
2656 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002657 "4001:10::128",
2658 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002659 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002660 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002661 None, gbd2.bvi,
2662 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002663 "4001:11::128",
2664 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002665 epg_321.add_vpp_config()
2666
2667 #
2668 # three local endpoints
2669 #
2670 ep1 = VppGbpEndpoint(self, self.pg0,
2671 epg_220, None,
2672 "10.0.0.1", "11.0.0.1",
2673 "2001:10::1", "3001:10::1")
2674 ep1.add_vpp_config()
2675 ep2 = VppGbpEndpoint(self, self.pg1,
2676 epg_221, None,
2677 "10.0.1.1", "11.0.1.1",
2678 "2001:11::1", "3001:11::1")
2679 ep2.add_vpp_config()
2680 ep3 = VppGbpEndpoint(self, self.pg2,
2681 epg_222, None,
2682 "10.0.2.2", "11.0.2.2",
2683 "2001:12::1", "3001:12::1")
2684 ep3.add_vpp_config()
2685
2686 #
2687 # service endpoints
2688 #
2689 sep1 = VppGbpEndpoint(self, self.pg3,
2690 epg_320, None,
2691 "12.0.0.1", "13.0.0.1",
2692 "4001:10::1", "5001:10::1")
2693 sep1.add_vpp_config()
2694 sep2 = VppGbpEndpoint(self, self.pg4,
2695 epg_320, None,
2696 "12.0.0.2", "13.0.0.2",
2697 "4001:10::2", "5001:10::2")
2698 sep2.add_vpp_config()
2699 sep3 = VppGbpEndpoint(self, self.pg5,
2700 epg_321, None,
2701 "12.0.1.1", "13.0.1.1",
2702 "4001:11::1", "5001:11::1")
2703 sep3.add_vpp_config()
2704 # this EP is not installed immediately
2705 sep4 = VppGbpEndpoint(self, self.pg6,
2706 epg_321, None,
2707 "12.0.1.2", "13.0.1.2",
2708 "4001:11::2", "5001:11::2")
2709
2710 #
2711 # an L2 switch packet between local EPs in different EPGs
2712 # different dest ports on each so the are LB hashed differently
2713 #
2714 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2715 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2716 UDP(sport=1234, dport=1234) /
2717 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002718 (Ether(src=ep3.mac, dst=ep1.mac) /
2719 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2720 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002721 Raw('\xa5' * 100))]
2722 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2723 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2724 UDP(sport=1234, dport=1234) /
2725 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002726 (Ether(src=ep3.mac, dst=ep1.mac) /
2727 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002728 UDP(sport=1234, dport=1230) /
2729 Raw('\xa5' * 100))]
2730
2731 # should be dropped since no contract yet
2732 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2733 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2734
2735 #
2736 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2737 # one of the next-hops is via an EP that is not known
2738 #
2739 acl = VppGbpAcl(self)
2740 rule4 = acl.create_rule(permit_deny=1, proto=17)
2741 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2742 acl_index = acl.add_vpp_config([rule4, rule6])
2743
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002744 #
2745 # test the src-ip hash mode
2746 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002747 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002748 self, epg_220, epg_222, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002749 [VppGbpContractRule(
2750 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002751 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002752 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2753 sep1.ip4, sep1.epg.rd),
2754 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2755 sep2.ip4, sep2.epg.rd)]),
2756 VppGbpContractRule(
2757 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002758 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002759 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2760 sep3.ip6, sep3.epg.rd),
2761 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002762 sep4.ip6, sep4.epg.rd)])],
2763 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002764 c1.add_vpp_config()
2765
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002766 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002767 self, epg_222, epg_220, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002768 [VppGbpContractRule(
2769 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2770 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2771 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2772 sep1.ip4, sep1.epg.rd),
2773 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2774 sep2.ip4, sep2.epg.rd)]),
2775 VppGbpContractRule(
2776 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2777 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2778 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2779 sep3.ip6, sep3.epg.rd),
2780 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002781 sep4.ip6, sep4.epg.rd)])],
2782 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002783 c2.add_vpp_config()
2784
Neale Ranns13a08cc2018-11-07 09:25:54 -08002785 #
2786 # send again with the contract preset, now packets arrive
2787 # at SEP1 or SEP2 depending on the hashing
2788 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002789 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002790
2791 for rx in rxs:
2792 self.assertEqual(rx[Ether].src, routed_src_mac)
2793 self.assertEqual(rx[Ether].dst, sep1.mac)
2794 self.assertEqual(rx[IP].src, ep1.ip4.address)
2795 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2796
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002797 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2798
2799 for rx in rxs:
2800 self.assertEqual(rx[Ether].src, routed_src_mac)
2801 self.assertEqual(rx[Ether].dst, sep2.mac)
2802 self.assertEqual(rx[IP].src, ep3.ip4.address)
2803 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2804
Neale Ranns13a08cc2018-11-07 09:25:54 -08002805 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2806
2807 for rx in rxs:
2808 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2809 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2810 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2811 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2812 self.assertEqual(rx[VXLAN].vni, 117)
2813 self.assertTrue(rx[VXLAN].flags.G)
2814 self.assertTrue(rx[VXLAN].flags.Instance)
2815 # redirect policy has been applied
2816 self.assertTrue(rx[VXLAN].gpflags.A)
2817 self.assertFalse(rx[VXLAN].gpflags.D)
2818
2819 inner = rx[VXLAN].payload
2820
2821 self.assertEqual(inner[Ether].src, routed_src_mac)
2822 self.assertEqual(inner[Ether].dst, sep4.mac)
2823 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2824 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2825
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002826 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002827
2828 for rx in rxs:
2829 self.assertEqual(rx[Ether].src, routed_src_mac)
2830 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002831 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2832 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002833
2834 #
2835 # programme the unknown EP
2836 #
2837 sep4.add_vpp_config()
2838
2839 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2840
2841 for rx in rxs:
2842 self.assertEqual(rx[Ether].src, routed_src_mac)
2843 self.assertEqual(rx[Ether].dst, sep4.mac)
2844 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2845 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2846
2847 #
2848 # and revert back to unprogrammed
2849 #
2850 sep4.remove_vpp_config()
2851
2852 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2853
2854 for rx in rxs:
2855 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2856 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2857 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2858 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2859 self.assertEqual(rx[VXLAN].vni, 117)
2860 self.assertTrue(rx[VXLAN].flags.G)
2861 self.assertTrue(rx[VXLAN].flags.Instance)
2862 # redirect policy has been applied
2863 self.assertTrue(rx[VXLAN].gpflags.A)
2864 self.assertFalse(rx[VXLAN].gpflags.D)
2865
2866 inner = rx[VXLAN].payload
2867
2868 self.assertEqual(inner[Ether].src, routed_src_mac)
2869 self.assertEqual(inner[Ether].dst, sep4.mac)
2870 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2871 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2872
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002873 c1.remove_vpp_config()
2874 c2.remove_vpp_config()
2875
2876 #
2877 # test the symmetric hash mode
2878 #
2879 c1 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002880 self, epg_220, epg_222, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002881 [VppGbpContractRule(
2882 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2883 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2884 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2885 sep1.ip4, sep1.epg.rd),
2886 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2887 sep2.ip4, sep2.epg.rd)]),
2888 VppGbpContractRule(
2889 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2890 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2891 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2892 sep3.ip6, sep3.epg.rd),
2893 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002894 sep4.ip6, sep4.epg.rd)])],
2895 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002896 c1.add_vpp_config()
2897
2898 c2 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002899 self, epg_222, epg_220, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002900 [VppGbpContractRule(
2901 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2902 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2903 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2904 sep1.ip4, sep1.epg.rd),
2905 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2906 sep2.ip4, sep2.epg.rd)]),
2907 VppGbpContractRule(
2908 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2909 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2910 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2911 sep3.ip6, sep3.epg.rd),
2912 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002913 sep4.ip6, sep4.epg.rd)])],
2914 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002915 c2.add_vpp_config()
2916
2917 #
2918 # send again with the contract preset, now packets arrive
2919 # at SEP1 for both directions
2920 #
2921 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2922
2923 for rx in rxs:
2924 self.assertEqual(rx[Ether].src, routed_src_mac)
2925 self.assertEqual(rx[Ether].dst, sep1.mac)
2926 self.assertEqual(rx[IP].src, ep1.ip4.address)
2927 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2928
2929 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2930
2931 for rx in rxs:
2932 self.assertEqual(rx[Ether].src, routed_src_mac)
2933 self.assertEqual(rx[Ether].dst, sep1.mac)
2934 self.assertEqual(rx[IP].src, ep3.ip4.address)
2935 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2936
Neale Ranns13a08cc2018-11-07 09:25:54 -08002937 #
2938 # programme the unknown EP for the L3 tests
2939 #
2940 sep4.add_vpp_config()
2941
2942 #
2943 # an L3 switch packet between local EPs in different EPGs
2944 # different dest ports on each so the are LB hashed differently
2945 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002946 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002947 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2948 UDP(sport=1234, dport=1234) /
2949 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002950 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002951 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2952 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002953 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002954 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002955 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2956 UDP(sport=1234, dport=1234) /
2957 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002958 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002959 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2960 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002961 Raw('\xa5' * 100))]
2962
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002963 c3 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00002964 self, epg_220, epg_221, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002965 [VppGbpContractRule(
2966 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2967 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2968 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2969 sep1.ip4, sep1.epg.rd),
2970 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2971 sep2.ip4, sep2.epg.rd)]),
2972 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002973 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002974 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002975 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2976 sep3.ip6, sep3.epg.rd),
2977 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2978 sep4.ip6, sep4.epg.rd)])],
2979 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002980 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002981
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002982 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002983
2984 for rx in rxs:
2985 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002986 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002987 self.assertEqual(rx[IP].src, ep1.ip4.address)
2988 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2989
2990 #
2991 # learn a remote EP in EPG 221
2992 #
2993 vx_tun_l3 = VppGbpVxlanTunnel(
2994 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002995 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2996 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002997 vx_tun_l3.add_vpp_config()
2998
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002999 c4 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00003000 self, epg_221, epg_220, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003001 [VppGbpContractRule(
3002 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3003 []),
3004 VppGbpContractRule(
3005 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003006 [])],
3007 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003008 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003009
3010 p = (Ether(src=self.pg7.remote_mac,
3011 dst=self.pg7.local_mac) /
3012 IP(src=self.pg7.remote_ip4,
3013 dst=self.pg7.local_ip4) /
3014 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003015 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003016 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003017 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3018 UDP(sport=1234, dport=1234) /
3019 Raw('\xa5' * 100))
3020
3021 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3022
3023 # endpoint learnt via the parent GBP-vxlan interface
3024 self.assertTrue(find_gbp_endpoint(self,
3025 vx_tun_l3._sw_if_index,
3026 ip="10.0.0.88"))
3027
3028 p = (Ether(src=self.pg7.remote_mac,
3029 dst=self.pg7.local_mac) /
3030 IP(src=self.pg7.remote_ip4,
3031 dst=self.pg7.local_ip4) /
3032 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003033 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003034 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003035 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3036 UDP(sport=1234, dport=1234) /
3037 Raw('\xa5' * 100))
3038
3039 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3040
3041 # endpoint learnt via the parent GBP-vxlan interface
3042 self.assertTrue(find_gbp_endpoint(self,
3043 vx_tun_l3._sw_if_index,
3044 ip="2001:10::88"))
3045
3046 #
3047 # L3 switch from local to remote EP
3048 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003049 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003050 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3051 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003052 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003053 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003054 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3055 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003056 Raw('\xa5' * 100))]
3057
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003058 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003059
3060 for rx in rxs:
3061 self.assertEqual(rx[Ether].src, routed_src_mac)
3062 self.assertEqual(rx[Ether].dst, sep1.mac)
3063 self.assertEqual(rx[IP].src, ep1.ip4.address)
3064 self.assertEqual(rx[IP].dst, "10.0.0.88")
3065
3066 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3067
3068 for rx in rxs:
3069 self.assertEqual(rx[Ether].src, routed_src_mac)
3070 self.assertEqual(rx[Ether].dst, sep4.mac)
3071 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3072 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3073
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003074 #
3075 # test the dst-ip hash mode
3076 #
3077 c5 = VppGbpContract(
Neale Ranns4ba67722019-02-28 11:11:39 +00003078 self, epg_220, epg_221, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003079 [VppGbpContractRule(
3080 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3081 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3082 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3083 sep1.ip4, sep1.epg.rd),
3084 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3085 sep2.ip4, sep2.epg.rd)]),
3086 VppGbpContractRule(
3087 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3088 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3089 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3090 sep3.ip6, sep3.epg.rd),
3091 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003092 sep4.ip6, sep4.epg.rd)])],
3093 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003094 c5.add_vpp_config()
3095
3096 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3097
3098 for rx in rxs:
3099 self.assertEqual(rx[Ether].src, routed_src_mac)
3100 self.assertEqual(rx[Ether].dst, sep1.mac)
3101 self.assertEqual(rx[IP].src, ep1.ip4.address)
3102 self.assertEqual(rx[IP].dst, "10.0.0.88")
3103
3104 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003105
3106 for rx in rxs:
3107 self.assertEqual(rx[Ether].src, routed_src_mac)
3108 self.assertEqual(rx[Ether].dst, sep3.mac)
3109 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3110 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3111
Neale Rannsb6a47952018-11-21 05:44:35 -08003112 #
3113 # cleanup
3114 #
3115 self.pg7.unconfig_ip4()
3116
3117 def test_gbp_l3_out(self):
3118 """ GBP L3 Out """
3119
3120 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3121 self.vapi.cli("set logging class gbp debug")
3122
3123 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3124 routed_src_mac = "00:22:bd:f8:19:ff"
3125
3126 #
3127 # IP tables
3128 #
3129 t4 = VppIpTable(self, 1)
3130 t4.add_vpp_config()
3131 t6 = VppIpTable(self, 1, True)
3132 t6.add_vpp_config()
3133
3134 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3135 rd1.add_vpp_config()
3136
Ole Troan8006c6a2018-12-17 12:02:26 +01003137 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003138
3139 #
3140 # Bind the BVI to the RD
3141 #
3142 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3143 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3144
3145 #
3146 # Pg7 hosts a BD's BUM
3147 # Pg1 some other l3 interface
3148 #
3149 self.pg7.config_ip4()
3150 self.pg7.resolve_arp()
3151
3152 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003153 # a multicast vxlan-gbp tunnel for broadcast in the BD
3154 #
3155 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3156 "239.1.1.1", 88,
3157 mcast_itf=self.pg7)
3158 tun_bm.add_vpp_config()
3159
3160 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003161 # a GBP external bridge domains for the EPs
3162 #
3163 bd1 = VppBridgeDomain(self, 1)
3164 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003165 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003166 gbd1.add_vpp_config()
3167
3168 #
3169 # The Endpoint-groups in which the external endpoints exist
3170 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003171 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003172 None, gbd1.bvi,
3173 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003174 "2001:10::128",
3175 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003176 epg_220.add_vpp_config()
3177
3178 # the BVIs have the subnets applied ...
3179 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3180 ip4_addr.add_vpp_config()
3181 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3182 ip6_addr.add_vpp_config()
3183
3184 # ... which are L3-out subnets
3185 l3o_1 = VppGbpSubnet(
3186 self, rd1, "10.0.0.0", 24,
3187 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4ba67722019-02-28 11:11:39 +00003188 epg=epg_220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003189 l3o_1.add_vpp_config()
3190
3191 #
3192 # an external interface attached to the outside world and the
3193 # external BD
3194 #
3195 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3196 vlan_100.admin_up()
3197 ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1)
3198 ext_itf.add_vpp_config()
3199
3200 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003201 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003202 #
3203 vx_tun_l3 = VppGbpVxlanTunnel(
3204 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003205 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3206 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003207 vx_tun_l3.add_vpp_config()
3208
3209 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003210 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003211 # are ARP'd for
3212 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003213 p4 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003214 Dot1Q(vlan=100) /
3215 IP(src="10.0.0.1", dst="10.0.0.88") /
3216 UDP(sport=1234, dport=1234) /
3217 Raw('\xa5' * 100))
Ole Troan8006c6a2018-12-17 12:02:26 +01003218 p6 = (Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003219 Dot1Q(vlan=100) /
3220 IPv6(src="2001:10::1", dst="2001:10::88") /
3221 UDP(sport=1234, dport=1234) /
3222 Raw('\xa5' * 100))
3223
3224 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3225
3226 for rx in rxs:
3227 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3228 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3229 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3230 self.assertEqual(rx[IP].dst, "239.1.1.1")
3231 self.assertEqual(rx[VXLAN].vni, 88)
3232 self.assertTrue(rx[VXLAN].flags.G)
3233 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003234 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003235 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003236 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003237 self.assertFalse(rx[VXLAN].gpflags.D)
3238
3239 inner = rx[VXLAN].payload
3240
3241 self.assertTrue(inner.haslayer(ARP))
3242
3243 #
3244 # An external Endpoint
3245 #
3246 eep = VppGbpEndpoint(self, vlan_100,
3247 epg_220, None,
3248 "10.0.0.1", "11.0.0.1",
3249 "2001:10::1", "3001::1",
3250 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3251 eep.add_vpp_config()
3252
3253 #
3254 # A remote endpoint
3255 #
3256 rep = VppGbpEndpoint(self, vx_tun_l3,
3257 epg_220, None,
3258 "10.0.0.101", "11.0.0.101",
3259 "2001:10::101", "3001::101",
3260 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3261 self.pg7.local_ip4,
3262 self.pg7.remote_ip4,
3263 mac=None)
3264 rep.add_vpp_config()
3265
3266 #
3267 # remote to external
3268 #
3269 p = (Ether(src=self.pg7.remote_mac,
3270 dst=self.pg7.local_mac) /
3271 IP(src=self.pg7.remote_ip4,
3272 dst=self.pg7.local_ip4) /
3273 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003274 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003275 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003276 IP(src="10.0.0.101", dst="10.0.0.1") /
3277 UDP(sport=1234, dport=1234) /
3278 Raw('\xa5' * 100))
3279
3280 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3281
3282 #
3283 # A subnet reachable through the external EP
3284 #
3285 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
3286 [VppRoutePath(eep.ip4.address,
3287 eep.epg.bvi.sw_if_index)],
3288 table_id=t4.table_id)
3289 ip_220.add_vpp_config()
3290
3291 l3o_220 = VppGbpSubnet(
3292 self, rd1, "10.220.0.0", 24,
3293 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4ba67722019-02-28 11:11:39 +00003294 epg=epg_220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003295 l3o_220.add_vpp_config()
3296
3297 p = (Ether(src=self.pg7.remote_mac,
3298 dst=self.pg7.local_mac) /
3299 IP(src=self.pg7.remote_ip4,
3300 dst=self.pg7.local_ip4) /
3301 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003302 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003303 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003304 IP(src="10.0.0.101", dst="10.220.0.1") /
3305 UDP(sport=1234, dport=1234) /
3306 Raw('\xa5' * 100))
3307
3308 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3309
3310 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003311 # cleanup
3312 #
3313 self.pg7.unconfig_ip4()
3314
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003315
3316if __name__ == '__main__':
3317 unittest.main(testRunner=VppTestRunner)