blob: 21d0770cf6645a6fcd3cf0f6e92dcdda282b885d [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Paul Vinciguerradc22c832021-04-25 21:50:38 -04002import typing
3from socket import AF_INET6, inet_pton, inet_ntop
Neale Rannsbc27d1b2018-02-05 01:13:38 -08004import unittest
Neale Rannsefd7bc22019-11-11 08:32:34 +00005from ipaddress import ip_address, IPv4Network, IPv6Network
Neale Rannsbc27d1b2018-02-05 01:13:38 -08006
Neale Rannsbc27d1b2018-02-05 01:13:38 -08007from scapy.packet import Raw
Neale Rannsc29c0af2018-11-07 04:21:12 -08008from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Ranns36abbf12019-03-12 02:34:07 -07009from scapy.layers.inet import IP, UDP, ICMP
Paul Vinciguerradc22c832021-04-25 21:50:38 -040010from scapy.layers.inet6 import (
11 IPv6,
12 ICMPv6ND_NS,
13 ICMPv6NDOptSrcLLAddr,
14 ICMPv6ND_NA,
15 ICMPv6EchoRequest,
16)
Neale Ranns25b04942018-04-04 09:34:50 -070017from scapy.utils6 import in6_getnsma, in6_getnsmac
Neale Ranns93cc3ee2018-10-10 07:22:51 -070018from scapy.layers.vxlan import VXLAN
Paul Vinciguerradc22c832021-04-25 21:50:38 -040019from scapy.data import ETH_P_IP, ETH_P_IPV6
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080020
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000021from framework import tag_fixme_vpp_workers
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080022from framework import VppTestCase, VppTestRunner
23from vpp_object import VppObject
24from vpp_interface import VppInterface
Paul Vinciguerradc22c832021-04-25 21:50:38 -040025from vpp_ip_route import (
26 VppIpRoute,
27 VppRoutePath,
28 VppIpTable,
29 VppIpInterfaceAddress,
30 VppIpInterfaceBind,
31 find_route,
32 FibPathProto,
33 FibPathType,
34)
35from vpp_l2 import (
36 VppBridgeDomain,
37 VppBridgeDomainPort,
38 VppBridgeDomainArpEntry,
39 VppL2FibEntry,
40 find_bridge_domain_port,
41 VppL2Vtr,
42)
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -070043from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
Neale Rannsefd7bc22019-11-11 08:32:34 +000044from vpp_ip import DpoProto, get_dpo_proto
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080045from vpp_papi import VppEnum, MACAddress
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080046from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \
47 VppVxlanGbpTunnel
Neale Ranns4dd4cf42019-03-27 05:06:47 -070048from vpp_neighbor import VppNeighbor
Jakub Grajciar2f8cd912020-03-27 06:55:06 +010049from vpp_acl import AclRule, VppAcl
Neale Rannsbc27d1b2018-02-05 01:13:38 -080050
Paul Vinciguerra4271c972019-05-14 13:25:49 -040051NUM_PKTS = 67
52
Neale Rannsbc27d1b2018-02-05 01:13:38 -080053
Neale Ranns6d1ba562019-07-10 01:14:58 -070054def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None,
Benoît Ganne040d47c2020-04-16 16:57:00 +020055 tep=None, sclass=None, flags=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070056 if ip:
Neale Rannsefd7bc22019-11-11 08:32:34 +000057 vip = ip
Neale Ranns93cc3ee2018-10-10 07:22:51 -070058 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010059 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070060
61 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070062
Neale Rannsc0a93142018-09-05 15:42:26 -070063 for ep in eps:
Neale Ranns3eea9de2019-06-21 02:09:25 -070064 if tep:
Neale Rannsefd7bc22019-11-11 08:32:34 +000065 src = tep[0]
66 dst = tep[1]
67 if src != str(ep.endpoint.tun.src) or \
68 dst != str(ep.endpoint.tun.dst):
Neale Ranns3eea9de2019-06-21 02:09:25 -070069 continue
Neale Ranns93cc3ee2018-10-10 07:22:51 -070070 if sw_if_index:
71 if ep.endpoint.sw_if_index != sw_if_index:
72 continue
Neale Ranns6d1ba562019-07-10 01:14:58 -070073 if sclass:
74 if ep.endpoint.sclass != sclass:
75 continue
Benoît Ganne040d47c2020-04-16 16:57:00 +020076 if flags:
77 if flags != (flags & ep.endpoint.flags):
78 continue
Neale Ranns93cc3ee2018-10-10 07:22:51 -070079 if ip:
80 for eip in ep.endpoint.ips:
Neale Rannsefd7bc22019-11-11 08:32:34 +000081 if vip == str(eip):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070082 return True
83 if mac:
Neale Rannsefd7bc22019-11-11 08:32:34 +000084 if vmac == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070085 return True
Neale Ranns3eea9de2019-06-21 02:09:25 -070086
Neale Rannsc0a93142018-09-05 15:42:26 -070087 return False
88
89
Paul Vinciguerradc22c832021-04-25 21:50:38 -040090def find_gbp_vxlan(test: VppTestCase, vni):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070091 ts = test.vapi.gbp_vxlan_tunnel_dump()
92 for t in ts:
93 if t.tunnel.vni == vni:
94 return True
95 return False
96
97
Neale Rannsbc27d1b2018-02-05 01:13:38 -080098class VppGbpEndpoint(VppObject):
99 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200100 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800101 """
102
Neale Ranns25b04942018-04-04 09:34:50 -0700103 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700104 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +0100105 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -0700106
107 @property
Neale Rannsc0a93142018-09-05 15:42:26 -0700108 def ip4(self):
109 return self._ip4
110
111 @property
112 def fip4(self):
113 return self._fip4
114
115 @property
116 def ip6(self):
117 return self._ip6
118
119 @property
120 def fip6(self):
121 return self._fip6
122
123 @property
124 def ips(self):
125 return [self.ip4, self.ip6]
126
127 @property
128 def fips(self):
129 return [self.fip4, self.fip6]
130
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700131 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
132 flags=0,
133 tun_src="0.0.0.0",
134 tun_dst="0.0.0.0",
135 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800136 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700137 self.itf = itf
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400138 self.handle = None
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800139 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700140 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700141
Neale Rannsefd7bc22019-11-11 08:32:34 +0000142 self._ip4 = ip4
143 self._fip4 = fip4
144 self._ip6 = ip6
145 self._fip6 = fip6
Neale Rannsc0a93142018-09-05 15:42:26 -0700146
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700147 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100148 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700149 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100150 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700151
152 self.flags = flags
Neale Rannsefd7bc22019-11-11 08:32:34 +0000153 self.tun_src = tun_src
154 self.tun_dst = tun_dst
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800155
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400156 def encode(self):
157 ips = [self.ip4, self.ip6]
158 return {
159 "sw_if_index": self.itf.sw_if_index,
160 "ips": ips,
161 "n_ips": len(ips),
162 "mac": self.vmac.packed,
163 "sclass": self.epg.sclass,
164 "flags": self.flags,
165 "tun": {
166 "src": self.tun_src,
167 "dst": self.tun_dst,
168 },
169 }
170
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800171 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700172 res = self._test.vapi.gbp_endpoint_add(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400173 endpoint=self.encode(),
174 )
Neale Rannsc0a93142018-09-05 15:42:26 -0700175 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800176 self._test.registry.register(self, self._test.logger)
177
178 def remove_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400179 self._test.vapi.gbp_endpoint_del(handle=self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800180
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800181 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700182 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
183 self.itf.sw_if_index,
Neale Rannsefd7bc22019-11-11 08:32:34 +0000184 self.ip4,
Neale Ranns4ba67722019-02-28 11:11:39 +0000185 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800186
187 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700188 return find_gbp_endpoint(self._test,
189 self.itf.sw_if_index,
Neale Rannsefd7bc22019-11-11 08:32:34 +0000190 self.ip4)
Neale Ranns25b04942018-04-04 09:34:50 -0700191
192
193class VppGbpRecirc(VppObject):
194 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200195 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700196 """
197
198 def __init__(self, test, epg, recirc, is_ext=False):
199 self._test = test
200 self.recirc = recirc
201 self.epg = epg
202 self.is_ext = is_ext
203
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400204 def encode(self):
205 return {
206 "is_ext": self.is_ext,
207 "sw_if_index": self.recirc.sw_if_index,
208 "sclass": self.epg.sclass,
209 }
210
Neale Ranns25b04942018-04-04 09:34:50 -0700211 def add_vpp_config(self):
212 self._test.vapi.gbp_recirc_add_del(
213 1,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400214 recirc=self.encode(),
215 )
Neale Ranns25b04942018-04-04 09:34:50 -0700216 self._test.registry.register(self, self._test.logger)
217
218 def remove_vpp_config(self):
219 self._test.vapi.gbp_recirc_add_del(
220 0,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400221 recirc=self.encode(),
222 )
Neale Ranns25b04942018-04-04 09:34:50 -0700223
Neale Ranns25b04942018-04-04 09:34:50 -0700224 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700225 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700226
227 def query_vpp_config(self):
228 rs = self._test.vapi.gbp_recirc_dump()
229 for r in rs:
230 if r.recirc.sw_if_index == self.recirc.sw_if_index:
231 return True
232 return False
233
234
Neale Rannsb6a47952018-11-21 05:44:35 -0800235class VppGbpExtItf(VppObject):
236 """
237 GBP ExtItfulation Interface
238 """
239
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200240 def __init__(self, test, itf, bd, rd, anon=False):
Neale Rannsb6a47952018-11-21 05:44:35 -0800241 self._test = test
242 self.itf = itf
243 self.bd = bd
244 self.rd = rd
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200245 self.flags = 1 if anon else 0
Neale Rannsb6a47952018-11-21 05:44:35 -0800246
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400247 def encode(self):
248 return {
249 "sw_if_index": self.itf.sw_if_index,
250 "bd_id": self.bd.bd_id,
251 "rd_id": self.rd.rd_id,
252 "flags": self.flags,
253 }
254
Neale Rannsb6a47952018-11-21 05:44:35 -0800255 def add_vpp_config(self):
256 self._test.vapi.gbp_ext_itf_add_del(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400257 1,
258 ext_itf=self.encode(),
259 )
Neale Rannsb6a47952018-11-21 05:44:35 -0800260 self._test.registry.register(self, self._test.logger)
261
262 def remove_vpp_config(self):
263 self._test.vapi.gbp_ext_itf_add_del(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400264 0,
265 ext_itf=self.encode(),
266 )
Neale Rannsb6a47952018-11-21 05:44:35 -0800267
Neale Rannsb6a47952018-11-21 05:44:35 -0800268 def object_id(self):
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200269 return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index,
270 " [anon]" if self.flags else "")
Neale Rannsb6a47952018-11-21 05:44:35 -0800271
272 def query_vpp_config(self):
273 rs = self._test.vapi.gbp_ext_itf_dump()
274 for r in rs:
275 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
276 return True
277 return False
278
279
Neale Ranns25b04942018-04-04 09:34:50 -0700280class VppGbpSubnet(VppObject):
281 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200282 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700283 """
Filip Vargaf4749ca2019-04-25 14:55:32 +0200284
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700285 def __init__(self, test, rd, address, address_len,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400286 type, sw_if_index=0xffffffff, sclass=0xffff):
287 # TODO: replace hardcoded defaults when vpp_papi supports
288 # defaults in typedefs
Neale Ranns25b04942018-04-04 09:34:50 -0700289 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700290 self.rd_id = rd.rd_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000291 a = ip_address(address)
292 if 4 == a.version:
293 self.prefix = IPv4Network("%s/%d" % (address, address_len),
294 strict=False)
295 else:
296 self.prefix = IPv6Network("%s/%d" % (address, address_len),
297 strict=False)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700298 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700299 self.sw_if_index = sw_if_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700300 self.sclass = sclass
Neale Ranns25b04942018-04-04 09:34:50 -0700301
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400302 def encode(self):
303 return {
304 "type": self.type,
305 "sw_if_index": self.sw_if_index,
306 "sclass": self.sclass,
307 "prefix": self.prefix,
308 "rd_id": self.rd_id,
309 }
310
Neale Ranns25b04942018-04-04 09:34:50 -0700311 def add_vpp_config(self):
312 self._test.vapi.gbp_subnet_add_del(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400313 is_add=1,
314 subnet=self.encode(),
315 )
Neale Ranns25b04942018-04-04 09:34:50 -0700316 self._test.registry.register(self, self._test.logger)
317
318 def remove_vpp_config(self):
319 self._test.vapi.gbp_subnet_add_del(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400320 is_add=0,
321 subnet=self.encode()
322 )
Neale Ranns25b04942018-04-04 09:34:50 -0700323
Neale Ranns25b04942018-04-04 09:34:50 -0700324 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700325 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700326
327 def query_vpp_config(self):
328 ss = self._test.vapi.gbp_subnet_dump()
329 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700330 if s.subnet.rd_id == self.rd_id and \
Filip Vargaf4749ca2019-04-25 14:55:32 +0200331 s.subnet.type == self.type and \
332 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700333 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700334 return False
335
336
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800337class VppGbpEndpointRetention(object):
338 def __init__(self, remote_ep_timeout=0xffffffff):
339 self.remote_ep_timeout = remote_ep_timeout
340
341 def encode(self):
342 return {'remote_ep_timeout': self.remote_ep_timeout}
343
344
Neale Ranns25b04942018-04-04 09:34:50 -0700345class VppGbpEndpointGroup(VppObject):
346 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200347 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700348 """
349
Neale Ranns4ba67722019-02-28 11:11:39 +0000350 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800351 bvi, bvi_ip4, bvi_ip6=None,
352 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700353 self._test = test
354 self.uplink = uplink
355 self.bvi = bvi
Neale Rannsefd7bc22019-11-11 08:32:34 +0000356 self.bvi_ip4 = bvi_ip4
357 self.bvi_ip6 = bvi_ip6
Neale Ranns4ba67722019-02-28 11:11:39 +0000358 self.vnid = vnid
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400359 self.bd = bd # VppGbpBridgeDomain
Neale Ranns25b04942018-04-04 09:34:50 -0700360 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800361 self.sclass = sclass
362 if 0 == self.sclass:
363 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800364 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700365
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400366 def encode(self) -> dict:
367 return {
368 "uplink_sw_if_index": self.uplink.sw_if_index
369 if self.uplink else INDEX_INVALID,
370 "bd_id": self.bd.bd.bd_id,
371 "rd_id": self.rd.rd_id,
372 "vnid": self.vnid,
373 "sclass": self.sclass,
374 "retention": self.retention.encode(),
375 }
376
Neale Ranns25b04942018-04-04 09:34:50 -0700377 def add_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400378 self._test.vapi.gbp_endpoint_group_add(epg=self.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700379 self._test.registry.register(self, self._test.logger)
380
381 def remove_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400382 self._test.vapi.gbp_endpoint_group_del(sclass=self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700383
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400384 def object_id(self) -> str:
Neale Ranns4ba67722019-02-28 11:11:39 +0000385 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700386
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400387 def query_vpp_config(self) -> bool:
Neale Ranns25b04942018-04-04 09:34:50 -0700388 epgs = self._test.vapi.gbp_endpoint_group_dump()
389 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000390 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800391 return True
392 return False
393
394
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700395class VppGbpBridgeDomain(VppObject):
396 """
397 GBP Bridge Domain
398 """
399
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400400 def __init__(self, test, bd, rd, bvi,
401 uu_fwd: typing.Optional[VppVxlanGbpTunnel] = None,
Neale Ranns69a85b52019-06-14 07:49:50 +0000402 bm_flood=None, learn=True,
403 uu_drop=False, bm_drop=False,
404 ucast_arp=False):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700405 self._test = test
406 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800407 self.uu_fwd = uu_fwd
408 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700409 self.bd = bd
Neale Ranns160c9232019-06-19 06:25:56 -0700410 self.rd = rd
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700411
Neale Rannsc29c0af2018-11-07 04:21:12 -0800412 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
Neale Ranns69a85b52019-06-14 07:49:50 +0000413
414 self.flags = e.GBP_BD_API_FLAG_NONE
415 if not learn:
416 self.flags |= e.GBP_BD_API_FLAG_DO_NOT_LEARN
417 if uu_drop:
418 self.flags |= e.GBP_BD_API_FLAG_UU_FWD_DROP
419 if bm_drop:
420 self.flags |= e.GBP_BD_API_FLAG_MCAST_DROP
421 if ucast_arp:
422 self.flags |= e.GBP_BD_API_FLAG_UCAST_ARP
Neale Rannsc29c0af2018-11-07 04:21:12 -0800423
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400424 def encode(self) -> dict:
425 return {
426 "flags": self.flags,
427 "bvi_sw_if_index": self.bvi.sw_if_index,
428 "uu_fwd_sw_if_index": self.uu_fwd.sw_if_index
429 if self.uu_fwd else INDEX_INVALID,
430 "bm_flood_sw_if_index": self.bm_flood.sw_if_index
431 if self.bm_flood else INDEX_INVALID,
432 "bd_id": self.bd.bd_id,
433 "rd_id": self.rd.rd_id,
434 }
435
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700436 def add_vpp_config(self):
437 self._test.vapi.gbp_bridge_domain_add(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400438 bd=self.encode(),
439 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700440 self._test.registry.register(self, self._test.logger)
441
442 def remove_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400443 self._test.vapi.gbp_bridge_domain_del(bd_id=self.bd.bd_id)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700444
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400445 def object_id(self) -> str:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700446 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
447
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400448 def query_vpp_config(self) -> bool:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700449 bds = self._test.vapi.gbp_bridge_domain_dump()
450 for bd in bds:
451 if bd.bd.bd_id == self.bd.bd_id:
452 return True
453 return False
454
455
456class VppGbpRouteDomain(VppObject):
457 """
458 GBP Route Domain
459 """
460
Neale Ranns160c9232019-06-19 06:25:56 -0700461 def __init__(self, test, rd_id, scope, t4, t6, ip4_uu=None, ip6_uu=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700462 self._test = test
463 self.rd_id = rd_id
Neale Ranns160c9232019-06-19 06:25:56 -0700464 self.scope = scope
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700465 self.t4 = t4
466 self.t6 = t6
467 self.ip4_uu = ip4_uu
468 self.ip6_uu = ip6_uu
469
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400470 def encode(self) -> dict:
471 return {
472 "rd_id": self.rd_id,
473 "scope": self.scope,
474 "ip4_table_id": self.t4.table_id,
475 "ip6_table_id": self.t6.table_id,
476 "ip4_uu_sw_if_index": self.ip4_uu.sw_if_index
477 if self.ip4_uu else INDEX_INVALID,
478 "ip6_uu_sw_if_index": self.ip6_uu.sw_if_index
479 if self.ip6_uu else INDEX_INVALID,
480
481 }
482
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700483 def add_vpp_config(self):
484 self._test.vapi.gbp_route_domain_add(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400485 rd=self.encode(),
486 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700487 self._test.registry.register(self, self._test.logger)
488
489 def remove_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400490 self._test.vapi.gbp_route_domain_del(rd_id=self.rd_id)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700491
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700492 def object_id(self):
493 return "gbp-route-domain:[%d]" % (self.rd_id)
494
495 def query_vpp_config(self):
496 rds = self._test.vapi.gbp_route_domain_dump()
497 for rd in rds:
498 if rd.rd.rd_id == self.rd_id:
499 return True
500 return False
501
502
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400503class VppGbpContractNextHop:
Neale Ranns13a08cc2018-11-07 09:25:54 -0800504 def __init__(self, mac, bd, ip, rd):
505 self.mac = mac
506 self.ip = ip
507 self.bd = bd
508 self.rd = rd
509
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400510 def encode(self) -> dict:
511 return {
512 "ip": self.ip,
513 "mac": self.mac.packed,
514 "bd_id": self.bd.bd.bd_id,
515 "rd_id": self.rd.rd_id,
516 }
Neale Ranns13a08cc2018-11-07 09:25:54 -0800517
518
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400519class VppGbpContractRule:
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400520 def __init__(self, action, hash_mode, nhs=None):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800521 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100522 self.hash_mode = hash_mode
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400523 self.nhs = [] if nhs is None else nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800524
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400525 def encode(self) -> dict:
Neale Ranns13a08cc2018-11-07 09:25:54 -0800526 nhs = []
527 for nh in self.nhs:
528 nhs.append(nh.encode())
529 while len(nhs) < 8:
530 nhs.append({})
531 return {'action': self.action,
532 'nh_set': {
533 'hash_mode': self.hash_mode,
534 'n_nhs': len(self.nhs),
535 'nhs': nhs}}
536
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400537 def __repr__(self):
538 return '<VppGbpContractRule action=%s, hash_mode=%s>' % (
539 self.action, self.hash_mode)
540
Neale Ranns13a08cc2018-11-07 09:25:54 -0800541
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800542class VppGbpContract(VppObject):
543 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200544 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800545 """
546
Neale Ranns160c9232019-06-19 06:25:56 -0700547 def __init__(self, test, scope, sclass, dclass, acl_index,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400548 rules: list, allowed_ethertypes: list):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800549 self._test = test
Neale Ranns160c9232019-06-19 06:25:56 -0700550 self.scope = scope
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800551 self.acl_index = acl_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700552 self.sclass = sclass
553 self.dclass = dclass
Neale Ranns13a08cc2018-11-07 09:25:54 -0800554 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800555 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700556 while (len(self.allowed_ethertypes) < 16):
557 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800558
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400559 def encode(self) -> dict:
Neale Ranns13a08cc2018-11-07 09:25:54 -0800560 rules = []
561 for r in self.rules:
562 rules.append(r.encode())
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400563 return {
564 'acl_index': self.acl_index,
565 'scope': self.scope,
566 'sclass': self.sclass,
567 'dclass': self.dclass,
568 'n_rules': len(rules),
569 'rules': rules,
570 'n_ether_types': len(self.allowed_ethertypes),
571 'allowed_ethertypes': self.allowed_ethertypes,
572 }
573
574 def add_vpp_config(self):
Neale Ranns796c84b2019-03-28 07:56:23 -0700575 r = self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400576 is_add=1,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400577 contract=self.encode()
578 )
579
Neale Ranns796c84b2019-03-28 07:56:23 -0700580 self.stats_index = r.stats_index
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800581 self._test.registry.register(self, self._test.logger)
582
583 def remove_vpp_config(self):
584 self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400585 is_add=0,
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400586 contract=self.encode(),
587 )
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800588
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800589 def object_id(self):
Neale Ranns160c9232019-06-19 06:25:56 -0700590 return "gbp-contract:[%d:%d:%d:%d]" % (self.scope,
591 self.sclass,
592 self.dclass,
593 self.acl_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800594
595 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700596 cs = self._test.vapi.gbp_contract_dump()
597 for c in cs:
Neale Ranns160c9232019-06-19 06:25:56 -0700598 if c.contract.scope == self.scope \
599 and c.contract.sclass == self.sclass \
600 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800601 return True
602 return False
603
Neale Ranns796c84b2019-03-28 07:56:23 -0700604 def get_drop_stats(self):
605 c = self._test.statistics.get_counter("/net/gbp/contract/drop")
606 return c[0][self.stats_index]
607
608 def get_permit_stats(self):
609 c = self._test.statistics.get_counter("/net/gbp/contract/permit")
610 return c[0][self.stats_index]
611
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800612
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700613class VppGbpVxlanTunnel(VppInterface):
614 """
615 GBP VXLAN tunnel
616 """
617
Neale Ranns8da9fc62019-03-04 14:08:11 -0800618 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700619 super(VppGbpVxlanTunnel, self).__init__(test)
620 self._test = test
621 self.vni = vni
622 self.bd_rd_id = bd_rd_id
623 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800624 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700625
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400626 def encode(self) -> dict:
627 return {
628 "vni": self.vni,
629 "mode": self.mode,
630 "bd_rd_id": self.bd_rd_id,
631 "src": self.src,
632 }
633
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700634 def add_vpp_config(self):
635 r = self._test.vapi.gbp_vxlan_tunnel_add(
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400636 tunnel=self.encode(),
637 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700638 self.set_sw_if_index(r.sw_if_index)
639 self._test.registry.register(self, self._test.logger)
640
641 def remove_vpp_config(self):
Paul Vinciguerradc22c832021-04-25 21:50:38 -0400642 self._test.vapi.gbp_vxlan_tunnel_del(vni=self.vni)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700643
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700644 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800645 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700646
647 def query_vpp_config(self):
648 return find_gbp_vxlan(self._test, self.vni)
649
650
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +0000651@tag_fixme_vpp_workers
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800652class TestGBP(VppTestCase):
653 """ GBP Test Case """
654
Filip Vargadd1e3e72019-04-15 18:52:43 +0200655 @property
Filip Varga5f4f2082020-09-30 22:24:47 +0200656 def nat_config_flags(self):
Filip Vargadd1e3e72019-04-15 18:52:43 +0200657 return VppEnum.vl_api_nat_config_flags_t
658
Filip Varga5f4f2082020-09-30 22:24:47 +0200659 @property
660 def nat44_config_flags(self):
661 return VppEnum.vl_api_nat44_config_flags_t
662
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700663 @classmethod
664 def setUpClass(cls):
665 super(TestGBP, cls).setUpClass()
666
667 @classmethod
668 def tearDownClass(cls):
669 super(TestGBP, cls).tearDownClass()
670
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800671 def setUp(self):
672 super(TestGBP, self).setUp()
673
Neale Ranns25b04942018-04-04 09:34:50 -0700674 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700675 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700676
Ole Troan8006c6a2018-12-17 12:02:26 +0100677 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800678
679 for i in self.pg_interfaces:
680 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700681 for i in self.lo_interfaces:
682 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800683
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200684 self.vlan_100 = VppDot1QSubint(self, self.pg0, 100)
685 self.vlan_100.admin_up()
686 self.vlan_101 = VppDot1QSubint(self, self.pg0, 101)
687 self.vlan_101.admin_up()
688 self.vlan_102 = VppDot1QSubint(self, self.pg0, 102)
689 self.vlan_102.admin_up()
690
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800691 def tearDown(self):
692 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700693 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800694 super(TestGBP, self).tearDown()
Benoît Ganned51880c2019-09-03 18:17:38 +0200695 for i in self.lo_interfaces:
696 i.remove_vpp_config()
697 self.lo_interfaces = []
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200698 self.vlan_102.remove_vpp_config()
699 self.vlan_101.remove_vpp_config()
700 self.vlan_100.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800701
Neale Ranns25b04942018-04-04 09:34:50 -0700702 def send_and_expect_bridged(self, src, tx, dst):
703 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800704
Neale Ranns25b04942018-04-04 09:34:50 -0700705 for r in rx:
706 self.assertEqual(r[Ether].src, tx[0][Ether].src)
707 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
708 self.assertEqual(r[IP].src, tx[0][IP].src)
709 self.assertEqual(r[IP].dst, tx[0][IP].dst)
710 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800711
Neale Ranns25b04942018-04-04 09:34:50 -0700712 def send_and_expect_bridged6(self, src, tx, dst):
713 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800714
Neale Ranns25b04942018-04-04 09:34:50 -0700715 for r in rx:
716 self.assertEqual(r[Ether].src, tx[0][Ether].src)
717 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
718 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
719 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
720 return rx
721
722 def send_and_expect_routed(self, src, tx, dst, src_mac):
723 rx = self.send_and_expect(src, tx, dst)
724
725 for r in rx:
726 self.assertEqual(r[Ether].src, src_mac)
727 self.assertEqual(r[Ether].dst, dst.remote_mac)
728 self.assertEqual(r[IP].src, tx[0][IP].src)
729 self.assertEqual(r[IP].dst, tx[0][IP].dst)
730 return rx
731
Neale Ranns69a85b52019-06-14 07:49:50 +0000732 def send_and_expect_routed6(self, src, tx, dst, src_mac):
733 rx = self.send_and_expect(src, tx, dst)
734
735 for r in rx:
736 self.assertEqual(r[Ether].src, src_mac)
737 self.assertEqual(r[Ether].dst, dst.remote_mac)
738 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
739 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
740 return rx
741
Neale Ranns25b04942018-04-04 09:34:50 -0700742 def send_and_expect_natted(self, src, tx, dst, src_ip):
743 rx = self.send_and_expect(src, tx, dst)
744
745 for r in rx:
746 self.assertEqual(r[Ether].src, tx[0][Ether].src)
747 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
748 self.assertEqual(r[IP].src, src_ip)
749 self.assertEqual(r[IP].dst, tx[0][IP].dst)
750 return rx
751
Neale Ranns4a6d0232018-04-24 07:45:33 -0700752 def send_and_expect_natted6(self, src, tx, dst, src_ip):
753 rx = self.send_and_expect(src, tx, dst)
754
755 for r in rx:
756 self.assertEqual(r[Ether].src, tx[0][Ether].src)
757 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
758 self.assertEqual(r[IPv6].src, src_ip)
759 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
760 return rx
761
Neale Ranns25b04942018-04-04 09:34:50 -0700762 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
763 rx = self.send_and_expect(src, tx, dst)
764
765 for r in rx:
766 self.assertEqual(r[Ether].src, tx[0][Ether].src)
767 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
768 self.assertEqual(r[IP].dst, dst_ip)
769 self.assertEqual(r[IP].src, tx[0][IP].src)
770 return rx
771
Neale Ranns4a6d0232018-04-24 07:45:33 -0700772 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
773 rx = self.send_and_expect(src, tx, dst)
774
775 for r in rx:
776 self.assertEqual(r[Ether].src, tx[0][Ether].src)
777 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
778 self.assertEqual(r[IPv6].dst, dst_ip)
779 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
780 return rx
781
Neale Ranns25b04942018-04-04 09:34:50 -0700782 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
783 rx = self.send_and_expect(src, tx, dst)
784
785 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100786 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700787 self.assertEqual(r[Ether].dst, dst.remote_mac)
788 self.assertEqual(r[IP].dst, dst_ip)
789 self.assertEqual(r[IP].src, src_ip)
790 return rx
791
Neale Ranns4a6d0232018-04-24 07:45:33 -0700792 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
793 rx = self.send_and_expect(src, tx, dst)
794
795 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100796 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700797 self.assertEqual(r[Ether].dst, dst.remote_mac)
798 self.assertEqual(r[IPv6].dst, dst_ip)
799 self.assertEqual(r[IPv6].src, src_ip)
800 return rx
801
Mohsin Kazmife52dea2019-04-18 15:54:58 +0200802 def send_and_expect_no_arp(self, src, tx, dst):
803 self.pg_send(src, tx)
804 dst.get_capture(0, timeout=1)
805 dst.assert_nothing_captured(remark="")
Mohsin Kazmife52dea2019-04-18 15:54:58 +0200806
807 def send_and_expect_arp(self, src, tx, dst):
808 rx = self.send_and_expect(src, tx, dst)
809
810 for r in rx:
811 self.assertEqual(r[Ether].src, tx[0][Ether].src)
812 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
813 self.assertEqual(r[ARP].psrc, tx[0][ARP].psrc)
814 self.assertEqual(r[ARP].pdst, tx[0][ARP].pdst)
815 self.assertEqual(r[ARP].hwsrc, tx[0][ARP].hwsrc)
816 self.assertEqual(r[ARP].hwdst, tx[0][ARP].hwdst)
817 return rx
818
Neale Ranns25b04942018-04-04 09:34:50 -0700819 def test_gbp(self):
820 """ Group Based Policy """
821
Neale Rannsb6a47952018-11-21 05:44:35 -0800822 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
823
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800824 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700825 # Route Domains
826 #
827 gt4 = VppIpTable(self, 0)
828 gt4.add_vpp_config()
829 gt6 = VppIpTable(self, 0, is_ip6=True)
830 gt6.add_vpp_config()
831 nt4 = VppIpTable(self, 20)
832 nt4.add_vpp_config()
833 nt6 = VppIpTable(self, 20, is_ip6=True)
834 nt6.add_vpp_config()
835
Neale Ranns160c9232019-06-19 06:25:56 -0700836 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
837 rd20 = VppGbpRouteDomain(self, 20, 420, nt4, nt6, None, None)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700838
839 rd0.add_vpp_config()
840 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700841
842 #
Neale Ranns160c9232019-06-19 06:25:56 -0700843 # Bridge Domains
844 #
845 bd1 = VppBridgeDomain(self, 1)
846 bd2 = VppBridgeDomain(self, 2)
847 bd20 = VppBridgeDomain(self, 20)
848
849 bd1.add_vpp_config()
850 bd2.add_vpp_config()
851 bd20.add_vpp_config()
852
853 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
854 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
855 gbd20 = VppGbpBridgeDomain(self, bd20, rd20, self.loop2)
856
857 gbd1.add_vpp_config()
858 gbd2.add_vpp_config()
859 gbd20.add_vpp_config()
860
861 #
Neale Ranns25b04942018-04-04 09:34:50 -0700862 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700863 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
864 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000865 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
866 self.pg4, self.loop0,
867 "10.0.0.128", "2001:10::128"),
868 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
869 self.pg5, self.loop0,
870 "10.0.1.128", "2001:10:1::128"),
871 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
872 self.pg6, self.loop1,
873 "10.0.2.128", "2001:10:2::128"),
874 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
875 self.pg7, self.loop2,
876 "11.0.0.128", "3001::128"),
877 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
878 self.pg8, self.loop2,
879 "11.0.0.129", "3001::129")]
880 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
881 VppGbpRecirc(self, epgs[1], self.loop4),
882 VppGbpRecirc(self, epgs[2], self.loop5),
883 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
884 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700885
886 epg_nat = epgs[3]
887 recirc_nat = recircs[3]
888
889 #
890 # 4 end-points, 2 in the same subnet, 3 in the same BD
891 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700892 eps = [VppGbpEndpoint(self, self.pg0,
893 epgs[0], recircs[0],
894 "10.0.0.1", "11.0.0.1",
895 "2001:10::1", "3001::1"),
896 VppGbpEndpoint(self, self.pg1,
897 epgs[0], recircs[0],
898 "10.0.0.2", "11.0.0.2",
899 "2001:10::2", "3001::2"),
900 VppGbpEndpoint(self, self.pg2,
901 epgs[1], recircs[1],
902 "10.0.1.1", "11.0.0.3",
903 "2001:10:1::1", "3001::3"),
904 VppGbpEndpoint(self, self.pg3,
905 epgs[2], recircs[2],
906 "10.0.2.1", "11.0.0.4",
907 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700908
Filip Vargae7a80a92021-02-26 09:31:21 +0100909 self.vapi.nat44_ed_plugin_enable_disable(enable=1)
Filip Vargaed2ee5e2021-03-23 12:57:58 +0100910 self.vapi.nat66_plugin_enable_disable(enable=1)
Filip Varga5f4f2082020-09-30 22:24:47 +0200911
Neale Ranns25b04942018-04-04 09:34:50 -0700912 #
913 # Config related to each of the EPGs
914 #
915 for epg in epgs:
916 # IP config on the BVI interfaces
917 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns59f71132020-04-08 12:19:38 +0000918 b4 = VppIpInterfaceBind(self, epg.bvi,
919 epg.rd.t4).add_vpp_config()
920 b6 = VppIpInterfaceBind(self, epg.bvi,
921 epg.rd.t6).add_vpp_config()
Benoît Gannea03d25d2019-09-03 17:54:21 +0200922 epg.bvi.set_mac(self.router_mac)
Neale Ranns25b04942018-04-04 09:34:50 -0700923
924 # The BVIs are NAT inside interfaces
Filip Varga5f4f2082020-09-30 22:24:47 +0200925 flags = self.nat_config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +0200926 self.vapi.nat44_interface_add_del_feature(
927 sw_if_index=epg.bvi.sw_if_index,
928 flags=flags, is_add=1)
929 self.vapi.nat66_add_del_interface(
Filip Vargaed2ee5e2021-03-23 12:57:58 +0100930 sw_if_index=epg.bvi.sw_if_index,
931 flags=flags, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700932
Neale Ranns59f71132020-04-08 12:19:38 +0000933 if_ip4 = VppIpInterfaceAddress(self, epg.bvi,
934 epg.bvi_ip4, 32,
935 bind=b4).add_vpp_config()
936 if_ip6 = VppIpInterfaceAddress(self, epg.bvi,
937 epg.bvi_ip6, 128,
938 bind=b6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700939
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700940 # EPG uplink interfaces in the RD
941 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
942 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700943
944 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700945 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100946 str(self.router_mac),
Neale Rannsefd7bc22019-11-11 08:32:34 +0000947 epg.bvi_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700948 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100949 str(self.router_mac),
Neale Rannsefd7bc22019-11-11 08:32:34 +0000950 epg.bvi_ip6)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700951 epg.bd_arp_ip4.add_vpp_config()
952 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700953
954 # EPG in VPP
955 epg.add_vpp_config()
956
957 for recirc in recircs:
958 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700959 VppIpInterfaceBind(self, recirc.recirc,
960 recirc.epg.rd.t4).add_vpp_config()
961 VppIpInterfaceBind(self, recirc.recirc,
962 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700963
Neale Ranns4a6d0232018-04-24 07:45:33 -0700964 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200965 sw_if_index=recirc.recirc.sw_if_index, is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700966 self.vapi.nat66_add_del_interface(
Filip Vargaed2ee5e2021-03-23 12:57:58 +0100967 sw_if_index=recirc.recirc.sw_if_index, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700968
969 recirc.add_vpp_config()
970
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700971 for recirc in recircs:
972 self.assertTrue(find_bridge_domain_port(self,
973 recirc.epg.bd.bd.bd_id,
974 recirc.recirc.sw_if_index))
975
Neale Ranns25b04942018-04-04 09:34:50 -0700976 for ep in eps:
977 self.pg_enable_capture(self.pg_interfaces)
978 self.pg_start()
979 #
980 # routes to the endpoints. We need these since there are no
981 # adj-fibs due to the fact the the BVI address has /32 and
982 # the subnet is not attached.
983 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700984 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700985 # Add static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsefd7bc22019-11-11 08:32:34 +0000986 if ip_address(ip).version == 4:
Filip Varga5f4f2082020-09-30 22:24:47 +0200987 flags = self.nat_config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +0200988 self.vapi.nat44_add_del_static_mapping(
989 is_add=1,
Neale Rannsefd7bc22019-11-11 08:32:34 +0000990 local_ip_address=ip,
991 external_ip_address=fip,
Filip Vargaf4749ca2019-04-25 14:55:32 +0200992 external_sw_if_index=0xFFFFFFFF,
993 vrf_id=0,
994 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -0700995 else:
Filip Vargaf4749ca2019-04-25 14:55:32 +0200996 self.vapi.nat66_add_del_static_mapping(
Neale Rannsefd7bc22019-11-11 08:32:34 +0000997 local_ip_address=ip,
998 external_ip_address=fip,
Filip Vargaf4749ca2019-04-25 14:55:32 +0200999 vrf_id=0, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -07001000
Neale Ranns25b04942018-04-04 09:34:50 -07001001 # VPP EP create ...
1002 ep.add_vpp_config()
1003
Neale Rannsc0a93142018-09-05 15:42:26 -07001004 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -07001005
Neale Rannsc0a93142018-09-05 15:42:26 -07001006 # ... results in a Gratuitous ARP/ND on the EPG's uplink
1007 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
1008
1009 for ii, ip in enumerate(ep.ips):
1010 p = rx[ii]
1011
Neale Rannsefd7bc22019-11-11 08:32:34 +00001012 if ip_address(ip).version == 6:
Neale Rannsc0a93142018-09-05 15:42:26 -07001013 self.assertTrue(p.haslayer(ICMPv6ND_NA))
Neale Rannsefd7bc22019-11-11 08:32:34 +00001014 self.assertEqual(p[ICMPv6ND_NA].tgt, ip)
Neale Rannsc0a93142018-09-05 15:42:26 -07001015 else:
1016 self.assertTrue(p.haslayer(ARP))
Neale Rannsefd7bc22019-11-11 08:32:34 +00001017 self.assertEqual(p[ARP].psrc, ip)
1018 self.assertEqual(p[ARP].pdst, ip)
Neale Ranns25b04942018-04-04 09:34:50 -07001019
1020 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -07001021 for fip in ep.fips:
Neale Rannsbc764c82019-06-19 07:07:13 -07001022 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001023 fip)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001024 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001025
Neale Rannsc0a93142018-09-05 15:42:26 -07001026 # floating IPs route via EPG recirc
Neale Ranns097fa662018-05-01 05:17:55 -07001027 r = VppIpRoute(
Neale Rannsefd7bc22019-11-11 08:32:34 +00001028 self, fip, ip_address(fip).max_prefixlen,
1029 [VppRoutePath(fip,
Neale Ranns097fa662018-05-01 05:17:55 -07001030 ep.recirc.recirc.sw_if_index,
1031 type=FibPathType.FIB_PATH_TYPE_DVR,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001032 proto=get_dpo_proto(fip))],
Neale Ranns097fa662018-05-01 05:17:55 -07001033 table_id=20)
Neale Rannsc0a93142018-09-05 15:42:26 -07001034 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001035
1036 # L2 FIB entries in the NAT EPG BD to bridge the packets from
1037 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001038 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
1039 ep.recirc.recirc, bvi_mac=0)
1040 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001041
1042 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001043 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -07001044 #
1045 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
1046 src=self.pg0.remote_mac) /
1047 ARP(op="who-has",
1048 hwdst="ff:ff:ff:ff:ff:ff",
1049 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001050 pdst="10.0.0.88",
1051 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -07001052
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001053 self.vapi.cli("clear trace")
1054 self.pg0.add_stream(pkt_arp)
1055
1056 self.pg_enable_capture(self.pg_interfaces)
1057 self.pg_start()
1058
1059 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -07001060
1061 #
1062 # ARP/ND packets get a response
1063 #
1064 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
1065 src=self.pg0.remote_mac) /
1066 ARP(op="who-has",
1067 hwdst="ff:ff:ff:ff:ff:ff",
1068 hwsrc=self.pg0.remote_mac,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001069 pdst=epgs[0].bvi_ip4,
1070 psrc=eps[0].ip4))
Neale Ranns25b04942018-04-04 09:34:50 -07001071
1072 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
1073
Neale Rannsefd7bc22019-11-11 08:32:34 +00001074 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001075 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001076 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
1077 src=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001078 IPv6(dst=d, src=eps[0].ip6) /
1079 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) /
Neale Ranns25b04942018-04-04 09:34:50 -07001080 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
1081 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
1082
1083 #
1084 # broadcast packets are flooded
1085 #
1086 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
1087 src=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001088 IP(src=eps[0].ip4, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001089 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001090 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001091
1092 self.vapi.cli("clear trace")
1093 self.pg0.add_stream(pkt_bcast)
1094
1095 self.pg_enable_capture(self.pg_interfaces)
1096 self.pg_start()
1097
1098 rxd = eps[1].itf.get_capture(1)
1099 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1100 rxd = epgs[0].uplink.get_capture(1)
1101 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1102
1103 #
1104 # packets to non-local L3 destinations dropped
1105 #
1106 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001107 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001108 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001109 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001110 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001111 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001112 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001113 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001114 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001115 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001116 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001117 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001118
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001119 self.send_and_assert_no_replies(self.pg0,
1120 pkt_intra_epg_220_ip4 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001121
1122 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001123 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001124 IPv6(src=eps[0].ip6,
Neale Rannsc0a93142018-09-05 15:42:26 -07001125 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001126 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001127 Raw(b'\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001128 self.send_and_assert_no_replies(self.pg0,
1129 pkt_inter_epg_222_ip6 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001130
1131 #
1132 # Add the subnet routes
1133 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001134 s41 = VppGbpSubnet(
1135 self, rd0, "10.0.0.0", 24,
1136 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1137 s42 = VppGbpSubnet(
1138 self, rd0, "10.0.1.0", 24,
1139 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1140 s43 = VppGbpSubnet(
1141 self, rd0, "10.0.2.0", 24,
1142 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1143 s61 = VppGbpSubnet(
1144 self, rd0, "2001:10::1", 64,
1145 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1146 s62 = VppGbpSubnet(
1147 self, rd0, "2001:10:1::1", 64,
1148 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1149 s63 = VppGbpSubnet(
1150 self, rd0, "2001:10:2::1", 64,
1151 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001152 s41.add_vpp_config()
1153 s42.add_vpp_config()
1154 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001155 s61.add_vpp_config()
1156 s62.add_vpp_config()
1157 s63.add_vpp_config()
1158
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001159 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001160 pkt_intra_epg_220_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001161 eps[0].epg.uplink)
1162 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001163 pkt_inter_epg_222_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001164 eps[0].epg.uplink)
1165 self.send_and_expect_bridged6(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001166 pkt_inter_epg_222_ip6 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001167 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001168
1169 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1170 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1171 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1172 self.logger.info(self.vapi.cli("sh gbp recirc"))
1173 self.logger.info(self.vapi.cli("sh int"))
1174 self.logger.info(self.vapi.cli("sh int addr"))
1175 self.logger.info(self.vapi.cli("sh int feat loop6"))
1176 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1177 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001178 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001179
1180 #
1181 # Packet destined to unknown unicast is sent on the epg uplink ...
1182 #
1183 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1184 dst="00:00:00:33:44:55") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001185 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001186 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001187 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001188 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001189
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001190 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001191 pkt_intra_epg_220_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001192 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001193 # ... and nowhere else
1194 self.pg1.get_capture(0, timeout=0.1)
1195 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1196
1197 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1198 dst="00:00:00:33:44:66") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001199 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001200 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001201 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001202 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001203
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001204 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001205 pkt_intra_epg_221_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001206 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001207
1208 #
1209 # Packets from the uplink are forwarded in the absence of a contract
1210 #
1211 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1212 dst=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001213 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001214 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001215 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001216 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001217
1218 self.send_and_expect_bridged(self.pg4,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001219 pkt_intra_epg_220_from_uplink * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001220 self.pg0)
1221
1222 #
1223 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001224 # can communicate
1225 #
1226 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001227 dst=self.pg1.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001228 IP(src=eps[0].ip4,
1229 dst=eps[1].ip4) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001230 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001231 Raw(b'\xa5' * 100))
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001232
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001233 self.send_and_expect_bridged(self.pg0,
1234 pkt_intra_epg * NUM_PKTS,
1235 self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001236
1237 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001238 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001239 # cannot communicate
1240 #
1241 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001242 dst=self.pg2.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001243 IP(src=eps[0].ip4,
1244 dst=eps[2].ip4) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001245 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001246 Raw(b'\xa5' * 100))
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001247 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001248 dst=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001249 IP(src=eps[2].ip4,
1250 dst=eps[0].ip4) /
Neale Ranns25b04942018-04-04 09:34:50 -07001251 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001252 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001253 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001254 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001255 IP(src=eps[0].ip4,
1256 dst=eps[3].ip4) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001257 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001258 Raw(b'\xa5' * 100))
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001259
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001260 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001261 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001262 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001263 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001264
1265 #
1266 # A uni-directional contract from EPG 220 -> 221
1267 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001268 rule = AclRule(is_permit=1, proto=17)
1269 rule2 = AclRule(src_prefix=IPv6Network((0, 0)),
1270 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
1271 acl = VppAcl(self, rules=[rule, rule2])
1272 acl.add_vpp_config()
1273
Neale Ranns13a08cc2018-11-07 09:25:54 -08001274 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001275 self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001276 [VppGbpContractRule(
1277 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001278 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001279 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001280 VppGbpContractRule(
1281 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001282 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001283 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001284 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001285 c1.add_vpp_config()
1286
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001287 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001288 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001289 eps[2].itf)
1290 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001291 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001292
1293 #
1294 # contract for the return direction
1295 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001296 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001297 self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001298 [VppGbpContractRule(
1299 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001300 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001301 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001302 VppGbpContractRule(
1303 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001304 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001305 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001306 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001307 c2.add_vpp_config()
1308
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001309 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001310 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001311 eps[2].itf)
1312 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001313 pkt_inter_epg_221_to_220 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001314 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001315
Neale Ranns796c84b2019-03-28 07:56:23 -07001316 ds = c2.get_drop_stats()
1317 self.assertEqual(ds['packets'], 0)
1318 ps = c2.get_permit_stats()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001319 self.assertEqual(ps['packets'], NUM_PKTS)
Neale Ranns796c84b2019-03-28 07:56:23 -07001320
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001321 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001322 # the contract does not allow non-IP
1323 #
1324 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1325 dst=self.pg2.remote_mac) /
1326 ARP())
1327 self.send_and_assert_no_replies(eps[0].itf,
1328 pkt_non_ip_inter_epg_220_to_221 * 17)
1329
1330 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001331 # check that inter group is still disabled for the groups
1332 # not in the contract.
1333 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001334 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001335 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001336
Neale Ranns25b04942018-04-04 09:34:50 -07001337 #
1338 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1339 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001340 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001341 self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001342 [VppGbpContractRule(
1343 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001344 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001345 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001346 VppGbpContractRule(
1347 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001348 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001349 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001350 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001351 c3.add_vpp_config()
1352
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001353 self.logger.info(self.vapi.cli("sh gbp contract"))
1354
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001355 self.send_and_expect_routed(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001356 pkt_inter_epg_220_to_222 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001357 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001358 str(self.router_mac))
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001359 #
1360 # remove both contracts, traffic stops in both directions
1361 #
1362 c2.remove_vpp_config()
1363 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001364 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001365 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001366
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001367 self.send_and_assert_no_replies(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001368 pkt_inter_epg_221_to_220 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001369 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001370 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001371 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001372 pkt_intra_epg * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001373 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001374
1375 #
Neale Ranns25b04942018-04-04 09:34:50 -07001376 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001377 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001378
Neale Ranns25b04942018-04-04 09:34:50 -07001379 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001380 se1 = VppGbpSubnet(
1381 self, rd0, "0.0.0.0", 0,
1382 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1383 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001384 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001385 se2 = VppGbpSubnet(
1386 self, rd0, "11.0.0.0", 8,
1387 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1388 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001389 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001390 se16 = VppGbpSubnet(
1391 self, rd0, "::", 0,
1392 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1393 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001394 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001395 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001396 se3 = VppGbpSubnet(
1397 self, rd20, "0.0.0.0", 0,
1398 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1399 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001400 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001401 se36 = VppGbpSubnet(
1402 self, rd20, "::", 0,
1403 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1404 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001405 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001406 se4 = VppGbpSubnet(
1407 self, rd20, "11.0.0.0", 8,
1408 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1409 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001410 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001411 se1.add_vpp_config()
1412 se2.add_vpp_config()
1413 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001414 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001415 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001416 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001417
Neale Ranns25b04942018-04-04 09:34:50 -07001418 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1419 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001420 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1421 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001422 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001423
Neale Ranns4a6d0232018-04-24 07:45:33 -07001424 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001425 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001426 #
Neale Ranns25b04942018-04-04 09:34:50 -07001427 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001428 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001429 IP(src=eps[0].ip4,
Neale Rannsc0a93142018-09-05 15:42:26 -07001430 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001431 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001432 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001433
1434 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001435 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001436 pkt_inter_epg_220_to_global * NUM_PKTS)
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001437 rule = AclRule(is_permit=1, proto=17, ports=1234)
1438 rule2 = AclRule(is_permit=1, proto=17, ports=1234,
1439 src_prefix=IPv6Network((0, 0)),
1440 dst_prefix=IPv6Network((0, 0)))
1441 acl2 = VppAcl(self, rules=[rule, rule2])
1442 acl2.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001443
Neale Ranns13a08cc2018-11-07 09:25:54 -08001444 c4 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001445 self, 400, epgs[0].sclass, epgs[3].sclass, acl2.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001446 [VppGbpContractRule(
1447 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001448 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001449 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001450 VppGbpContractRule(
1451 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001452 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001453 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001454 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001455 c4.add_vpp_config()
1456
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001457 self.send_and_expect_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001458 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001459 self.pg7,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001460 eps[0].fip4)
Neale Ranns25b04942018-04-04 09:34:50 -07001461
Neale Ranns4a6d0232018-04-24 07:45:33 -07001462 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001463 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001464 IPv6(src=eps[0].ip6,
Neale Rannsc0a93142018-09-05 15:42:26 -07001465 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001466 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001467 Raw(b'\xa5' * 100))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001468
1469 self.send_and_expect_natted6(self.pg0,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001470 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001471 self.pg7,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001472 eps[0].fip6)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001473 #
1474 # From a global address to an EP: OUT2IN
1475 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001476 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001477 dst=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001478 IP(dst=eps[0].fip4,
Neale Ranns25b04942018-04-04 09:34:50 -07001479 src="1.1.1.1") /
1480 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001481 Raw(b'\xa5' * 100))
Neale Ranns25b04942018-04-04 09:34:50 -07001482
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001483 self.send_and_assert_no_replies(
1484 self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001485
Neale Ranns13a08cc2018-11-07 09:25:54 -08001486 c5 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001487 self, 400, epgs[3].sclass, epgs[0].sclass, acl2.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001488 [VppGbpContractRule(
1489 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001490 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001491 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001492 VppGbpContractRule(
1493 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001494 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001495 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001496 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001497 c5.add_vpp_config()
1498
1499 self.send_and_expect_unnatted(self.pg7,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001500 pkt_inter_epg_220_from_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001501 eps[0].itf,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001502 eps[0].ip4)
Neale Ranns25b04942018-04-04 09:34:50 -07001503
Ole Troan8006c6a2018-12-17 12:02:26 +01001504 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001505 dst=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001506 IPv6(dst=eps[0].fip6,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001507 src="6001::1") /
1508 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001509 Raw(b'\xa5' * 100))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001510
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001511 self.send_and_expect_unnatted6(
1512 self.pg7,
1513 pkt_inter_epg_220_from_global * NUM_PKTS,
1514 eps[0].itf,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001515 eps[0].ip6)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001516
1517 #
1518 # From a local VM to another local VM using resp. public addresses:
1519 # IN2OUT2IN
1520 #
Neale Ranns25b04942018-04-04 09:34:50 -07001521 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001522 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001523 IP(src=eps[0].ip4,
1524 dst=eps[1].fip4) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001525 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001526 Raw(b'\xa5' * 100))
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001527
Neale Ranns4a6d0232018-04-24 07:45:33 -07001528 self.send_and_expect_double_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001529 pkt_intra_epg_220_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001530 eps[1].itf,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001531 eps[0].fip4,
1532 eps[1].ip4)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001533
Neale Rannsc0a93142018-09-05 15:42:26 -07001534 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001535 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001536 IPv6(src=eps[0].ip6,
1537 dst=eps[1].fip6) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001538 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001539 Raw(b'\xa5' * 100))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001540
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001541 self.send_and_expect_double_natted6(
1542 eps[0].itf,
1543 pkt_intra_epg_220_global * NUM_PKTS,
1544 eps[1].itf,
Neale Rannsefd7bc22019-11-11 08:32:34 +00001545 eps[0].fip6,
1546 eps[1].ip6)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001547
1548 #
Neale Ranns25b04942018-04-04 09:34:50 -07001549 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001550 #
Filip Vargae7a80a92021-02-26 09:31:21 +01001551 self.vapi.nat44_ed_plugin_enable_disable(enable=0)
Filip Vargaed2ee5e2021-03-23 12:57:58 +01001552 self.vapi.nat66_plugin_enable_disable(enable=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001553
Neale Ranns774356a2018-11-29 12:02:16 +00001554 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
Neale Ranns3eea9de2019-06-21 02:09:25 -07001555 tep=None, n_tries=100, s_time=1):
Benoît Ganne040d47c2020-04-16 16:57:00 +02001556 # only learnt EP can timeout
1557 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
1558 flags = ep_flags.GBP_API_ENDPOINT_FLAG_LEARNT
Neale Ranns774356a2018-11-29 12:02:16 +00001559 while (n_tries):
Benoît Ganne040d47c2020-04-16 16:57:00 +02001560 if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep,
1561 flags=flags):
Neale Ranns774356a2018-11-29 12:02:16 +00001562 return True
1563 n_tries = n_tries - 1
1564 self.sleep(s_time)
Benoît Ganne040d47c2020-04-16 16:57:00 +02001565 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep,
1566 flags=flags))
Neale Ranns774356a2018-11-29 12:02:16 +00001567 return False
1568
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001569 def test_gbp_learn_l2(self):
1570 """ GBP L2 Endpoint Learning """
1571
Neale Ranns69a85b52019-06-14 07:49:50 +00001572 drop_no_contract = self.statistics.get_err_counter(
1573 '/err/gbp-policy-port/drop-no-contract')
1574 allow_intra_class = self.statistics.get_err_counter(
1575 '/err/gbp-policy-port/allow-intra-sclass')
Neale Ranns796c84b2019-03-28 07:56:23 -07001576
Neale Rannsb6a47952018-11-21 05:44:35 -08001577 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001578 learnt = [{'mac': '00:00:11:11:11:01',
1579 'ip': '10.0.0.1',
1580 'ip6': '2001:10::2'},
1581 {'mac': '00:00:11:11:11:02',
1582 'ip': '10.0.0.2',
1583 'ip6': '2001:10::3'}]
1584
1585 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001586 # IP tables
1587 #
1588 gt4 = VppIpTable(self, 1)
1589 gt4.add_vpp_config()
1590 gt6 = VppIpTable(self, 1, is_ip6=True)
1591 gt6.add_vpp_config()
1592
Neale Ranns160c9232019-06-19 06:25:56 -07001593 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001594 rd1.add_vpp_config()
1595
1596 #
1597 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1598 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1599 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1600 #
1601 self.pg2.config_ip4()
1602 self.pg2.resolve_arp()
1603 self.pg2.generate_remote_hosts(4)
1604 self.pg2.configure_ipv4_neighbors()
1605 self.pg3.config_ip4()
1606 self.pg3.resolve_arp()
1607 self.pg4.config_ip4()
1608 self.pg4.resolve_arp()
1609
1610 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001611 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1612 #
1613 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1614 "239.1.1.1", 88,
1615 mcast_itf=self.pg4)
1616 tun_bm.add_vpp_config()
1617
1618 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001619 # a GBP bridge domain with a BVI and a UU-flood interface
1620 #
1621 bd1 = VppBridgeDomain(self, 1)
1622 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07001623 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
1624 self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001625 gbd1.add_vpp_config()
1626
1627 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1628 self.logger.info(self.vapi.cli("sh gbp bridge"))
1629
1630 # ... and has a /32 applied
1631 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1632 ip_addr.add_vpp_config()
1633
1634 #
1635 # The Endpoint-group in which we are learning endpoints
1636 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001637 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001638 None, self.loop0,
1639 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001640 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00001641 VppGbpEndpointRetention(4))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001642 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001643 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001644 None, self.loop1,
1645 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001646 "2001:11::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00001647 VppGbpEndpointRetention(4))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001648 epg_330.add_vpp_config()
1649
1650 #
1651 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001652 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001653 #
1654 vx_tun_l2_1 = VppGbpVxlanTunnel(
1655 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001656 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1657 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001658 vx_tun_l2_1.add_vpp_config()
1659
1660 #
1661 # A static endpoint that the learnt endpoints are trying to
1662 # talk to
1663 #
1664 ep = VppGbpEndpoint(self, self.pg0,
1665 epg_220, None,
1666 "10.0.0.127", "11.0.0.127",
1667 "2001:10::1", "3001::1")
1668 ep.add_vpp_config()
1669
Neale Rannsefd7bc22019-11-11 08:32:34 +00001670 self.assertTrue(find_route(self, ep.ip4, 32, table_id=1))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001671
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001672 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001673 p = (Ether(src=self.pg2.remote_mac,
1674 dst=self.pg2.local_mac) /
1675 IP(src=self.pg2.remote_hosts[0].ip4,
1676 dst=self.pg2.local_ip4) /
1677 UDP(sport=1234, dport=48879) /
1678 VXLAN(vni=99, gpid=88, flags=0x88) /
1679 Ether(src=learnt[0]["mac"], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001680 IP(src=learnt[0]["ip"], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001681 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001682 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001683
1684 self.send_and_assert_no_replies(self.pg2, p)
1685
Neale Ranns796c84b2019-03-28 07:56:23 -07001686 self.logger.info(self.vapi.cli("sh error"))
Neale Ranns69a85b52019-06-14 07:49:50 +00001687 self.assert_error_counter_equal(
1688 '/err/gbp-policy-port/drop-no-contract',
1689 drop_no_contract + 1)
Neale Ranns796c84b2019-03-28 07:56:23 -07001690
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001691 #
1692 # we should not have learnt a new tunnel endpoint, since
1693 # the EPG was not learnt.
1694 #
1695 self.assertEqual(INDEX_INVALID,
1696 find_vxlan_gbp_tunnel(self,
1697 self.pg2.local_ip4,
1698 self.pg2.remote_hosts[0].ip4,
1699 99))
1700
Neale Ranns69a85b52019-06-14 07:49:50 +00001701 # ep is not learnt, because the EPG is unknown
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001702 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1703
Neale Ranns8da9fc62019-03-04 14:08:11 -08001704 #
1705 # Learn new EPs from IP packets
1706 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001707 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001708 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001709 # arriving on an unknown TEP
1710 p = (Ether(src=self.pg2.remote_mac,
1711 dst=self.pg2.local_mac) /
1712 IP(src=self.pg2.remote_hosts[1].ip4,
1713 dst=self.pg2.local_ip4) /
1714 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001715 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001716 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001717 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001718 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001719 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001720
1721 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1722
1723 # the new TEP
1724 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1725 self,
1726 self.pg2.local_ip4,
1727 self.pg2.remote_hosts[1].ip4,
1728 99)
1729 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1730
1731 #
1732 # the EP is learnt via the learnt TEP
1733 # both from its MAC and its IP
1734 #
1735 self.assertTrue(find_gbp_endpoint(self,
1736 vx_tun_l2_1.sw_if_index,
1737 mac=l['mac']))
1738 self.assertTrue(find_gbp_endpoint(self,
1739 vx_tun_l2_1.sw_if_index,
1740 ip=l['ip']))
1741
Neale Ranns69a85b52019-06-14 07:49:50 +00001742 self.assert_error_counter_equal(
1743 '/err/gbp-policy-port/allow-intra-sclass',
1744 allow_intra_class + 2)
Neale Ranns796c84b2019-03-28 07:56:23 -07001745
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001746 self.logger.info(self.vapi.cli("show gbp endpoint"))
1747 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001748 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001749
1750 #
1751 # If we sleep for the threshold time, the learnt endpoints should
1752 # age out
1753 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001754 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001755 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1756 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001757
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001758 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001759 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1760 #
1761 for ii, l in enumerate(learnt):
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001762 # add some junk in the reserved field of the vxlan-header
1763 # next to the VNI. we should accept since reserved bits are
1764 # ignored on rx.
Neale Ranns8da9fc62019-03-04 14:08:11 -08001765 p = (Ether(src=self.pg2.remote_mac,
1766 dst=self.pg2.local_mac) /
1767 IP(src=self.pg2.remote_hosts[1].ip4,
1768 dst="239.1.1.1") /
1769 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001770 VXLAN(vni=88, reserved2=0x80, gpid=112, flags=0x88) /
Neale Ranns8da9fc62019-03-04 14:08:11 -08001771 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1772 ARP(op="who-has",
1773 psrc=l['ip'], pdst=l['ip'],
1774 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1775
1776 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1777
1778 # the new TEP
1779 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1780 self,
1781 self.pg2.local_ip4,
1782 self.pg2.remote_hosts[1].ip4,
1783 99)
1784 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1785
1786 #
1787 # the EP is learnt via the learnt TEP
1788 # both from its MAC and its IP
1789 #
1790 self.assertTrue(find_gbp_endpoint(self,
1791 vx_tun_l2_1.sw_if_index,
1792 mac=l['mac']))
1793 self.assertTrue(find_gbp_endpoint(self,
1794 vx_tun_l2_1.sw_if_index,
1795 ip=l['ip']))
1796
1797 #
1798 # wait for the learnt endpoints to age out
1799 #
1800 for l in learnt:
1801 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1802 mac=l['mac'])
1803
1804 #
1805 # Learn new EPs from L2 packets
1806 #
1807 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001808 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001809 # arriving on an unknown TEP
1810 p = (Ether(src=self.pg2.remote_mac,
1811 dst=self.pg2.local_mac) /
1812 IP(src=self.pg2.remote_hosts[1].ip4,
1813 dst=self.pg2.local_ip4) /
1814 UDP(sport=1234, dport=48879) /
1815 VXLAN(vni=99, gpid=112, flags=0x88) /
1816 Ether(src=l['mac'], dst=ep.mac) /
Ole Troan770a0de2019-11-07 13:52:21 +01001817 Raw(b'\xa5' * 100))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001818
1819 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1820
1821 # the new TEP
1822 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1823 self,
1824 self.pg2.local_ip4,
1825 self.pg2.remote_hosts[1].ip4,
1826 99)
1827 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1828
1829 #
1830 # the EP is learnt via the learnt TEP
1831 # both from its MAC and its IP
1832 #
1833 self.assertTrue(find_gbp_endpoint(self,
1834 vx_tun_l2_1.sw_if_index,
1835 mac=l['mac']))
1836
1837 self.logger.info(self.vapi.cli("show gbp endpoint"))
1838 self.logger.info(self.vapi.cli("show gbp vxlan"))
1839 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1840
1841 #
1842 # wait for the learnt endpoints to age out
1843 #
1844 for l in learnt:
1845 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1846 mac=l['mac'])
1847
1848 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001849 # repeat. the do not learn bit is set so the EPs are not learnt
1850 #
1851 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001852 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001853 p = (Ether(src=self.pg2.remote_mac,
1854 dst=self.pg2.local_mac) /
1855 IP(src=self.pg2.remote_hosts[1].ip4,
1856 dst=self.pg2.local_ip4) /
1857 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001858 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001859 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001860 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001861 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001862 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001863
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001864 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001865
1866 for l in learnt:
1867 self.assertFalse(find_gbp_endpoint(self,
1868 vx_tun_l2_1.sw_if_index,
1869 mac=l['mac']))
1870
1871 #
1872 # repeat
1873 #
1874 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001875 # a packet with an sclass from a known EPG
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001876 # set a reserved bit in addition to the G and I
1877 # reserved bits should not be checked on rx.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001878 p = (Ether(src=self.pg2.remote_mac,
1879 dst=self.pg2.local_mac) /
1880 IP(src=self.pg2.remote_hosts[1].ip4,
1881 dst=self.pg2.local_ip4) /
1882 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001883 VXLAN(vni=99, gpid=112, flags=0xc8) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001884 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001885 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001886 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001887 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001888
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001889 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001890
1891 self.assertTrue(find_gbp_endpoint(self,
1892 vx_tun_l2_1.sw_if_index,
1893 mac=l['mac']))
1894
1895 #
1896 # Static EP replies to dynamics
1897 #
1898 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1899 for l in learnt:
1900 p = (Ether(src=ep.mac, dst=l['mac']) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001901 IP(dst=l['ip'], src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001902 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001903 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001904
1905 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1906
1907 for rx in rxs:
1908 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1909 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1910 self.assertEqual(rx[UDP].dport, 48879)
1911 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001912 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001913 self.assertEqual(rx[VXLAN].vni, 99)
1914 self.assertTrue(rx[VXLAN].flags.G)
1915 self.assertTrue(rx[VXLAN].flags.Instance)
1916 self.assertTrue(rx[VXLAN].gpflags.A)
1917 self.assertFalse(rx[VXLAN].gpflags.D)
1918
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001919 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001920 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1921 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001922
1923 #
1924 # repeat in the other EPG
1925 # there's no contract between 220 and 330, but the A-bit is set
1926 # so the packet is cleared for delivery
1927 #
1928 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001929 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001930 p = (Ether(src=self.pg2.remote_mac,
1931 dst=self.pg2.local_mac) /
1932 IP(src=self.pg2.remote_hosts[1].ip4,
1933 dst=self.pg2.local_ip4) /
1934 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001935 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001936 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001937 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001938 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001939 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001940
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001941 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02001942
1943 self.assertTrue(find_gbp_endpoint(self,
1944 vx_tun_l2_1.sw_if_index,
1945 mac=l['mac']))
1946
1947 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001948 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001949 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001950 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001951 p = (Ether(src=ep.mac, dst=l['mac']) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001952 IP(dst=learnt[0]['ip'], src=ep.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08001953 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001954 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001955
Neale Ranns13a08cc2018-11-07 09:25:54 -08001956 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001957
1958 #
1959 # refresh the entries after the check for no replies above
1960 #
1961 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001962 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001963 p = (Ether(src=self.pg2.remote_mac,
1964 dst=self.pg2.local_mac) /
1965 IP(src=self.pg2.remote_hosts[1].ip4,
1966 dst=self.pg2.local_ip4) /
1967 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001968 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001969 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00001970 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001971 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001972 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001973
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001974 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001975
1976 self.assertTrue(find_gbp_endpoint(self,
1977 vx_tun_l2_1.sw_if_index,
1978 mac=l['mac']))
1979
1980 #
1981 # Add the contract so they can talk
1982 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001983 rule = AclRule(is_permit=1, proto=17)
1984 rule2 = AclRule(src_prefix=IPv6Network((0, 0)),
1985 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
1986 acl = VppAcl(self, rules=[rule, rule2])
1987 acl.add_vpp_config()
1988
Neale Ranns13a08cc2018-11-07 09:25:54 -08001989 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01001990 self, 401, epg_220.sclass, epg_330.sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001991 [VppGbpContractRule(
1992 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001993 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001994 []),
Neale Rannse28c87c2019-07-05 00:53:45 -07001995 VppGbpContractRule(
1996 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1997 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
1998 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001999 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002000 c1.add_vpp_config()
2001
2002 for l in learnt:
2003 p = (Ether(src=ep.mac, dst=l['mac']) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002004 IP(dst=l['ip'], src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002005 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002006 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002007
2008 self.send_and_expect(self.pg0, [p], self.pg2)
2009
2010 #
2011 # send UU packets from the local EP
2012 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002013 self.logger.info(self.vapi.cli("sh gbp bridge"))
Neale Rannse28c87c2019-07-05 00:53:45 -07002014 self.logger.info(self.vapi.cli("sh bridge-domain 1 detail"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002015 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002016 IP(dst="10.0.0.133", src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002017 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002018 Raw(b'\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08002019 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002020
2021 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2022
2023 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002024 IP(dst="10.0.0.133", src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002025 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002026 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002027 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
2028
Neale Ranns879d11c2019-01-21 23:34:18 -08002029 for rx in rxs:
2030 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2031 self.assertEqual(rx[IP].dst, "239.1.1.1")
2032 self.assertEqual(rx[UDP].dport, 48879)
2033 # the UDP source port is a random value for hashing
2034 self.assertEqual(rx[VXLAN].gpid, 112)
2035 self.assertEqual(rx[VXLAN].vni, 88)
2036 self.assertTrue(rx[VXLAN].flags.G)
2037 self.assertTrue(rx[VXLAN].flags.Instance)
2038 self.assertFalse(rx[VXLAN].gpflags.A)
2039 self.assertFalse(rx[VXLAN].gpflags.D)
2040
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002041 rule = AclRule(is_permit=1, proto=17)
2042 rule2 = AclRule(src_prefix=IPv6Network((0, 0)),
2043 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
2044 acl = VppAcl(self, rules=[rule, rule2])
2045 acl.add_vpp_config()
2046
Neale Rannse28c87c2019-07-05 00:53:45 -07002047 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002048 self, 401, epg_330.sclass, epg_220.sclass, acl.acl_index,
Neale Rannse28c87c2019-07-05 00:53:45 -07002049 [VppGbpContractRule(
2050 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2051 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2052 []),
2053 VppGbpContractRule(
2054 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2055 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2056 [])],
2057 [ETH_P_IP, ETH_P_IPV6])
2058 c2.add_vpp_config()
2059
2060 for l in learnt:
2061 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2062 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002063 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002064 # Check v6 Endpoints learning
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002065 #
2066 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002067 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002068 p = (Ether(src=self.pg2.remote_mac,
2069 dst=self.pg2.local_mac) /
2070 IP(src=self.pg2.remote_hosts[1].ip4,
2071 dst=self.pg2.local_ip4) /
2072 UDP(sport=1234, dport=48879) /
Neale Rannse28c87c2019-07-05 00:53:45 -07002073 VXLAN(vni=99, gpid=113, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002074 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002075 IPv6(src=l['ip6'], dst=ep.ip6) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002076 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002077 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002078
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002079 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Rannse28c87c2019-07-05 00:53:45 -07002080 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002081
Neale Rannse28c87c2019-07-05 00:53:45 -07002082 self.assertTrue(find_gbp_endpoint(
2083 self,
2084 vx_tun_l2_1.sw_if_index,
2085 ip=l['ip6'],
2086 tep=[self.pg2.local_ip4,
2087 self.pg2.remote_hosts[1].ip4]))
2088
2089 self.logger.info(self.vapi.cli("sh int"))
2090 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
2091 self.logger.info(self.vapi.cli("sh gbp vxlan"))
2092 self.logger.info(self.vapi.cli("sh gbp endpoint"))
2093 self.logger.info(self.vapi.cli("sh gbp interface"))
2094
2095 #
2096 # EP moves to a different TEP
2097 #
2098 for l in learnt:
2099 # a packet with an sclass from a known EPG
2100 p = (Ether(src=self.pg2.remote_mac,
2101 dst=self.pg2.local_mac) /
2102 IP(src=self.pg2.remote_hosts[2].ip4,
2103 dst=self.pg2.local_ip4) /
2104 UDP(sport=1234, dport=48879) /
2105 VXLAN(vni=99, gpid=113, flags=0x88) /
2106 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002107 IPv6(src=l['ip6'], dst=ep.ip6) /
Neale Rannse28c87c2019-07-05 00:53:45 -07002108 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002109 Raw(b'\xa5' * 100))
Neale Rannse28c87c2019-07-05 00:53:45 -07002110
2111 rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
2112 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
2113
2114 self.assertTrue(find_gbp_endpoint(
2115 self,
2116 vx_tun_l2_1.sw_if_index,
Neale Ranns6d1ba562019-07-10 01:14:58 -07002117 sclass=113,
Neale Rannse28c87c2019-07-05 00:53:45 -07002118 mac=l['mac'],
2119 tep=[self.pg2.local_ip4,
2120 self.pg2.remote_hosts[2].ip4]))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002121
2122 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002123 # v6 remote EP reachability
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002124 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002125 for l in learnt:
2126 p = (Ether(src=ep.mac, dst=l['mac']) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002127 IPv6(dst=l['ip6'], src=ep.ip6) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002128 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002129 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00002130
2131 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
2132
2133 for rx in rxs:
2134 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Rannse28c87c2019-07-05 00:53:45 -07002135 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns69a85b52019-06-14 07:49:50 +00002136 self.assertEqual(rx[UDP].dport, 48879)
2137 # the UDP source port is a random value for hashing
2138 self.assertEqual(rx[VXLAN].gpid, 112)
2139 self.assertEqual(rx[VXLAN].vni, 99)
2140 self.assertTrue(rx[VXLAN].flags.G)
2141 self.assertTrue(rx[VXLAN].flags.Instance)
2142 self.assertTrue(rx[VXLAN].gpflags.A)
2143 self.assertFalse(rx[VXLAN].gpflags.D)
2144 self.assertEqual(rx[IPv6].dst, l['ip6'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002145
2146 #
Neale Ranns6d1ba562019-07-10 01:14:58 -07002147 # EP changes sclass
2148 #
2149 for l in learnt:
2150 # a packet with an sclass from a known EPG
2151 p = (Ether(src=self.pg2.remote_mac,
2152 dst=self.pg2.local_mac) /
2153 IP(src=self.pg2.remote_hosts[2].ip4,
2154 dst=self.pg2.local_ip4) /
2155 UDP(sport=1234, dport=48879) /
2156 VXLAN(vni=99, gpid=112, flags=0x88) /
2157 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002158 IPv6(src=l['ip6'], dst=ep.ip6) /
Neale Ranns6d1ba562019-07-10 01:14:58 -07002159 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002160 Raw(b'\xa5' * 100))
Neale Ranns6d1ba562019-07-10 01:14:58 -07002161
2162 rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
2163 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
2164
2165 self.assertTrue(find_gbp_endpoint(
2166 self,
2167 vx_tun_l2_1.sw_if_index,
2168 mac=l['mac'],
2169 sclass=112,
2170 tep=[self.pg2.local_ip4,
2171 self.pg2.remote_hosts[2].ip4]))
2172
2173 #
2174 # check reachability and contract intra-epg
2175 #
2176 allow_intra_class = self.statistics.get_err_counter(
2177 '/err/gbp-policy-mac/allow-intra-sclass')
2178
2179 for l in learnt:
2180 p = (Ether(src=ep.mac, dst=l['mac']) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002181 IPv6(dst=l['ip6'], src=ep.ip6) /
Neale Ranns6d1ba562019-07-10 01:14:58 -07002182 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002183 Raw(b'\xa5' * 100))
Neale Ranns6d1ba562019-07-10 01:14:58 -07002184
2185 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
2186
2187 for rx in rxs:
2188 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2189 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
2190 self.assertEqual(rx[UDP].dport, 48879)
2191 self.assertEqual(rx[VXLAN].gpid, 112)
2192 self.assertEqual(rx[VXLAN].vni, 99)
2193 self.assertTrue(rx[VXLAN].flags.G)
2194 self.assertTrue(rx[VXLAN].flags.Instance)
2195 self.assertTrue(rx[VXLAN].gpflags.A)
2196 self.assertFalse(rx[VXLAN].gpflags.D)
2197 self.assertEqual(rx[IPv6].dst, l['ip6'])
2198
2199 allow_intra_class += NUM_PKTS
2200
2201 self.assert_error_counter_equal(
2202 '/err/gbp-policy-mac/allow-intra-sclass',
2203 allow_intra_class)
2204
2205 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002206 # clean up
2207 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002208 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002209 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2210 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002211 self.pg2.unconfig_ip4()
2212 self.pg3.unconfig_ip4()
2213 self.pg4.unconfig_ip4()
2214
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002215 def test_gbp_contract(self):
Neale Ranns69a85b52019-06-14 07:49:50 +00002216 """ GBP Contracts """
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002217
2218 #
Neale Ranns160c9232019-06-19 06:25:56 -07002219 # Route Domains
2220 #
2221 gt4 = VppIpTable(self, 0)
2222 gt4.add_vpp_config()
2223 gt6 = VppIpTable(self, 0, is_ip6=True)
2224 gt6.add_vpp_config()
2225
2226 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
2227
2228 rd0.add_vpp_config()
2229
2230 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002231 # Bridge Domains
2232 #
2233 bd1 = VppBridgeDomain(self, 1, arp_term=0)
2234 bd2 = VppBridgeDomain(self, 2, arp_term=0)
2235
2236 bd1.add_vpp_config()
2237 bd2.add_vpp_config()
2238
Neale Ranns160c9232019-06-19 06:25:56 -07002239 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
2240 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002241
2242 gbd1.add_vpp_config()
2243 gbd2.add_vpp_config()
2244
2245 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002246 # 3 EPGs, 2 of which share a BD.
2247 #
2248 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
2249 None, self.loop0,
2250 "10.0.0.128", "2001:10::128"),
2251 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
2252 None, self.loop0,
2253 "10.0.1.128", "2001:10:1::128"),
2254 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
2255 None, self.loop1,
2256 "10.0.2.128", "2001:10:2::128")]
2257 #
2258 # 4 end-points, 2 in the same subnet, 3 in the same BD
2259 #
2260 eps = [VppGbpEndpoint(self, self.pg0,
2261 epgs[0], None,
2262 "10.0.0.1", "11.0.0.1",
2263 "2001:10::1", "3001::1"),
2264 VppGbpEndpoint(self, self.pg1,
2265 epgs[0], None,
2266 "10.0.0.2", "11.0.0.2",
2267 "2001:10::2", "3001::2"),
2268 VppGbpEndpoint(self, self.pg2,
2269 epgs[1], None,
2270 "10.0.1.1", "11.0.0.3",
2271 "2001:10:1::1", "3001::3"),
2272 VppGbpEndpoint(self, self.pg3,
2273 epgs[2], None,
2274 "10.0.2.1", "11.0.0.4",
2275 "2001:10:2::1", "3001::4")]
2276
2277 #
2278 # Config related to each of the EPGs
2279 #
2280 for epg in epgs:
2281 # IP config on the BVI interfaces
2282 if epg != epgs[1]:
Neale Ranns59f71132020-04-08 12:19:38 +00002283 b4 = VppIpInterfaceBind(self, epg.bvi,
2284 epg.rd.t4).add_vpp_config()
2285 b6 = VppIpInterfaceBind(self, epg.bvi,
2286 epg.rd.t6).add_vpp_config()
Benoît Gannea03d25d2019-09-03 17:54:21 +02002287 epg.bvi.set_mac(self.router_mac)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002288
Neale Ranns59f71132020-04-08 12:19:38 +00002289 if_ip4 = VppIpInterfaceAddress(self, epg.bvi,
2290 epg.bvi_ip4, 32,
2291 bind=b4).add_vpp_config()
2292 if_ip6 = VppIpInterfaceAddress(self, epg.bvi,
2293 epg.bvi_ip6, 128,
2294 bind=b6).add_vpp_config()
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002295
2296 # add the BD ARP termination entry for BVI IP
2297 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
2298 str(self.router_mac),
Neale Rannsefd7bc22019-11-11 08:32:34 +00002299 epg.bvi_ip4)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002300 epg.bd_arp_ip4.add_vpp_config()
2301
2302 # EPG in VPP
2303 epg.add_vpp_config()
2304
2305 #
2306 # config ep
2307 #
2308 for ep in eps:
2309 ep.add_vpp_config()
2310
2311 self.logger.info(self.vapi.cli("show gbp endpoint"))
2312 self.logger.info(self.vapi.cli("show interface"))
2313 self.logger.info(self.vapi.cli("show br"))
2314
2315 #
2316 # Intra epg allowed without contract
2317 #
2318 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2319 dst=self.pg1.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002320 IP(src=eps[0].ip4,
2321 dst=eps[1].ip4) /
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002322 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002323 Raw(b'\xa5' * 100))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002324
2325 self.send_and_expect_bridged(self.pg0,
2326 pkt_intra_epg_220_to_220 * 65,
2327 self.pg1)
2328
Neale Ranns69a85b52019-06-14 07:49:50 +00002329 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2330 dst=self.pg1.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002331 IPv6(src=eps[0].ip6,
2332 dst=eps[1].ip6) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002333 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002334 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00002335
2336 self.send_and_expect_bridged6(self.pg0,
2337 pkt_intra_epg_220_to_220 * 65,
2338 self.pg1)
2339
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002340 #
2341 # Inter epg denied without contract
2342 #
2343 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
2344 dst=self.pg2.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002345 IP(src=eps[0].ip4,
2346 dst=eps[2].ip4) /
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002347 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002348 Raw(b'\xa5' * 100))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002349
2350 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221)
2351
2352 #
2353 # A uni-directional contract from EPG 220 -> 221
2354 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002355 rule = AclRule(is_permit=1, proto=17)
2356 rule2 = AclRule(src_prefix=IPv6Network((0, 0)),
2357 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
2358 rule3 = AclRule(is_permit=1, proto=1)
2359 acl = VppAcl(self, rules=[rule, rule2, rule3])
2360 acl.add_vpp_config()
2361
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002362 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002363 self, 400, epgs[0].sclass, epgs[1].sclass, acl.acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002364 [VppGbpContractRule(
2365 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002366 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002367 []),
2368 VppGbpContractRule(
2369 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002370 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns69a85b52019-06-14 07:49:50 +00002371 []),
2372 VppGbpContractRule(
2373 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2374 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002375 [])],
2376 [ETH_P_IP, ETH_P_IPV6])
2377 c1.add_vpp_config()
2378
2379 self.send_and_expect_bridged(eps[0].itf,
2380 pkt_inter_epg_220_to_221 * 65,
2381 eps[2].itf)
2382
2383 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
2384 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002385 IP(src=eps[0].ip4,
2386 dst=eps[3].ip4) /
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002387 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002388 Raw(b'\xa5' * 100))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002389 self.send_and_assert_no_replies(eps[0].itf,
2390 pkt_inter_epg_220_to_222 * 65)
2391
2392 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002393 # ping router IP in different BD
2394 #
2395 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2396 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002397 IP(src=eps[0].ip4,
2398 dst=epgs[1].bvi_ip4) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002399 ICMP(type='echo-request'))
2400
2401 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2402
2403 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2404 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002405 IPv6(src=eps[0].ip6,
2406 dst=epgs[1].bvi_ip6) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002407 ICMPv6EchoRequest())
2408
2409 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2410
2411 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002412 # contract for the return direction
2413 #
2414 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002415 self, 400, epgs[1].sclass, epgs[0].sclass, acl.acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002416 [VppGbpContractRule(
2417 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002418 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002419 []),
2420 VppGbpContractRule(
2421 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002422 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002423 [])],
2424 [ETH_P_IP, ETH_P_IPV6])
2425 c2.add_vpp_config()
2426
2427 self.send_and_expect_bridged(eps[0].itf,
2428 pkt_inter_epg_220_to_221 * 65,
2429 eps[2].itf)
2430 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2431 dst=self.pg0.remote_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002432 IP(src=eps[2].ip4,
2433 dst=eps[0].ip4) /
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002434 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002435 Raw(b'\xa5' * 100))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002436 self.send_and_expect_bridged(eps[2].itf,
2437 pkt_inter_epg_221_to_220 * 65,
2438 eps[0].itf)
Neale Ranns69a85b52019-06-14 07:49:50 +00002439 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2440 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002441 IP(src=eps[2].ip4,
2442 dst=eps[0].ip4) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002443 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002444 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00002445 self.send_and_expect_routed(eps[2].itf,
2446 pkt_inter_epg_221_to_220 * 65,
2447 eps[0].itf,
2448 str(self.router_mac))
2449 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2450 dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002451 IPv6(src=eps[2].ip6,
2452 dst=eps[0].ip6) /
Neale Ranns69a85b52019-06-14 07:49:50 +00002453 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002454 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00002455 self.send_and_expect_routed6(eps[2].itf,
2456 pkt_inter_epg_221_to_220 * 65,
2457 eps[0].itf,
2458 str(self.router_mac))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002459
2460 #
2461 # contract between 220 and 222 uni-direction
2462 #
2463 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01002464 self, 400, epgs[0].sclass, epgs[2].sclass, acl.acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002465 [VppGbpContractRule(
2466 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002467 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002468 []),
2469 VppGbpContractRule(
2470 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002471 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002472 [])],
2473 [ETH_P_IP, ETH_P_IPV6])
2474 c3.add_vpp_config()
2475
2476 self.send_and_expect(eps[0].itf,
2477 pkt_inter_epg_220_to_222 * 65,
2478 eps[3].itf)
2479
2480 c3.remove_vpp_config()
2481 c1.remove_vpp_config()
2482 c2.remove_vpp_config()
2483 acl.remove_vpp_config()
2484
Neale Ranns69a85b52019-06-14 07:49:50 +00002485 def test_gbp_bd_drop_flags(self):
2486 """ GBP BD drop flags """
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002487
2488 #
2489 # IP tables
2490 #
2491 gt4 = VppIpTable(self, 1)
2492 gt4.add_vpp_config()
2493 gt6 = VppIpTable(self, 1, is_ip6=True)
2494 gt6.add_vpp_config()
2495
Neale Ranns160c9232019-06-19 06:25:56 -07002496 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002497 rd1.add_vpp_config()
2498
2499 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002500 # a GBP bridge domain with a BVI only
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002501 #
2502 bd1 = VppBridgeDomain(self, 1)
2503 bd1.add_vpp_config()
2504
Neale Ranns69a85b52019-06-14 07:49:50 +00002505 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2506 None, None,
2507 uu_drop=True, bm_drop=True)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002508 gbd1.add_vpp_config()
2509
2510 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2511 self.logger.info(self.vapi.cli("sh gbp bridge"))
2512
2513 # ... and has a /32 applied
Neale Ranns59f71132020-04-08 12:19:38 +00002514 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi,
2515 "10.0.0.128", 32).add_vpp_config()
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002516
2517 #
2518 # The Endpoint-group
2519 #
2520 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2521 None, self.loop0,
2522 "10.0.0.128",
2523 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00002524 VppGbpEndpointRetention(3))
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002525 epg_220.add_vpp_config()
2526
2527 ep = VppGbpEndpoint(self, self.pg0,
2528 epg_220, None,
2529 "10.0.0.127", "11.0.0.127",
2530 "2001:10::1", "3001::1")
2531 ep.add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00002532
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002533 #
2534 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2535 # in bd
2536 #
2537 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2538 self.logger.info(self.vapi.cli("sh gbp bridge"))
2539 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002540 IP(dst="10.0.0.133", src=ep.ip4) /
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002541 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002542 Raw(b'\xa5' * 100))
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002543 self.send_and_assert_no_replies(ep.itf, [p_uu])
2544
2545 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002546 IP(dst="10.0.0.133", src=ep.ip4) /
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002547 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002548 Raw(b'\xa5' * 100))
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002549 self.send_and_assert_no_replies(ep.itf, [p_bm])
2550
2551 self.pg3.unconfig_ip4()
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002552
2553 self.logger.info(self.vapi.cli("sh int"))
2554
Neale Ranns69a85b52019-06-14 07:49:50 +00002555 def test_gbp_bd_arp_flags(self):
2556 """ GBP BD arp flags """
2557
2558 #
2559 # IP tables
2560 #
2561 gt4 = VppIpTable(self, 1)
2562 gt4.add_vpp_config()
2563 gt6 = VppIpTable(self, 1, is_ip6=True)
2564 gt6.add_vpp_config()
2565
2566 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
2567 rd1.add_vpp_config()
2568
2569 #
2570 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
2571 #
2572 self.pg4.config_ip4()
2573 self.pg4.resolve_arp()
2574
2575 #
2576 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
2577 #
2578 tun_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2579 "239.1.1.1", 88,
2580 mcast_itf=self.pg4)
2581 tun_uu.add_vpp_config()
2582
2583 #
2584 # a GBP bridge domain with a BVI and a UU-flood interface
2585 #
2586 bd1 = VppBridgeDomain(self, 1)
2587 bd1.add_vpp_config()
2588
2589 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2590 tun_uu, None,
2591 ucast_arp=True)
2592 gbd1.add_vpp_config()
2593
2594 # ... and has a /32 applied
Neale Ranns59f71132020-04-08 12:19:38 +00002595 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi,
2596 "10.0.0.128", 32).add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00002597
2598 #
2599 # The Endpoint-group
2600 #
2601 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2602 None, self.loop0,
2603 "10.0.0.128",
2604 "2001:10::128",
2605 VppGbpEndpointRetention(2))
2606 epg_220.add_vpp_config()
2607
2608 ep = VppGbpEndpoint(self, self.pg0,
2609 epg_220, None,
2610 "10.0.0.127", "11.0.0.127",
2611 "2001:10::1", "3001::1")
2612 ep.add_vpp_config()
2613
2614 #
2615 # send ARP packet from the local EP expect it on the uu interface
2616 #
2617 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2618 self.logger.info(self.vapi.cli("sh gbp bridge"))
2619 p_arp = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2620 ARP(op="who-has",
Neale Rannsefd7bc22019-11-11 08:32:34 +00002621 psrc=ep.ip4, pdst="10.0.0.99",
Neale Ranns69a85b52019-06-14 07:49:50 +00002622 hwsrc=ep.mac,
2623 hwdst="ff:ff:ff:ff:ff:ff"))
2624 self.send_and_expect(ep.itf, [p_arp], self.pg4)
2625
2626 self.pg4.unconfig_ip4()
2627
Neale Rannsc29c0af2018-11-07 04:21:12 -08002628 def test_gbp_learn_vlan_l2(self):
2629 """ GBP L2 Endpoint w/ VLANs"""
2630
Neale Rannsb6a47952018-11-21 05:44:35 -08002631 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002632 learnt = [{'mac': '00:00:11:11:11:01',
2633 'ip': '10.0.0.1',
2634 'ip6': '2001:10::2'},
2635 {'mac': '00:00:11:11:11:02',
2636 'ip': '10.0.0.2',
2637 'ip6': '2001:10::3'}]
2638
2639 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002640 # IP tables
2641 #
2642 gt4 = VppIpTable(self, 1)
2643 gt4.add_vpp_config()
2644 gt6 = VppIpTable(self, 1, is_ip6=True)
2645 gt6.add_vpp_config()
2646
Neale Ranns160c9232019-06-19 06:25:56 -07002647 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002648 rd1.add_vpp_config()
2649
2650 #
2651 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2652 #
2653 self.pg2.config_ip4()
2654 self.pg2.resolve_arp()
2655 self.pg2.generate_remote_hosts(4)
2656 self.pg2.configure_ipv4_neighbors()
2657 self.pg3.config_ip4()
2658 self.pg3.resolve_arp()
2659
2660 #
2661 # The EP will be on a vlan sub-interface
2662 #
2663 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2664 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002665 self.vapi.l2_interface_vlan_tag_rewrite(
2666 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2667 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002668
2669 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2670 self.pg3.remote_ip4, 116)
2671 bd_uu_fwd.add_vpp_config()
2672
2673 #
2674 # a GBP bridge domain with a BVI and a UU-flood interface
2675 # The BD is marked as do not learn, so no endpoints are ever
2676 # learnt in this BD.
2677 #
2678 bd1 = VppBridgeDomain(self, 1)
2679 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002680 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002681 learn=False)
2682 gbd1.add_vpp_config()
2683
2684 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2685 self.logger.info(self.vapi.cli("sh gbp bridge"))
2686
2687 # ... and has a /32 applied
Neale Ranns59f71132020-04-08 12:19:38 +00002688 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi,
2689 "10.0.0.128", 32).add_vpp_config()
Neale Rannsc29c0af2018-11-07 04:21:12 -08002690
2691 #
2692 # The Endpoint-group in which we are learning endpoints
2693 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002694 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002695 None, self.loop0,
2696 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002697 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00002698 VppGbpEndpointRetention(4))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002699 epg_220.add_vpp_config()
2700
2701 #
2702 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002703 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002704 #
2705 vx_tun_l2_1 = VppGbpVxlanTunnel(
2706 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002707 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2708 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002709 vx_tun_l2_1.add_vpp_config()
2710
2711 #
2712 # A static endpoint that the learnt endpoints are trying to
2713 # talk to
2714 #
2715 ep = VppGbpEndpoint(self, vlan_11,
2716 epg_220, None,
2717 "10.0.0.127", "11.0.0.127",
2718 "2001:10::1", "3001::1")
2719 ep.add_vpp_config()
2720
Neale Rannsefd7bc22019-11-11 08:32:34 +00002721 self.assertTrue(find_route(self, ep.ip4, 32, table_id=1))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002722
2723 #
2724 # Send to the static EP
2725 #
2726 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002727 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002728 # arriving on an unknown TEP
2729 p = (Ether(src=self.pg2.remote_mac,
2730 dst=self.pg2.local_mac) /
2731 IP(src=self.pg2.remote_hosts[1].ip4,
2732 dst=self.pg2.local_ip4) /
2733 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002734 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002735 Ether(src=l['mac'], dst=ep.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002736 IP(src=l['ip'], dst=ep.ip4) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002737 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002738 Raw(b'\xa5' * 100))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002739
2740 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2741
2742 #
2743 # packet to EP has the EP's vlan tag
2744 #
2745 for rx in rxs:
2746 self.assertEqual(rx[Dot1Q].vlan, 11)
2747
2748 #
2749 # the EP is not learnt since the BD setting prevents it
2750 # also no TEP too
2751 #
2752 self.assertFalse(find_gbp_endpoint(self,
2753 vx_tun_l2_1.sw_if_index,
2754 mac=l['mac']))
2755 self.assertEqual(INDEX_INVALID,
2756 find_vxlan_gbp_tunnel(
2757 self,
2758 self.pg2.local_ip4,
2759 self.pg2.remote_hosts[1].ip4,
2760 99))
2761
2762 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2763
2764 #
2765 # static to remotes
2766 # we didn't learn the remotes so they are sent to the UU-fwd
2767 #
2768 for l in learnt:
2769 p = (Ether(src=ep.mac, dst=l['mac']) /
2770 Dot1Q(vlan=11) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002771 IP(dst=l['ip'], src=ep.ip4) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002772 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002773 Raw(b'\xa5' * 100))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002774
2775 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2776
2777 for rx in rxs:
2778 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2779 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2780 self.assertEqual(rx[UDP].dport, 48879)
2781 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002782 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002783 self.assertEqual(rx[VXLAN].vni, 116)
2784 self.assertTrue(rx[VXLAN].flags.G)
2785 self.assertTrue(rx[VXLAN].flags.Instance)
2786 self.assertFalse(rx[VXLAN].gpflags.A)
2787 self.assertFalse(rx[VXLAN].gpflags.D)
2788
2789 self.pg2.unconfig_ip4()
2790 self.pg3.unconfig_ip4()
2791
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002792 def test_gbp_learn_l3(self):
2793 """ GBP L3 Endpoint Learning """
2794
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04002795 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08002796
Neale Rannsb6a47952018-11-21 05:44:35 -08002797 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002798 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2799 routed_src_mac = "00:22:bd:f8:19:ff"
2800
2801 learnt = [{'mac': '00:00:11:11:11:02',
2802 'ip': '10.0.1.2',
2803 'ip6': '2001:10::2'},
2804 {'mac': '00:00:11:11:11:03',
2805 'ip': '10.0.1.3',
2806 'ip6': '2001:10::3'}]
2807
2808 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002809 # IP tables
2810 #
2811 t4 = VppIpTable(self, 1)
2812 t4.add_vpp_config()
2813 t6 = VppIpTable(self, 1, True)
2814 t6.add_vpp_config()
2815
2816 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2817 self.pg4.remote_ip4, 114)
2818 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2819 self.pg4.remote_ip4, 116)
2820 tun_ip4_uu.add_vpp_config()
2821 tun_ip6_uu.add_vpp_config()
2822
Neale Ranns160c9232019-06-19 06:25:56 -07002823 rd1 = VppGbpRouteDomain(self, 2, 401, t4, t6, tun_ip4_uu, tun_ip6_uu)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002824 rd1.add_vpp_config()
2825
Ole Troan8006c6a2018-12-17 12:02:26 +01002826 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002827
2828 #
2829 # Bind the BVI to the RD
2830 #
Neale Ranns59f71132020-04-08 12:19:38 +00002831 b4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2832 b6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002833
2834 #
2835 # Pg2 hosts the vxlan tunnel
2836 # hosts on pg2 to act as TEPs
2837 # pg3 is BD uu-fwd
2838 # pg4 is RD uu-fwd
2839 #
2840 self.pg2.config_ip4()
2841 self.pg2.resolve_arp()
2842 self.pg2.generate_remote_hosts(4)
2843 self.pg2.configure_ipv4_neighbors()
2844 self.pg3.config_ip4()
2845 self.pg3.resolve_arp()
2846 self.pg4.config_ip4()
2847 self.pg4.resolve_arp()
2848
2849 #
2850 # a GBP bridge domain with a BVI and a UU-flood interface
2851 #
2852 bd1 = VppBridgeDomain(self, 1)
2853 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002854 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002855 gbd1.add_vpp_config()
2856
2857 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2858 self.logger.info(self.vapi.cli("sh gbp bridge"))
2859 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002860
2861 # ... and has a /32 and /128 applied
Neale Ranns59f71132020-04-08 12:19:38 +00002862 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi,
2863 "10.0.0.128", 32,
2864 bind=b4).add_vpp_config()
2865 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi,
2866 "2001:10::128", 128,
2867 bind=b6).add_vpp_config()
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002868
2869 #
2870 # The Endpoint-group in which we are learning endpoints
2871 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002872 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002873 None, self.loop0,
2874 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002875 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00002876 VppGbpEndpointRetention(4))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002877 epg_220.add_vpp_config()
2878
2879 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002880 # The VXLAN GBP tunnel is in L3 mode with learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002881 #
2882 vx_tun_l3 = VppGbpVxlanTunnel(
2883 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002884 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2885 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002886 vx_tun_l3.add_vpp_config()
2887
2888 #
2889 # A static endpoint that the learnt endpoints are trying to
2890 # talk to
2891 #
2892 ep = VppGbpEndpoint(self, self.pg0,
2893 epg_220, None,
2894 "10.0.0.127", "11.0.0.127",
2895 "2001:10::1", "3001::1")
2896 ep.add_vpp_config()
2897
2898 #
2899 # learn some remote IPv4 EPs
2900 #
2901 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002902 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002903 # arriving on an unknown TEP
2904 p = (Ether(src=self.pg2.remote_mac,
2905 dst=self.pg2.local_mac) /
2906 IP(src=self.pg2.remote_hosts[1].ip4,
2907 dst=self.pg2.local_ip4) /
2908 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002909 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002910 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002911 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002912 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002913 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002914
2915 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2916
2917 # the new TEP
2918 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2919 self,
2920 self.pg2.local_ip4,
2921 self.pg2.remote_hosts[1].ip4,
2922 vx_tun_l3.vni)
2923 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2924
2925 # endpoint learnt via the parent GBP-vxlan interface
2926 self.assertTrue(find_gbp_endpoint(self,
2927 vx_tun_l3._sw_if_index,
2928 ip=l['ip']))
2929
2930 #
2931 # Static IPv4 EP replies to learnt
2932 #
2933 for l in learnt:
2934 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002935 IP(dst=l['ip'], src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002936 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002937 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002938
Filip Vargaf4749ca2019-04-25 14:55:32 +02002939 rxs = self.send_and_expect(self.pg0, p * 1, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002940
2941 for rx in rxs:
2942 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2943 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2944 self.assertEqual(rx[UDP].dport, 48879)
2945 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002946 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002947 self.assertEqual(rx[VXLAN].vni, 101)
2948 self.assertTrue(rx[VXLAN].flags.G)
2949 self.assertTrue(rx[VXLAN].flags.Instance)
2950 self.assertTrue(rx[VXLAN].gpflags.A)
2951 self.assertFalse(rx[VXLAN].gpflags.D)
2952
2953 inner = rx[VXLAN].payload
2954
2955 self.assertEqual(inner[Ether].src, routed_src_mac)
2956 self.assertEqual(inner[Ether].dst, routed_dst_mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00002957 self.assertEqual(inner[IP].src, ep.ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002958 self.assertEqual(inner[IP].dst, l['ip'])
2959
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002960 for l in learnt:
2961 self.assertFalse(find_gbp_endpoint(self,
2962 tep1_sw_if_index,
2963 ip=l['ip']))
2964
2965 #
2966 # learn some remote IPv6 EPs
2967 #
2968 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002969 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002970 # arriving on an unknown TEP
2971 p = (Ether(src=self.pg2.remote_mac,
2972 dst=self.pg2.local_mac) /
2973 IP(src=self.pg2.remote_hosts[1].ip4,
2974 dst=self.pg2.local_ip4) /
2975 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002976 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002977 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00002978 IPv6(src=l['ip6'], dst=ep.ip6) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002979 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002980 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002981
2982 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2983
2984 # the new TEP
2985 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2986 self,
2987 self.pg2.local_ip4,
2988 self.pg2.remote_hosts[1].ip4,
2989 vx_tun_l3.vni)
2990 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2991
2992 self.logger.info(self.vapi.cli("show gbp bridge"))
2993 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2994 self.logger.info(self.vapi.cli("show gbp vxlan"))
2995 self.logger.info(self.vapi.cli("show int addr"))
2996
2997 # endpoint learnt via the TEP
2998 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2999
3000 self.logger.info(self.vapi.cli("show gbp endpoint"))
3001 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
3002
3003 #
3004 # Static EP replies to learnt
3005 #
3006 for l in learnt:
3007 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003008 IPv6(dst=l['ip6'], src=ep.ip6) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003009 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003010 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003011
Paul Vinciguerra4271c972019-05-14 13:25:49 -04003012 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003013
3014 for rx in rxs:
3015 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3016 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
3017 self.assertEqual(rx[UDP].dport, 48879)
3018 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003019 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003020 self.assertEqual(rx[VXLAN].vni, 101)
3021 self.assertTrue(rx[VXLAN].flags.G)
3022 self.assertTrue(rx[VXLAN].flags.Instance)
3023 self.assertTrue(rx[VXLAN].gpflags.A)
3024 self.assertFalse(rx[VXLAN].gpflags.D)
3025
3026 inner = rx[VXLAN].payload
3027
3028 self.assertEqual(inner[Ether].src, routed_src_mac)
3029 self.assertEqual(inner[Ether].dst, routed_dst_mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003030 self.assertEqual(inner[IPv6].src, ep.ip6)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003031 self.assertEqual(inner[IPv6].dst, l['ip6'])
3032
3033 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003034 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00003035 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003036
3037 #
3038 # Static sends to unknown EP with no route
3039 #
3040 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003041 IP(dst="10.0.0.99", src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003042 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003043 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003044
3045 self.send_and_assert_no_replies(self.pg0, [p])
3046
3047 #
3048 # Add a route to static EP's v4 and v6 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003049 #
3050 se_10_24 = VppGbpSubnet(
3051 self, rd1, "10.0.0.0", 24,
3052 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
3053 se_10_24.add_vpp_config()
3054
Neale Ranns69a85b52019-06-14 07:49:50 +00003055 #
3056 # static pings router
3057 #
3058 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003059 IP(dst=epg_220.bvi_ip4, src=ep.ip4) /
Neale Ranns69a85b52019-06-14 07:49:50 +00003060 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003061 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00003062
3063 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
3064
3065 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003066 IPv6(dst=epg_220.bvi_ip6, src=ep.ip6) /
Neale Ranns69a85b52019-06-14 07:49:50 +00003067 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003068 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00003069
3070 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
3071
3072 #
3073 # packets to address in the subnet are sent on the uu-fwd
3074 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003075 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003076 IP(dst="10.0.0.99", src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003077 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003078 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003079
3080 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
3081 for rx in rxs:
3082 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
3083 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
3084 self.assertEqual(rx[UDP].dport, 48879)
3085 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003086 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003087 self.assertEqual(rx[VXLAN].vni, 114)
3088 self.assertTrue(rx[VXLAN].flags.G)
3089 self.assertTrue(rx[VXLAN].flags.Instance)
3090 # policy is not applied to packets sent to the uu-fwd interfaces
3091 self.assertFalse(rx[VXLAN].gpflags.A)
3092 self.assertFalse(rx[VXLAN].gpflags.D)
3093
3094 #
3095 # learn some remote IPv4 EPs
3096 #
3097 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003098 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003099 # arriving on an unknown TEP
3100 p = (Ether(src=self.pg2.remote_mac,
3101 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003102 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003103 dst=self.pg2.local_ip4) /
3104 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003105 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003106 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003107 IP(src=l['ip'], dst=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003108 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003109 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003110
3111 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3112
3113 # the new TEP
3114 tep1_sw_if_index = find_vxlan_gbp_tunnel(
3115 self,
3116 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08003117 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003118 vx_tun_l3.vni)
3119 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
3120
3121 # endpoint learnt via the parent GBP-vxlan interface
3122 self.assertTrue(find_gbp_endpoint(self,
3123 vx_tun_l3._sw_if_index,
3124 ip=l['ip']))
3125
3126 #
3127 # Add a remote endpoint from the API
3128 #
3129 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
3130 epg_220, None,
3131 "10.0.0.88", "11.0.0.88",
3132 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08003133 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003134 self.pg2.local_ip4,
Neale Ranns3eea9de2019-06-21 02:09:25 -07003135 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003136 mac=None)
3137 rep_88.add_vpp_config()
3138
3139 #
3140 # Add a remote endpoint from the API that matches an existing one
Neale Ranns3eea9de2019-06-21 02:09:25 -07003141 # this is a lower priority, hence the packet is sent to the DP leanrt
3142 # TEP
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003143 #
3144 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
3145 epg_220, None,
3146 learnt[0]['ip'], "11.0.0.101",
3147 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08003148 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003149 self.pg2.local_ip4,
3150 self.pg2.remote_hosts[1].ip4,
3151 mac=None)
3152 rep_2.add_vpp_config()
3153
3154 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003155 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003156 # packets should be send on the v4/v6 uu=fwd interface resp.
3157 #
3158 se_10_1_24 = VppGbpSubnet(
3159 self, rd1, "10.0.1.0", 24,
3160 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
3161 se_10_1_24.add_vpp_config()
3162
3163 self.logger.info(self.vapi.cli("show gbp endpoint"))
3164
3165 ips = ["10.0.0.88", learnt[0]['ip']]
3166 for ip in ips:
3167 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003168 IP(dst=ip, src=ep.ip4) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003169 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003170 Raw(b'\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003171
Paul Vinciguerra4271c972019-05-14 13:25:49 -04003172 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003173
3174 for rx in rxs:
3175 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Ranns3eea9de2019-06-21 02:09:25 -07003176 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003177 self.assertEqual(rx[UDP].dport, 48879)
3178 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003179 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003180 self.assertEqual(rx[VXLAN].vni, 101)
3181 self.assertTrue(rx[VXLAN].flags.G)
3182 self.assertTrue(rx[VXLAN].flags.Instance)
3183 self.assertTrue(rx[VXLAN].gpflags.A)
3184 self.assertFalse(rx[VXLAN].gpflags.D)
3185
3186 inner = rx[VXLAN].payload
3187
3188 self.assertEqual(inner[Ether].src, routed_src_mac)
3189 self.assertEqual(inner[Ether].dst, routed_dst_mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003190 self.assertEqual(inner[IP].src, ep.ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003191 self.assertEqual(inner[IP].dst, ip)
3192
3193 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003194 # remove the API remote EPs, only API sourced is gone, the DP
3195 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003196 #
3197 rep_88.remove_vpp_config()
3198 rep_2.remove_vpp_config()
3199
Neale Rannsefd7bc22019-11-11 08:32:34 +00003200 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4))
Neale Ranns00a469d2018-12-20 06:12:19 -08003201
3202 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003203 IP(src=ep.ip4, dst=rep_2.ip4) /
Neale Ranns00a469d2018-12-20 06:12:19 -08003204 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003205 Raw(b'\xa5' * 100))
Neale Ranns00a469d2018-12-20 06:12:19 -08003206 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003207
Neale Rannsefd7bc22019-11-11 08:32:34 +00003208 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003209
Neale Ranns13a08cc2018-11-07 09:25:54 -08003210 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003211 IP(src=ep.ip4, dst=rep_88.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003212 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003213 Raw(b'\xa5' * 100))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003214 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003215
Neale Ranns13a08cc2018-11-07 09:25:54 -08003216 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003217 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08003218 # present (because it's DP learnt) when the TC ends so wait until
3219 # it is removed
3220 #
Neale Rannsefd7bc22019-11-11 08:32:34 +00003221 self.wait_for_ep_timeout(ip=rep_88.ip4)
3222 self.wait_for_ep_timeout(ip=rep_2.ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003223
3224 #
Neale Ranns3eea9de2019-06-21 02:09:25 -07003225 # Same as above, learn a remote EP via CP and DP
3226 # this time remove the DP one first. expect the CP data to remain
3227 #
3228 rep_3 = VppGbpEndpoint(self, vx_tun_l3,
3229 epg_220, None,
3230 "10.0.1.4", "11.0.0.103",
3231 "2001::10:3", "3001::103",
3232 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3233 self.pg2.local_ip4,
3234 self.pg2.remote_hosts[1].ip4,
3235 mac=None)
3236 rep_3.add_vpp_config()
3237
3238 p = (Ether(src=self.pg2.remote_mac,
3239 dst=self.pg2.local_mac) /
3240 IP(src=self.pg2.remote_hosts[2].ip4,
3241 dst=self.pg2.local_ip4) /
3242 UDP(sport=1234, dport=48879) /
3243 VXLAN(vni=101, gpid=441, flags=0x88) /
3244 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003245 IP(src="10.0.1.4", dst=ep.ip4) /
Neale Ranns3eea9de2019-06-21 02:09:25 -07003246 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003247 Raw(b'\xa5' * 100))
Neale Ranns3eea9de2019-06-21 02:09:25 -07003248 rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
3249
3250 self.assertTrue(find_gbp_endpoint(self,
3251 vx_tun_l3._sw_if_index,
Neale Rannsefd7bc22019-11-11 08:32:34 +00003252 ip=rep_3.ip4,
Neale Ranns3eea9de2019-06-21 02:09:25 -07003253 tep=[self.pg2.local_ip4,
3254 self.pg2.remote_hosts[2].ip4]))
3255
3256 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003257 IP(dst="10.0.1.4", src=ep.ip4) /
Neale Ranns3eea9de2019-06-21 02:09:25 -07003258 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003259 Raw(b'\xa5' * 100))
Neale Ranns3eea9de2019-06-21 02:09:25 -07003260 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3261
3262 # host 2 is the DP learned TEP
3263 for rx in rxs:
3264 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3265 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
3266
Neale Rannsefd7bc22019-11-11 08:32:34 +00003267 self.wait_for_ep_timeout(ip=rep_3.ip4,
Neale Ranns3eea9de2019-06-21 02:09:25 -07003268 tep=[self.pg2.local_ip4,
3269 self.pg2.remote_hosts[2].ip4])
3270
3271 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3272
3273 # host 1 is the CP learned TEP
3274 for rx in rxs:
3275 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3276 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
3277
3278 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003279 # shutdown with learnt endpoint present
3280 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003281 p = (Ether(src=self.pg2.remote_mac,
3282 dst=self.pg2.local_mac) /
3283 IP(src=self.pg2.remote_hosts[1].ip4,
3284 dst=self.pg2.local_ip4) /
3285 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003286 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003287 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003288 IP(src=learnt[1]['ip'], dst=ep.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003289 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003290 Raw(b'\xa5' * 100))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003291
3292 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3293
3294 # endpoint learnt via the parent GBP-vxlan interface
3295 self.assertTrue(find_gbp_endpoint(self,
3296 vx_tun_l3._sw_if_index,
3297 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003298
3299 #
3300 # TODO
3301 # remote endpoint becomes local
3302 #
3303 self.pg2.unconfig_ip4()
3304 self.pg3.unconfig_ip4()
3305 self.pg4.unconfig_ip4()
3306
Neale Ranns13a08cc2018-11-07 09:25:54 -08003307 def test_gbp_redirect(self):
3308 """ GBP Endpoint Redirect """
3309
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04003310 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08003311
Neale Rannsb6a47952018-11-21 05:44:35 -08003312 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08003313 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3314 routed_src_mac = "00:22:bd:f8:19:ff"
3315
3316 learnt = [{'mac': '00:00:11:11:11:02',
3317 'ip': '10.0.1.2',
3318 'ip6': '2001:10::2'},
3319 {'mac': '00:00:11:11:11:03',
3320 'ip': '10.0.1.3',
3321 'ip6': '2001:10::3'}]
3322
3323 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003324 # IP tables
3325 #
3326 t4 = VppIpTable(self, 1)
3327 t4.add_vpp_config()
3328 t6 = VppIpTable(self, 1, True)
3329 t6.add_vpp_config()
3330
Neale Ranns160c9232019-06-19 06:25:56 -07003331 rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003332 rd1.add_vpp_config()
3333
Ole Troan8006c6a2018-12-17 12:02:26 +01003334 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003335
3336 #
3337 # Bind the BVI to the RD
3338 #
Neale Ranns59f71132020-04-08 12:19:38 +00003339 b_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3340 b_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003341
3342 #
3343 # Pg7 hosts a BD's UU-fwd
3344 #
3345 self.pg7.config_ip4()
3346 self.pg7.resolve_arp()
3347
3348 #
3349 # a GBP bridge domains for the EPs
3350 #
3351 bd1 = VppBridgeDomain(self, 1)
3352 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003353 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003354 gbd1.add_vpp_config()
3355
3356 bd2 = VppBridgeDomain(self, 2)
3357 bd2.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003358 gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003359 gbd2.add_vpp_config()
3360
3361 # ... and has a /32 and /128 applied
Neale Ranns59f71132020-04-08 12:19:38 +00003362 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi,
3363 "10.0.0.128", 32,
3364 bind=b_ip4).add_vpp_config()
3365 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi,
3366 "2001:10::128", 128,
3367 bind=b_ip6).add_vpp_config()
3368 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi,
3369 "10.0.1.128", 32).add_vpp_config()
3370 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi,
3371 "2001:11::128", 128).add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003372
3373 #
3374 # The Endpoint-groups in which we are learning endpoints
3375 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003376 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003377 None, gbd1.bvi,
3378 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003379 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003380 VppGbpEndpointRetention(60))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003381 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003382 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003383 None, gbd2.bvi,
3384 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003385 "2001:11::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003386 VppGbpEndpointRetention(60))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003387 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003388 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003389 None, gbd1.bvi,
3390 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003391 "2001:12::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003392 VppGbpEndpointRetention(60))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003393 epg_222.add_vpp_config()
3394
3395 #
3396 # a GBP bridge domains for the SEPs
3397 #
3398 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3399 self.pg7.remote_ip4, 116)
3400 bd_uu1.add_vpp_config()
3401 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3402 self.pg7.remote_ip4, 117)
3403 bd_uu2.add_vpp_config()
3404
3405 bd3 = VppBridgeDomain(self, 3)
3406 bd3.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003407 gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2,
3408 bd_uu1, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003409 gbd3.add_vpp_config()
3410 bd4 = VppBridgeDomain(self, 4)
3411 bd4.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003412 gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3,
3413 bd_uu2, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003414 gbd4.add_vpp_config()
3415
3416 #
3417 # EPGs in which the service endpoints exist
3418 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003419 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003420 None, gbd1.bvi,
3421 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003422 "4001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003423 VppGbpEndpointRetention(60))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003424 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003425 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003426 None, gbd2.bvi,
3427 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003428 "4001:11::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003429 VppGbpEndpointRetention(60))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003430 epg_321.add_vpp_config()
3431
3432 #
3433 # three local endpoints
3434 #
3435 ep1 = VppGbpEndpoint(self, self.pg0,
3436 epg_220, None,
3437 "10.0.0.1", "11.0.0.1",
3438 "2001:10::1", "3001:10::1")
3439 ep1.add_vpp_config()
3440 ep2 = VppGbpEndpoint(self, self.pg1,
3441 epg_221, None,
3442 "10.0.1.1", "11.0.1.1",
3443 "2001:11::1", "3001:11::1")
3444 ep2.add_vpp_config()
3445 ep3 = VppGbpEndpoint(self, self.pg2,
3446 epg_222, None,
3447 "10.0.2.2", "11.0.2.2",
3448 "2001:12::1", "3001:12::1")
3449 ep3.add_vpp_config()
3450
3451 #
3452 # service endpoints
3453 #
3454 sep1 = VppGbpEndpoint(self, self.pg3,
3455 epg_320, None,
3456 "12.0.0.1", "13.0.0.1",
3457 "4001:10::1", "5001:10::1")
3458 sep1.add_vpp_config()
3459 sep2 = VppGbpEndpoint(self, self.pg4,
3460 epg_320, None,
3461 "12.0.0.2", "13.0.0.2",
3462 "4001:10::2", "5001:10::2")
3463 sep2.add_vpp_config()
3464 sep3 = VppGbpEndpoint(self, self.pg5,
3465 epg_321, None,
3466 "12.0.1.1", "13.0.1.1",
3467 "4001:11::1", "5001:11::1")
3468 sep3.add_vpp_config()
3469 # this EP is not installed immediately
3470 sep4 = VppGbpEndpoint(self, self.pg6,
3471 epg_321, None,
3472 "12.0.1.2", "13.0.1.2",
3473 "4001:11::2", "5001:11::2")
3474
3475 #
3476 # an L2 switch packet between local EPs in different EPGs
3477 # different dest ports on each so the are LB hashed differently
3478 #
3479 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003480 IP(src=ep1.ip4, dst=ep3.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003481 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003482 Raw(b'\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003483 (Ether(src=ep3.mac, dst=ep1.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003484 IP(src=ep3.ip4, dst=ep1.ip4) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003485 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003486 Raw(b'\xa5' * 100))]
Neale Ranns13a08cc2018-11-07 09:25:54 -08003487 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003488 IPv6(src=ep1.ip6, dst=ep3.ip6) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003489 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003490 Raw(b'\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003491 (Ether(src=ep3.mac, dst=ep1.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003492 IPv6(src=ep3.ip6, dst=ep1.ip6) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003493 UDP(sport=1234, dport=1230) /
Ole Troan770a0de2019-11-07 13:52:21 +01003494 Raw(b'\xa5' * 100))]
Neale Ranns13a08cc2018-11-07 09:25:54 -08003495
3496 # should be dropped since no contract yet
3497 self.send_and_assert_no_replies(self.pg0, [p4[0]])
3498 self.send_and_assert_no_replies(self.pg0, [p6[0]])
3499
3500 #
3501 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
3502 # one of the next-hops is via an EP that is not known
3503 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003504 rule4 = AclRule(is_permit=1, proto=17)
3505 rule6 = AclRule(src_prefix=IPv6Network((0, 0)),
3506 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
3507 acl = VppAcl(self, rules=[rule4, rule6])
3508 acl.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003509
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003510 #
3511 # test the src-ip hash mode
3512 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003513 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003514 self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003515 [VppGbpContractRule(
3516 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003517 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003518 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3519 sep1.ip4, sep1.epg.rd),
3520 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3521 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003522 VppGbpContractRule(
3523 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3524 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3525 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3526 sep3.ip6, sep3.epg.rd),
3527 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3528 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003529 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08003530 c1.add_vpp_config()
3531
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003532 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003533 self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003534 [VppGbpContractRule(
3535 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3536 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3537 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3538 sep1.ip4, sep1.epg.rd),
3539 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3540 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003541 VppGbpContractRule(
3542 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3543 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3544 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3545 sep3.ip6, sep3.epg.rd),
3546 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3547 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003548 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003549 c2.add_vpp_config()
3550
Neale Ranns13a08cc2018-11-07 09:25:54 -08003551 #
3552 # send again with the contract preset, now packets arrive
3553 # at SEP1 or SEP2 depending on the hashing
3554 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003555 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003556
3557 for rx in rxs:
3558 self.assertEqual(rx[Ether].src, routed_src_mac)
3559 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003560 self.assertEqual(rx[IP].src, ep1.ip4)
3561 self.assertEqual(rx[IP].dst, ep3.ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003562
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003563 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
3564
3565 for rx in rxs:
3566 self.assertEqual(rx[Ether].src, routed_src_mac)
3567 self.assertEqual(rx[Ether].dst, sep2.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003568 self.assertEqual(rx[IP].src, ep3.ip4)
3569 self.assertEqual(rx[IP].dst, ep1.ip4)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003570
Neale Ranns13a08cc2018-11-07 09:25:54 -08003571 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3572
3573 for rx in rxs:
3574 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3575 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3576 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3577 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3578 self.assertEqual(rx[VXLAN].vni, 117)
3579 self.assertTrue(rx[VXLAN].flags.G)
3580 self.assertTrue(rx[VXLAN].flags.Instance)
3581 # redirect policy has been applied
3582 self.assertTrue(rx[VXLAN].gpflags.A)
3583 self.assertFalse(rx[VXLAN].gpflags.D)
3584
3585 inner = rx[VXLAN].payload
3586
3587 self.assertEqual(inner[Ether].src, routed_src_mac)
3588 self.assertEqual(inner[Ether].dst, sep4.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003589 self.assertEqual(inner[IPv6].src, ep1.ip6)
3590 self.assertEqual(inner[IPv6].dst, ep3.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003591
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003592 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003593
3594 for rx in rxs:
3595 self.assertEqual(rx[Ether].src, routed_src_mac)
3596 self.assertEqual(rx[Ether].dst, sep3.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003597 self.assertEqual(rx[IPv6].src, ep3.ip6)
3598 self.assertEqual(rx[IPv6].dst, ep1.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003599
3600 #
3601 # programme the unknown EP
3602 #
3603 sep4.add_vpp_config()
3604
3605 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3606
3607 for rx in rxs:
3608 self.assertEqual(rx[Ether].src, routed_src_mac)
3609 self.assertEqual(rx[Ether].dst, sep4.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003610 self.assertEqual(rx[IPv6].src, ep1.ip6)
3611 self.assertEqual(rx[IPv6].dst, ep3.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003612
3613 #
3614 # and revert back to unprogrammed
3615 #
3616 sep4.remove_vpp_config()
3617
3618 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3619
3620 for rx in rxs:
3621 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3622 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3623 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3624 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3625 self.assertEqual(rx[VXLAN].vni, 117)
3626 self.assertTrue(rx[VXLAN].flags.G)
3627 self.assertTrue(rx[VXLAN].flags.Instance)
3628 # redirect policy has been applied
3629 self.assertTrue(rx[VXLAN].gpflags.A)
3630 self.assertFalse(rx[VXLAN].gpflags.D)
3631
3632 inner = rx[VXLAN].payload
3633
3634 self.assertEqual(inner[Ether].src, routed_src_mac)
3635 self.assertEqual(inner[Ether].dst, sep4.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003636 self.assertEqual(inner[IPv6].src, ep1.ip6)
3637 self.assertEqual(inner[IPv6].dst, ep3.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003638
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003639 c1.remove_vpp_config()
3640 c2.remove_vpp_config()
3641
3642 #
3643 # test the symmetric hash mode
3644 #
3645 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003646 self, 402, epg_220.sclass, epg_222.sclass, acl.acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003647 [VppGbpContractRule(
3648 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3649 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3650 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3651 sep1.ip4, sep1.epg.rd),
3652 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3653 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003654 VppGbpContractRule(
3655 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3656 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3657 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3658 sep3.ip6, sep3.epg.rd),
3659 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3660 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003661 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003662 c1.add_vpp_config()
3663
3664 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003665 self, 402, epg_222.sclass, epg_220.sclass, acl.acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003666 [VppGbpContractRule(
3667 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3668 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3669 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3670 sep1.ip4, sep1.epg.rd),
3671 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3672 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003673 VppGbpContractRule(
3674 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3675 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3676 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3677 sep3.ip6, sep3.epg.rd),
3678 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3679 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003680 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003681 c2.add_vpp_config()
3682
3683 #
3684 # send again with the contract preset, now packets arrive
3685 # at SEP1 for both directions
3686 #
3687 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3688
3689 for rx in rxs:
3690 self.assertEqual(rx[Ether].src, routed_src_mac)
3691 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003692 self.assertEqual(rx[IP].src, ep1.ip4)
3693 self.assertEqual(rx[IP].dst, ep3.ip4)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003694
3695 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3696
3697 for rx in rxs:
3698 self.assertEqual(rx[Ether].src, routed_src_mac)
3699 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003700 self.assertEqual(rx[IP].src, ep3.ip4)
3701 self.assertEqual(rx[IP].dst, ep1.ip4)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003702
Neale Ranns13a08cc2018-11-07 09:25:54 -08003703 #
3704 # programme the unknown EP for the L3 tests
3705 #
3706 sep4.add_vpp_config()
3707
3708 #
3709 # an L3 switch packet between local EPs in different EPGs
3710 # different dest ports on each so the are LB hashed differently
3711 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003712 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003713 IP(src=ep1.ip4, dst=ep2.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003714 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003715 Raw(b'\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003716 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003717 IP(src=ep2.ip4, dst=ep1.ip4) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003718 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003719 Raw(b'\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003720 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003721 IPv6(src=ep1.ip6, dst=ep2.ip6) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003722 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003723 Raw(b'\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003724 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003725 IPv6(src=ep2.ip6, dst=ep1.ip6) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003726 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003727 Raw(b'\xa5' * 100))]
Neale Ranns13a08cc2018-11-07 09:25:54 -08003728
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003729 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003730 self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003731 [VppGbpContractRule(
3732 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3733 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3734 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3735 sep1.ip4, sep1.epg.rd),
3736 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3737 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003738 VppGbpContractRule(
3739 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3740 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3741 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3742 sep3.ip6, sep3.epg.rd),
3743 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3744 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003745 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003746 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003747
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003748 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003749
3750 for rx in rxs:
3751 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003752 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003753 self.assertEqual(rx[IP].src, ep1.ip4)
3754 self.assertEqual(rx[IP].dst, ep2.ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003755
3756 #
3757 # learn a remote EP in EPG 221
Benoît Ganneb8543242019-07-31 14:15:57 +02003758 # packets coming from unknown remote EPs will be leant & redirected
Neale Ranns13a08cc2018-11-07 09:25:54 -08003759 #
3760 vx_tun_l3 = VppGbpVxlanTunnel(
3761 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003762 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3763 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003764 vx_tun_l3.add_vpp_config()
3765
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003766 c4 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003767 self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003768 [VppGbpContractRule(
Benoît Ganneb8543242019-07-31 14:15:57 +02003769 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003770 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Benoît Ganneb8543242019-07-31 14:15:57 +02003771 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3772 sep1.ip4, sep1.epg.rd),
3773 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3774 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003775 VppGbpContractRule(
Benoît Ganneb8543242019-07-31 14:15:57 +02003776 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003777 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Benoît Ganneb8543242019-07-31 14:15:57 +02003778 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3779 sep3.ip6, sep3.epg.rd),
3780 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3781 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003782 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003783 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003784
3785 p = (Ether(src=self.pg7.remote_mac,
3786 dst=self.pg7.local_mac) /
3787 IP(src=self.pg7.remote_ip4,
3788 dst=self.pg7.local_ip4) /
3789 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003790 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003791 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003792 IP(src="10.0.0.88", dst=ep1.ip4) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003793 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003794 Raw(b'\xa5' * 100))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003795
Benoît Ganneb8543242019-07-31 14:15:57 +02003796 # unknown remote EP to local EP redirected
3797 rxs = self.send_and_expect(self.pg7, [p], sep1.itf)
3798
3799 for rx in rxs:
3800 self.assertEqual(rx[Ether].src, routed_src_mac)
3801 self.assertEqual(rx[Ether].dst, sep1.mac)
3802 self.assertEqual(rx[IP].src, "10.0.0.88")
Neale Rannsefd7bc22019-11-11 08:32:34 +00003803 self.assertEqual(rx[IP].dst, ep1.ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003804
3805 # endpoint learnt via the parent GBP-vxlan interface
3806 self.assertTrue(find_gbp_endpoint(self,
3807 vx_tun_l3._sw_if_index,
3808 ip="10.0.0.88"))
3809
3810 p = (Ether(src=self.pg7.remote_mac,
3811 dst=self.pg7.local_mac) /
3812 IP(src=self.pg7.remote_ip4,
3813 dst=self.pg7.local_ip4) /
3814 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003815 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003816 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003817 IPv6(src="2001:10::88", dst=ep1.ip6) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003818 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003819 Raw(b'\xa5' * 100))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003820
Benoît Ganneb8543242019-07-31 14:15:57 +02003821 # unknown remote EP to local EP redirected (ipv6)
3822 rxs = self.send_and_expect(self.pg7, [p], sep3.itf)
3823
3824 for rx in rxs:
3825 self.assertEqual(rx[Ether].src, routed_src_mac)
3826 self.assertEqual(rx[Ether].dst, sep3.mac)
3827 self.assertEqual(rx[IPv6].src, "2001:10::88")
Neale Rannsefd7bc22019-11-11 08:32:34 +00003828 self.assertEqual(rx[IPv6].dst, ep1.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003829
3830 # endpoint learnt via the parent GBP-vxlan interface
3831 self.assertTrue(find_gbp_endpoint(self,
3832 vx_tun_l3._sw_if_index,
3833 ip="2001:10::88"))
3834
3835 #
3836 # L3 switch from local to remote EP
3837 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003838 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003839 IP(src=ep1.ip4, dst="10.0.0.88") /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003840 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003841 Raw(b'\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003842 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00003843 IPv6(src=ep1.ip6, dst="2001:10::88") /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003844 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01003845 Raw(b'\xa5' * 100))]
Neale Ranns13a08cc2018-11-07 09:25:54 -08003846
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003847 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003848
3849 for rx in rxs:
3850 self.assertEqual(rx[Ether].src, routed_src_mac)
3851 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003852 self.assertEqual(rx[IP].src, ep1.ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003853 self.assertEqual(rx[IP].dst, "10.0.0.88")
3854
3855 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3856
3857 for rx in rxs:
3858 self.assertEqual(rx[Ether].src, routed_src_mac)
3859 self.assertEqual(rx[Ether].dst, sep4.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003860 self.assertEqual(rx[IPv6].src, ep1.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003861 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3862
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003863 #
3864 # test the dst-ip hash mode
3865 #
3866 c5 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01003867 self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003868 [VppGbpContractRule(
3869 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3870 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3871 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3872 sep1.ip4, sep1.epg.rd),
3873 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3874 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003875 VppGbpContractRule(
3876 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3877 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3878 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3879 sep3.ip6, sep3.epg.rd),
3880 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3881 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003882 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003883 c5.add_vpp_config()
3884
3885 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3886
3887 for rx in rxs:
3888 self.assertEqual(rx[Ether].src, routed_src_mac)
3889 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003890 self.assertEqual(rx[IP].src, ep1.ip4)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003891 self.assertEqual(rx[IP].dst, "10.0.0.88")
3892
3893 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003894
3895 for rx in rxs:
3896 self.assertEqual(rx[Ether].src, routed_src_mac)
3897 self.assertEqual(rx[Ether].dst, sep3.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00003898 self.assertEqual(rx[IPv6].src, ep1.ip6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003899 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3900
Neale Rannsb6a47952018-11-21 05:44:35 -08003901 #
Benoît Ganne66035672019-08-02 17:57:08 +02003902 # a programmed remote SEP in EPG 320
Benoît Ganne388f4182019-07-31 14:29:00 +02003903 #
3904
3905 # gbp vxlan tunnel for the remote SEP
3906 vx_tun_l3_sep = VppGbpVxlanTunnel(
3907 self, 555, rd1.rd_id,
3908 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3909 self.pg2.local_ip4)
3910 vx_tun_l3_sep.add_vpp_config()
3911
3912 # remote SEP
3913 sep5 = VppGbpEndpoint(self, vx_tun_l3_sep,
3914 epg_320, None,
3915 "12.0.0.10", "13.0.0.10",
3916 "4001:10::10", "5001:10::10",
3917 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3918 self.pg7.local_ip4,
3919 self.pg7.remote_ip4,
3920 mac=None)
3921 sep5.add_vpp_config()
3922
3923 #
Benoît Ganne66035672019-08-02 17:57:08 +02003924 # local l3out redirect tests
Benoît Ganne388f4182019-07-31 14:29:00 +02003925 #
3926
3927 # add local l3out
3928 # the external bd
3929 self.loop4.set_mac(self.router_mac)
Neale Ranns59f71132020-04-08 12:19:38 +00003930 b_lo4_ip4 = VppIpInterfaceBind(self, self.loop4, t4).add_vpp_config()
3931 b_lo4_ip6 = VppIpInterfaceBind(self, self.loop4, t6).add_vpp_config()
Benoît Ganne388f4182019-07-31 14:29:00 +02003932 ebd = VppBridgeDomain(self, 100)
3933 ebd.add_vpp_config()
3934 gebd = VppGbpBridgeDomain(self, ebd, rd1, self.loop4, None, None)
3935 gebd.add_vpp_config()
3936 # the external epg
3937 eepg = VppGbpEndpointGroup(self, 888, 765, rd1, gebd,
3938 None, gebd.bvi,
3939 "10.1.0.128",
3940 "2001:10:1::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00003941 VppGbpEndpointRetention(60))
Benoît Ganne388f4182019-07-31 14:29:00 +02003942 eepg.add_vpp_config()
3943 # add subnets to BVI
3944 VppIpInterfaceAddress(
3945 self,
3946 gebd.bvi,
3947 "10.1.0.128",
Neale Ranns59f71132020-04-08 12:19:38 +00003948 24, bind=b_lo4_ip4).add_vpp_config()
Benoît Ganne388f4182019-07-31 14:29:00 +02003949 VppIpInterfaceAddress(
3950 self,
3951 gebd.bvi,
3952 "2001:10:1::128",
Neale Ranns59f71132020-04-08 12:19:38 +00003953 64, bind=b_lo4_ip6).add_vpp_config()
Benoît Ganne388f4182019-07-31 14:29:00 +02003954 # ... which are L3-out subnets
3955 VppGbpSubnet(self, rd1, "10.1.0.0", 24,
3956 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3957 sclass=765).add_vpp_config()
3958 VppGbpSubnet(self, rd1, "2001:10:1::128", 64,
3959 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3960 sclass=765).add_vpp_config()
3961 # external endpoints
3962 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3963 eep1 = VppGbpEndpoint(self, self.vlan_100, eepg, None, "10.1.0.1",
3964 "11.1.0.1", "2001:10:1::1", "3001:10:1::1",
3965 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3966 eep1.add_vpp_config()
3967 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3968 eep2 = VppGbpEndpoint(self, self.vlan_101, eepg, None, "10.1.0.2",
3969 "11.1.0.2", "2001:10:1::2", "3001:10:1::2",
3970 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3971 eep2.add_vpp_config()
3972
3973 # external subnets reachable though eep1 and eep2 respectively
3974 VppIpRoute(self, "10.220.0.0", 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +00003975 [VppRoutePath(eep1.ip4, eep1.epg.bvi.sw_if_index)],
Benoît Ganne388f4182019-07-31 14:29:00 +02003976 table_id=t4.table_id).add_vpp_config()
3977 VppGbpSubnet(self, rd1, "10.220.0.0", 24,
3978 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3979 sclass=4220).add_vpp_config()
3980 VppIpRoute(self, "10:220::", 64,
Neale Rannsefd7bc22019-11-11 08:32:34 +00003981 [VppRoutePath(eep1.ip6, eep1.epg.bvi.sw_if_index)],
Benoît Ganne388f4182019-07-31 14:29:00 +02003982 table_id=t6.table_id).add_vpp_config()
3983 VppGbpSubnet(self, rd1, "10:220::", 64,
3984 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3985 sclass=4220).add_vpp_config()
3986 VppIpRoute(self, "10.221.0.0", 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +00003987 [VppRoutePath(eep2.ip4, eep2.epg.bvi.sw_if_index)],
Benoît Ganne388f4182019-07-31 14:29:00 +02003988 table_id=t4.table_id).add_vpp_config()
3989 VppGbpSubnet(self, rd1, "10.221.0.0", 24,
3990 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3991 sclass=4221).add_vpp_config()
3992 VppIpRoute(self, "10:221::", 64,
Neale Rannsefd7bc22019-11-11 08:32:34 +00003993 [VppRoutePath(eep2.ip6, eep2.epg.bvi.sw_if_index)],
Benoît Ganne388f4182019-07-31 14:29:00 +02003994 table_id=t6.table_id).add_vpp_config()
3995 VppGbpSubnet(self, rd1, "10:221::", 64,
3996 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3997 sclass=4221).add_vpp_config()
3998
Benoît Ganne66035672019-08-02 17:57:08 +02003999 #
4000 # l3out redirect to remote (known, then unknown) SEP
4001 #
4002
Benoît Ganne388f4182019-07-31 14:29:00 +02004003 # packets from 1 external subnet to the other
4004 p = [(Ether(src=eep1.mac, dst=self.router_mac) /
4005 Dot1Q(vlan=100) /
4006 IP(src="10.220.0.17", dst="10.221.0.65") /
4007 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004008 Raw(b'\xa5' * 100)),
Benoît Ganne388f4182019-07-31 14:29:00 +02004009 (Ether(src=eep1.mac, dst=self.router_mac) /
4010 Dot1Q(vlan=100) /
4011 IPv6(src="10:220::17", dst="10:221::65") /
4012 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004013 Raw(b'\xa5' * 100))]
Benoît Ganne388f4182019-07-31 14:29:00 +02004014
4015 # packets should be dropped in absence of contract
4016 self.send_and_assert_no_replies(self.pg0, p)
4017
4018 # contract redirecting to sep5
4019 VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004020 self, 402, 4220, 4221, acl.acl_index,
Benoît Ganne388f4182019-07-31 14:29:00 +02004021 [VppGbpContractRule(
4022 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4023 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4024 [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd,
4025 sep5.ip4, sep5.epg.rd)]),
4026 VppGbpContractRule(
4027 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4028 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4029 [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd,
4030 sep5.ip6, sep5.epg.rd)])],
4031 [ETH_P_IP, ETH_P_IPV6]).add_vpp_config()
4032
4033 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4034
4035 for rx, tx in zip(rxs, p):
4036 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4037 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4038 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4039 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4040 # this should use the programmed remote leaf TEP
4041 self.assertEqual(rx[VXLAN].vni, 555)
4042 self.assertEqual(rx[VXLAN].gpid, 4220)
4043 self.assertTrue(rx[VXLAN].flags.G)
4044 self.assertTrue(rx[VXLAN].flags.Instance)
4045 # redirect policy has been applied
4046 self.assertTrue(rx[VXLAN].gpflags.A)
4047 self.assertTrue(rx[VXLAN].gpflags.D)
4048 rxip = rx[VXLAN][Ether].payload
4049 txip = tx[Dot1Q].payload
4050 self.assertEqual(rxip.src, txip.src)
4051 self.assertEqual(rxip.dst, txip.dst)
4052
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004053 # remote SEP: it is now an unknown remote SEP and should go
Benoît Ganne388f4182019-07-31 14:29:00 +02004054 # to spine proxy
4055 sep5.remove_vpp_config()
4056
4057 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4058
4059 for rx, tx in zip(rxs, p):
4060 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4061 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4062 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4063 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4064 # this should use the spine proxy TEP
4065 self.assertEqual(rx[VXLAN].vni, epg_320.bd.uu_fwd.vni)
4066 self.assertEqual(rx[VXLAN].gpid, 4220)
4067 self.assertTrue(rx[VXLAN].flags.G)
4068 self.assertTrue(rx[VXLAN].flags.Instance)
4069 # redirect policy has been applied
4070 self.assertTrue(rx[VXLAN].gpflags.A)
4071 self.assertTrue(rx[VXLAN].gpflags.D)
4072 rxip = rx[VXLAN][Ether].payload
4073 txip = tx[Dot1Q].payload
4074 self.assertEqual(rxip.src, txip.src)
4075 self.assertEqual(rxip.dst, txip.dst)
4076
4077 #
Benoît Ganne66035672019-08-02 17:57:08 +02004078 # l3out redirect to local SEP
4079 #
4080
4081 # change the contract between l3out to redirect to local SEPs
4082 # instead of remote SEP
4083 VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004084 self, 402, 4220, 4221, acl.acl_index,
Benoît Ganne66035672019-08-02 17:57:08 +02004085 [VppGbpContractRule(
4086 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4087 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4088 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4089 sep1.ip4, sep1.epg.rd)]),
4090 VppGbpContractRule(
4091 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4092 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4093 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4094 sep1.ip6, sep1.epg.rd)])],
4095 [ETH_P_IP, ETH_P_IPV6]).add_vpp_config()
4096
4097 rxs = self.send_and_expect(self.pg0, p, sep1.itf)
4098 for rx, tx in zip(rxs, p):
4099 self.assertEqual(rx[Ether].src, routed_src_mac)
4100 self.assertEqual(rx[Ether].dst, sep1.mac)
4101 rxip = rx[Ether].payload
4102 txip = tx[Ether].payload
4103 self.assertEqual(rxip.src, txip.src)
4104 self.assertEqual(rxip.dst, txip.dst)
4105
4106 #
4107 # redirect remote EP to remote (known then unknown) SEP
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004108 #
4109
4110 # remote SEP known again
4111 sep5.add_vpp_config()
4112
4113 # contract to redirect to learnt SEP
4114 VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004115 self, 402, epg_221.sclass, epg_222.sclass, acl.acl_index,
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004116 [VppGbpContractRule(
4117 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4118 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4119 [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd,
4120 sep5.ip4, sep5.epg.rd)]),
4121 VppGbpContractRule(
4122 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4123 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
4124 [VppGbpContractNextHop(sep5.vmac, sep5.epg.bd,
4125 sep5.ip6, sep5.epg.rd)])],
4126 [ETH_P_IP, ETH_P_IPV6]).add_vpp_config()
4127
4128 # packets from unknown EP 221 to known EP in EPG 222
4129 # should be redirected to known remote SEP
4130 base = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4131 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4132 UDP(sport=1234, dport=48879) /
4133 VXLAN(vni=444, gpid=441, flags=0x88) /
4134 Ether(src="00:22:22:22:22:44", dst=str(self.router_mac)))
4135 p = [(base /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004136 IP(src="10.0.1.100", dst=ep3.ip4) /
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004137 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004138 Raw(b'\xa5' * 100)),
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004139 (base /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004140 IPv6(src="2001:10::100", dst=ep3.ip6) /
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004141 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004142 Raw(b'\xa5' * 100))]
Benoît Ganne4ea511c2019-08-02 16:36:35 +02004143
4144 # unknown remote EP to local EP redirected to known remote SEP
4145 rxs = self.send_and_expect(self.pg7, p, self.pg7)
4146
4147 for rx, tx in zip(rxs, p):
4148 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4149 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4150 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4151 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4152 # this should use the programmed remote leaf TEP
4153 self.assertEqual(rx[VXLAN].vni, 555)
4154 self.assertEqual(rx[VXLAN].gpid, epg_221.sclass)
4155 self.assertTrue(rx[VXLAN].flags.G)
4156 self.assertTrue(rx[VXLAN].flags.Instance)
4157 # redirect policy has been applied
4158 self.assertTrue(rx[VXLAN].gpflags.A)
4159 self.assertFalse(rx[VXLAN].gpflags.D)
4160 rxip = rx[VXLAN][Ether].payload
4161 txip = tx[VXLAN][Ether].payload
4162 self.assertEqual(rxip.src, txip.src)
4163 self.assertEqual(rxip.dst, txip.dst)
4164
4165 # endpoint learnt via the parent GBP-vxlan interface
4166 self.assertTrue(find_gbp_endpoint(self,
4167 vx_tun_l3._sw_if_index,
4168 ip="10.0.1.100"))
4169 self.assertTrue(find_gbp_endpoint(self,
4170 vx_tun_l3._sw_if_index,
4171 ip="2001:10::100"))
4172
4173 # remote SEP: it is now an unknown remote SEP and should go
4174 # to spine proxy
4175 sep5.remove_vpp_config()
4176
4177 # remote EP (coming from spine proxy) to local EP redirected to
4178 # known remote SEP
4179 rxs = self.send_and_expect(self.pg7, p, self.pg7)
4180
4181 for rx, tx in zip(rxs, p):
4182 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4183 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4184 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4185 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4186 # this should use the spine proxy TEP
4187 self.assertEqual(rx[VXLAN].vni, epg_320.bd.uu_fwd.vni)
4188 self.assertEqual(rx[VXLAN].gpid, epg_221.sclass)
4189 self.assertTrue(rx[VXLAN].flags.G)
4190 self.assertTrue(rx[VXLAN].flags.Instance)
4191 # redirect policy has been applied
4192 self.assertTrue(rx[VXLAN].gpflags.A)
4193 self.assertFalse(rx[VXLAN].gpflags.D)
4194 rxip = rx[VXLAN][Ether].payload
4195 txip = tx[VXLAN][Ether].payload
4196 self.assertEqual(rxip.src, txip.src)
4197 self.assertEqual(rxip.dst, txip.dst)
4198
4199 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004200 # cleanup
4201 #
4202 self.pg7.unconfig_ip4()
4203
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004204 def test_gbp_redirect_extended(self):
4205 """ GBP Endpoint Redirect Extended """
4206
4207 self.vapi.cli("set logging class gbp level debug")
4208
4209 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
4210 routed_dst_mac = "00:0c:0c:0c:0c:0c"
4211 routed_src_mac = "00:22:bd:f8:19:ff"
4212
4213 learnt = [{'mac': '00:00:11:11:11:02',
4214 'ip': '10.0.1.2',
4215 'ip6': '2001:10::2'},
4216 {'mac': '00:00:11:11:11:03',
4217 'ip': '10.0.1.3',
4218 'ip6': '2001:10::3'}]
4219
4220 #
4221 # IP tables
4222 #
4223 t4 = VppIpTable(self, 1)
4224 t4.add_vpp_config()
4225 t6 = VppIpTable(self, 1, True)
4226 t6.add_vpp_config()
4227
4228 # create IPv4 and IPv6 RD UU VxLAN-GBP TEP and bind them to the right
4229 # VRF
4230 rd_uu4 = VppVxlanGbpTunnel(
4231 self,
4232 self.pg7.local_ip4,
4233 self.pg7.remote_ip4,
4234 114,
4235 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4236 VXLAN_GBP_API_TUNNEL_MODE_L3))
4237 rd_uu4.add_vpp_config()
4238 VppIpInterfaceBind(self, rd_uu4, t4).add_vpp_config()
4239
4240 rd_uu6 = VppVxlanGbpTunnel(
4241 self,
4242 self.pg7.local_ip4,
4243 self.pg7.remote_ip4,
4244 115,
4245 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4246 VXLAN_GBP_API_TUNNEL_MODE_L3))
4247 rd_uu6.add_vpp_config()
4248 VppIpInterfaceBind(self, rd_uu6, t4).add_vpp_config()
4249
4250 rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6, rd_uu4, rd_uu6)
4251 rd1.add_vpp_config()
4252
4253 self.loop0.set_mac(self.router_mac)
4254 self.loop1.set_mac(self.router_mac)
4255 self.loop2.set_mac(self.router_mac)
4256
4257 #
4258 # Bind the BVI to the RD
4259 #
Neale Ranns59f71132020-04-08 12:19:38 +00004260 b_lo0_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
4261 b_lo0_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
4262 b_lo1_ip4 = VppIpInterfaceBind(self, self.loop1, t4).add_vpp_config()
4263 b_lo1_ip6 = VppIpInterfaceBind(self, self.loop1, t6).add_vpp_config()
4264 b_lo2_ip4 = VppIpInterfaceBind(self, self.loop2, t4).add_vpp_config()
4265 b_lo2_ip6 = VppIpInterfaceBind(self, self.loop2, t6).add_vpp_config()
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004266
4267 #
4268 # Pg7 hosts a BD's UU-fwd
4269 #
4270 self.pg7.config_ip4()
4271 self.pg7.resolve_arp()
4272
4273 #
4274 # a GBP bridge domains for the EPs
4275 #
4276 bd1 = VppBridgeDomain(self, 1)
4277 bd1.add_vpp_config()
4278 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0)
4279 gbd1.add_vpp_config()
4280
4281 bd2 = VppBridgeDomain(self, 2)
4282 bd2.add_vpp_config()
4283 gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1)
4284 gbd2.add_vpp_config()
4285
4286 # ... and has a /32 and /128 applied
Neale Ranns59f71132020-04-08 12:19:38 +00004287 ip4_addr1 = VppIpInterfaceAddress(self, gbd1.bvi,
4288 "10.0.0.128", 32,
4289 bind=b_lo0_ip4).add_vpp_config()
4290 ip6_addr1 = VppIpInterfaceAddress(self, gbd1.bvi,
4291 "2001:10::128", 128,
4292 bind=b_lo0_ip6).add_vpp_config()
4293 ip4_addr2 = VppIpInterfaceAddress(self, gbd2.bvi,
4294 "10.0.1.128", 32,
4295 bind=b_lo1_ip4).add_vpp_config()
4296 ip6_addr2 = VppIpInterfaceAddress(self, gbd2.bvi,
4297 "2001:11::128", 128,
4298 bind=b_lo1_ip6).add_vpp_config()
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004299
4300 #
4301 # The Endpoint-groups
4302 #
4303 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
4304 None, gbd1.bvi,
4305 "10.0.0.128",
4306 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00004307 VppGbpEndpointRetention(60))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004308 epg_220.add_vpp_config()
4309 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
4310 None, gbd2.bvi,
4311 "10.0.1.128",
4312 "2001:11::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00004313 VppGbpEndpointRetention(60))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004314 epg_221.add_vpp_config()
4315
4316 #
4317 # a GBP bridge domains for the SEPs
4318 #
4319 bd_uu3 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
4320 self.pg7.remote_ip4, 116)
4321 bd_uu3.add_vpp_config()
4322
4323 bd3 = VppBridgeDomain(self, 3)
4324 bd3.add_vpp_config()
4325 gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2,
4326 bd_uu3, learn=False)
4327 gbd3.add_vpp_config()
4328
Neale Ranns59f71132020-04-08 12:19:38 +00004329 ip4_addr3 = VppIpInterfaceAddress(self, gbd3.bvi,
4330 "12.0.0.128", 32,
4331 bind=b_lo2_ip4).add_vpp_config()
4332 ip6_addr3 = VppIpInterfaceAddress(self, gbd3.bvi,
4333 "4001:10::128", 128,
4334 bind=b_lo2_ip6).add_vpp_config()
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004335
4336 #
4337 # self.logger.info(self.vapi.cli("show gbp bridge"))
4338 # self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
4339 # self.logger.info(self.vapi.cli("show gbp vxlan"))
4340 # self.logger.info(self.vapi.cli("show int addr"))
4341 #
4342
4343 #
4344 # EPGs in which the service endpoints exist
4345 #
4346 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
4347 None, gbd3.bvi,
4348 "12.0.0.128",
4349 "4001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00004350 VppGbpEndpointRetention(60))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004351 epg_320.add_vpp_config()
4352
4353 #
4354 # endpoints
4355 #
4356 ep1 = VppGbpEndpoint(self, self.pg0,
4357 epg_220, None,
4358 "10.0.0.1", "11.0.0.1",
4359 "2001:10::1", "3001:10::1")
4360 ep1.add_vpp_config()
4361 ep2 = VppGbpEndpoint(self, self.pg1,
4362 epg_221, None,
4363 "10.0.1.1", "11.0.1.1",
4364 "2001:11::1", "3001:11::1")
4365 ep2.add_vpp_config()
4366
4367 #
4368 # service endpoints
4369 #
4370 sep1 = VppGbpEndpoint(self, self.pg3,
4371 epg_320, None,
4372 "12.0.0.1", "13.0.0.1",
4373 "4001:10::1", "5001:10::1")
4374 sep2 = VppGbpEndpoint(self, self.pg4,
4375 epg_320, None,
4376 "12.0.0.2", "13.0.0.2",
4377 "4001:10::2", "5001:10::2")
4378
4379 # sep1 and sep2 are not added to config yet
4380 # they are unknown for now
4381
4382 #
4383 # add routes to EPG subnets
4384 #
4385 VppGbpSubnet(self, rd1, "10.0.0.0", 24,
4386 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT
4387 ).add_vpp_config()
4388 VppGbpSubnet(self, rd1, "10.0.1.0", 24,
4389 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT
4390 ).add_vpp_config()
4391
4392 #
4393 # Local host to known local host in different BD
4394 # with SFC contract (source and destination are in
4395 # one node and service endpoint in another node)
4396 #
4397 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004398 IP(src=ep1.ip4, dst=ep2.ip4) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004399 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004400 Raw(b'\xa5' * 100)),
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004401 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004402 IP(src=ep2.ip4, dst=ep1.ip4) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004403 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004404 Raw(b'\xa5' * 100))]
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004405 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004406 IPv6(src=ep1.ip6, dst=ep2.ip6) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004407 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004408 Raw(b'\xa5' * 100)),
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004409 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004410 IPv6(src=ep2.ip6, dst=ep1.ip6) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004411 UDP(sport=1234, dport=1230) /
Ole Troan770a0de2019-11-07 13:52:21 +01004412 Raw(b'\xa5' * 100))]
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004413
4414 # should be dropped since no contract yet
4415 self.send_and_assert_no_replies(self.pg0, [p4[0]])
4416 self.send_and_assert_no_replies(self.pg0, [p6[0]])
4417
4418 #
4419 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
4420 # one of the next-hops is via an EP that is not known
4421 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004422 rule4 = AclRule(is_permit=1, proto=17)
4423 rule6 = AclRule(src_prefix=IPv6Network((0, 0)),
4424 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
4425 acl = VppAcl(self, rules=[rule4, rule6])
4426 acl.add_vpp_config()
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004427
4428 #
4429 # test the src-ip hash mode
4430 #
4431 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004432 self, 402, epg_220.sclass, epg_221.sclass, acl.acl_index,
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004433 [VppGbpContractRule(
4434 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4435 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
4436 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4437 sep1.ip4, sep1.epg.rd)]),
4438 VppGbpContractRule(
4439 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4440 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
4441 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4442 sep1.ip6, sep1.epg.rd)])],
4443 [ETH_P_IP, ETH_P_IPV6])
4444 c1.add_vpp_config()
4445
4446 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004447 self, 402, epg_221.sclass, epg_220.sclass, acl.acl_index,
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004448 [VppGbpContractRule(
4449 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4450 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
4451 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4452 sep1.ip4, sep1.epg.rd)]),
4453 VppGbpContractRule(
4454 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
4455 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
4456 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
4457 sep1.ip6, sep1.epg.rd)])],
4458 [ETH_P_IP, ETH_P_IPV6])
4459 c2.add_vpp_config()
4460
4461 # ep1 <--> ep2 redirected through sep1
4462 # sep1 is unknown
4463 # packet is redirected to sep bd and then go through sep bd UU
4464
4465 rxs = self.send_and_expect(self.pg0, p4[0] * 17, self.pg7)
4466
4467 for rx in rxs:
4468 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4469 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4470 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4471 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4472 self.assertEqual(rx[VXLAN].vni, 116)
4473 self.assertTrue(rx[VXLAN].flags.G)
4474 self.assertTrue(rx[VXLAN].flags.Instance)
4475 # redirect policy has been applied
4476 self.assertTrue(rx[VXLAN].gpflags.A)
4477 self.assertFalse(rx[VXLAN].gpflags.D)
4478
4479 inner = rx[VXLAN].payload
4480
4481 self.assertEqual(inner[Ether].src, routed_src_mac)
4482 self.assertEqual(inner[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004483 self.assertEqual(inner[IP].src, ep1.ip4)
4484 self.assertEqual(inner[IP].dst, ep2.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004485
4486 rxs = self.send_and_expect(self.pg1, p4[1] * 17, self.pg7)
4487
4488 for rx in rxs:
4489 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4490 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4491 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4492 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4493 self.assertEqual(rx[VXLAN].vni, 116)
4494 self.assertTrue(rx[VXLAN].flags.G)
4495 self.assertTrue(rx[VXLAN].flags.Instance)
4496 # redirect policy has been applied
4497 self.assertTrue(rx[VXLAN].gpflags.A)
4498 self.assertFalse(rx[VXLAN].gpflags.D)
4499
4500 inner = rx[VXLAN].payload
4501
4502 self.assertEqual(inner[Ether].src, routed_src_mac)
4503 self.assertEqual(inner[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004504 self.assertEqual(inner[IP].src, ep2.ip4)
4505 self.assertEqual(inner[IP].dst, ep1.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004506
4507 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
4508
4509 for rx in rxs:
4510 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4511 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4512 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4513 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4514 self.assertEqual(rx[VXLAN].vni, 116)
4515 self.assertTrue(rx[VXLAN].flags.G)
4516 self.assertTrue(rx[VXLAN].flags.Instance)
4517 # redirect policy has been applied
4518 inner = rx[VXLAN].payload
4519
4520 self.assertEqual(inner[Ether].src, routed_src_mac)
4521 self.assertEqual(inner[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004522 self.assertEqual(inner[IPv6].src, ep1.ip6)
4523 self.assertEqual(inner[IPv6].dst, ep2.ip6)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004524
4525 rxs = self.send_and_expect(self.pg1, p6[1] * 17, self.pg7)
4526
4527 for rx in rxs:
4528 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4529 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4530 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4531 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4532 self.assertEqual(rx[VXLAN].vni, 116)
4533 self.assertTrue(rx[VXLAN].flags.G)
4534 self.assertTrue(rx[VXLAN].flags.Instance)
4535 # redirect policy has been applied
4536 self.assertTrue(rx[VXLAN].gpflags.A)
4537 self.assertFalse(rx[VXLAN].gpflags.D)
4538
4539 inner = rx[VXLAN].payload
4540
4541 self.assertEqual(inner[Ether].src, routed_src_mac)
4542 self.assertEqual(inner[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004543 self.assertEqual(inner[IPv6].src, ep2.ip6)
4544 self.assertEqual(inner[IPv6].dst, ep1.ip6)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004545
4546 # configure sep1: it is now local
4547 # packets between ep1 and ep2 are redirected locally
4548 sep1.add_vpp_config()
4549
4550 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
4551
4552 for rx in rxs:
4553 self.assertEqual(rx[Ether].src, routed_src_mac)
4554 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004555 self.assertEqual(rx[IP].src, ep1.ip4)
4556 self.assertEqual(rx[IP].dst, ep2.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004557
4558 rxs = self.send_and_expect(self.pg1, p6[1] * 17, sep1.itf)
4559
4560 for rx in rxs:
4561 self.assertEqual(rx[Ether].src, routed_src_mac)
4562 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004563 self.assertEqual(rx[IPv6].src, ep2.ip6)
4564 self.assertEqual(rx[IPv6].dst, ep1.ip6)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004565
4566 # packet coming from the l2 spine-proxy to sep1
4567 p = (Ether(src=self.pg7.remote_mac,
4568 dst=self.pg7.local_mac) /
4569 IP(src=self.pg7.remote_ip4,
4570 dst=self.pg7.local_ip4) /
4571 UDP(sport=1234, dport=48879) /
4572 VXLAN(vni=116, gpid=440, gpflags=0x08, flags=0x88) /
4573 Ether(src=str(self.router_mac), dst=sep1.mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004574 IP(src=ep1.ip4, dst=ep2.ip4) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004575 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004576 Raw(b'\xa5' * 100))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004577
4578 rxs = self.send_and_expect(self.pg7, [p] * 17, sep1.itf)
4579
4580 for rx in rxs:
4581 self.assertEqual(rx[Ether].src, str(self.router_mac))
4582 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004583 self.assertEqual(rx[IP].src, ep1.ip4)
4584 self.assertEqual(rx[IP].dst, ep2.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004585
4586 # contract for SEP to communicate with dst EP
4587 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004588 self, 402, epg_320.sclass, epg_221.sclass, acl.acl_index,
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004589 [VppGbpContractRule(
4590 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4591 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC),
4592 VppGbpContractRule(
4593 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4594 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC)],
4595 [ETH_P_IP, ETH_P_IPV6])
4596 c3.add_vpp_config()
4597
4598 # temporarily remove ep2, so that ep2 is remote & unknown
4599 ep2.remove_vpp_config()
4600
4601 # packet going back from sep1 to its original dest (ep2)
4602 # as ep2 is now unknown (see above), it must go through
4603 # the rd UU (packet is routed)
4604
4605 p1 = (Ether(src=sep1.mac, dst=self.router_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004606 IP(src=ep1.ip4, dst=ep2.ip4) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004607 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004608 Raw(b'\xa5' * 100))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004609
4610 rxs = self.send_and_expect(self.pg3, [p1] * 17, self.pg7)
4611
4612 for rx in rxs:
4613 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4614 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4615 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4616 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4617 self.assertEqual(rx[VXLAN].vni, 114)
4618 self.assertTrue(rx[VXLAN].flags.G)
4619 self.assertTrue(rx[VXLAN].flags.Instance)
4620 # redirect policy has been applied
4621 inner = rx[VXLAN].payload
4622 self.assertEqual(inner[Ether].src, routed_src_mac)
4623 self.assertEqual(inner[Ether].dst, routed_dst_mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004624 self.assertEqual(inner[IP].src, ep1.ip4)
4625 self.assertEqual(inner[IP].dst, ep2.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004626
4627 self.logger.info(self.vapi.cli("show bridge 3 detail"))
4628 sep1.remove_vpp_config()
4629
4630 self.logger.info(self.vapi.cli("show bridge 1 detail"))
4631 self.logger.info(self.vapi.cli("show bridge 2 detail"))
4632
4633 # re-add ep2: it is local again :)
4634 ep2.add_vpp_config()
4635
4636 # packet coming back from the remote sep through rd UU
4637 p2 = (Ether(src=self.pg7.remote_mac,
4638 dst=self.pg7.local_mac) /
4639 IP(src=self.pg7.remote_ip4,
4640 dst=self.pg7.local_ip4) /
4641 UDP(sport=1234, dport=48879) /
4642 VXLAN(vni=114, gpid=441, gpflags=0x09, flags=0x88) /
4643 Ether(src=str(self.router_mac), dst=self.router_mac) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004644 IP(src=ep1.ip4, dst=ep2.ip4) /
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004645 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004646 Raw(b'\xa5' * 100))
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004647
4648 rxs = self.send_and_expect(self.pg7, [p2], self.pg1)
4649
4650 for rx in rxs:
4651 self.assertEqual(rx[Ether].src, str(self.router_mac))
4652 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
Neale Rannsefd7bc22019-11-11 08:32:34 +00004653 self.assertEqual(rx[IP].src, ep1.ip4)
4654 self.assertEqual(rx[IP].dst, ep2.ip4)
Mohsin Kazmia3c8ca12019-07-10 18:45:55 +02004655
4656 #
4657 # bd_uu2.add_vpp_config()
4658 #
4659
4660 #
4661 # cleanup
4662 #
4663 c1.remove_vpp_config()
4664 c2.remove_vpp_config()
4665 c3.remove_vpp_config()
4666 self.pg7.unconfig_ip4()
4667
Neale Rannsb6a47952018-11-21 05:44:35 -08004668 def test_gbp_l3_out(self):
4669 """ GBP L3 Out """
4670
4671 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04004672 self.vapi.cli("set logging class gbp level debug")
Neale Rannsb6a47952018-11-21 05:44:35 -08004673
4674 routed_dst_mac = "00:0c:0c:0c:0c:0c"
4675 routed_src_mac = "00:22:bd:f8:19:ff"
4676
4677 #
4678 # IP tables
4679 #
4680 t4 = VppIpTable(self, 1)
4681 t4.add_vpp_config()
4682 t6 = VppIpTable(self, 1, True)
4683 t6.add_vpp_config()
4684
Neale Ranns160c9232019-06-19 06:25:56 -07004685 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
Neale Rannsb6a47952018-11-21 05:44:35 -08004686 rd1.add_vpp_config()
4687
Ole Troan8006c6a2018-12-17 12:02:26 +01004688 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08004689
4690 #
4691 # Bind the BVI to the RD
4692 #
Neale Ranns59f71132020-04-08 12:19:38 +00004693 b_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
4694 b_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
Neale Rannsb6a47952018-11-21 05:44:35 -08004695
4696 #
4697 # Pg7 hosts a BD's BUM
4698 # Pg1 some other l3 interface
4699 #
4700 self.pg7.config_ip4()
4701 self.pg7.resolve_arp()
4702
4703 #
Neale Ranns879d11c2019-01-21 23:34:18 -08004704 # a multicast vxlan-gbp tunnel for broadcast in the BD
4705 #
4706 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
4707 "239.1.1.1", 88,
4708 mcast_itf=self.pg7)
4709 tun_bm.add_vpp_config()
4710
4711 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004712 # a GBP external bridge domains for the EPs
4713 #
4714 bd1 = VppBridgeDomain(self, 1)
4715 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07004716 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08004717 gbd1.add_vpp_config()
4718
4719 #
4720 # The Endpoint-groups in which the external endpoints exist
4721 #
Neale Ranns879d11c2019-01-21 23:34:18 -08004722 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08004723 None, gbd1.bvi,
4724 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08004725 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00004726 VppGbpEndpointRetention(4))
Neale Rannsb6a47952018-11-21 05:44:35 -08004727 epg_220.add_vpp_config()
4728
4729 # the BVIs have the subnets applied ...
Neale Ranns59f71132020-04-08 12:19:38 +00004730 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128",
4731 24, bind=b_ip4).add_vpp_config()
4732 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128",
4733 64, bind=b_ip6).add_vpp_config()
Neale Rannsb6a47952018-11-21 05:44:35 -08004734
4735 # ... which are L3-out subnets
4736 l3o_1 = VppGbpSubnet(
4737 self, rd1, "10.0.0.0", 24,
4738 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004739 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08004740 l3o_1.add_vpp_config()
4741
4742 #
4743 # an external interface attached to the outside world and the
4744 # external BD
4745 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004746 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
4747 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00004748 vlan_144 = VppDot1QSubint(self, self.pg0, 144)
4749 vlan_144.admin_up()
Benoît Ganne286921e2019-06-05 19:08:40 +02004750 # vlan_102 is not poped
Neale Ranns36abbf12019-03-12 02:34:07 -07004751
Neale Rannsb6a47952018-11-21 05:44:35 -08004752 #
Neale Ranns879d11c2019-01-21 23:34:18 -08004753 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08004754 #
4755 vx_tun_l3 = VppGbpVxlanTunnel(
4756 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08004757 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
4758 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08004759 vx_tun_l3.add_vpp_config()
4760
4761 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004762 # External Endpoints
4763 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004764 eep1 = VppGbpEndpoint(self, self.vlan_100,
Neale Ranns36abbf12019-03-12 02:34:07 -07004765 epg_220, None,
4766 "10.0.0.1", "11.0.0.1",
4767 "2001:10::1", "3001::1",
4768 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
4769 eep1.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004770 eep2 = VppGbpEndpoint(self, self.vlan_101,
Neale Ranns36abbf12019-03-12 02:34:07 -07004771 epg_220, None,
4772 "10.0.0.2", "11.0.0.2",
4773 "2001:10::2", "3001::2",
4774 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
4775 eep2.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004776 eep3 = VppGbpEndpoint(self, self.vlan_102,
Benoît Ganne286921e2019-06-05 19:08:40 +02004777 epg_220, None,
4778 "10.0.0.3", "11.0.0.3",
4779 "2001:10::3", "3001::3",
4780 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
4781 eep3.add_vpp_config()
Neale Ranns36abbf12019-03-12 02:34:07 -07004782
4783 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004784 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07004785 #
4786 rep = VppGbpEndpoint(self, vx_tun_l3,
4787 epg_220, None,
4788 "10.0.0.101", "11.0.0.101",
4789 "2001:10::101", "3001::101",
4790 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
4791 self.pg7.local_ip4,
4792 self.pg7.remote_ip4,
4793 mac=None)
4794 rep.add_vpp_config()
4795
4796 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02004797 # EP1 impersonating EP3 is dropped
4798 #
4799 p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
4800 Dot1Q(vlan=100) /
4801 ARP(op="who-has",
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004802 psrc="10.0.0.3", pdst="10.0.0.128",
4803 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Gannec47b97d2019-06-06 17:53:21 +02004804 self.send_and_assert_no_replies(self.pg0, p)
4805
4806 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07004807 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07004808 #
4809 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
4810 Dot1Q(vlan=100) /
4811 ARP(op="who-has",
Neale Rannsefd7bc22019-11-11 08:32:34 +00004812 psrc=eep1.ip4, pdst="10.0.0.128",
Neale Ranns4c2bff02019-03-14 02:52:27 -07004813 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
4814 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
4815
4816 #
Benoît Ganne286921e2019-06-05 19:08:40 +02004817 # ARP packet from host in remote subnet are accepted and replied to
4818 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02004819 p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") /
Benoît Ganne286921e2019-06-05 19:08:40 +02004820 Dot1Q(vlan=102) /
4821 ARP(op="who-has",
Neale Rannsefd7bc22019-11-11 08:32:34 +00004822 psrc=eep3.ip4, pdst="10.0.0.128",
Benoît Gannec47b97d2019-06-06 17:53:21 +02004823 hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Ganne286921e2019-06-05 19:08:40 +02004824 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
4825
4826 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07004827 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08004828 # are ARP'd for
4829 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004830 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004831 Dot1Q(vlan=100) /
4832 IP(src="10.0.0.1", dst="10.0.0.88") /
4833 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004834 Raw(b'\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07004835 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004836 Dot1Q(vlan=100) /
4837 IPv6(src="2001:10::1", dst="2001:10::88") /
4838 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004839 Raw(b'\xa5' * 100))
Neale Rannsb6a47952018-11-21 05:44:35 -08004840
4841 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
4842
4843 for rx in rxs:
4844 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4845 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4846 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4847 self.assertEqual(rx[IP].dst, "239.1.1.1")
4848 self.assertEqual(rx[VXLAN].vni, 88)
4849 self.assertTrue(rx[VXLAN].flags.G)
4850 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08004851 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08004852 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08004853 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08004854 self.assertFalse(rx[VXLAN].gpflags.D)
4855
4856 inner = rx[VXLAN].payload
4857
4858 self.assertTrue(inner.haslayer(ARP))
4859
4860 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004861 # remote to external
4862 #
4863 p = (Ether(src=self.pg7.remote_mac,
4864 dst=self.pg7.local_mac) /
4865 IP(src=self.pg7.remote_ip4,
4866 dst=self.pg7.local_ip4) /
4867 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08004868 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01004869 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004870 IP(src="10.0.0.101", dst="10.0.0.1") /
4871 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01004872 Raw(b'\xa5' * 100))
Neale Rannsb6a47952018-11-21 05:44:35 -08004873
4874 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4875
4876 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004877 # local EP pings router
4878 #
4879 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4880 Dot1Q(vlan=100) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004881 IP(src=eep1.ip4, dst="10.0.0.128") /
Neale Ranns36abbf12019-03-12 02:34:07 -07004882 ICMP(type='echo-request'))
4883
4884 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4885
4886 for rx in rxs:
4887 self.assertEqual(rx[Ether].src, str(self.router_mac))
4888 self.assertEqual(rx[Ether].dst, eep1.mac)
4889 self.assertEqual(rx[Dot1Q].vlan, 100)
4890
4891 #
4892 # local EP pings other local EP
4893 #
4894 p = (Ether(src=eep1.mac, dst=eep2.mac) /
4895 Dot1Q(vlan=100) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004896 IP(src=eep1.ip4, dst=eep2.ip4) /
Neale Ranns36abbf12019-03-12 02:34:07 -07004897 ICMP(type='echo-request'))
4898
4899 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4900
4901 for rx in rxs:
4902 self.assertEqual(rx[Ether].src, eep1.mac)
4903 self.assertEqual(rx[Ether].dst, eep2.mac)
4904 self.assertEqual(rx[Dot1Q].vlan, 101)
4905
4906 #
Benoît Ganne286921e2019-06-05 19:08:40 +02004907 # local EP pings router w/o vlan tag poped
4908 #
4909 p = (Ether(src=eep3.mac, dst=str(self.router_mac)) /
4910 Dot1Q(vlan=102) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00004911 IP(src=eep3.ip4, dst="10.0.0.128") /
Benoît Ganne286921e2019-06-05 19:08:40 +02004912 ICMP(type='echo-request'))
4913
4914 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4915
4916 for rx in rxs:
4917 self.assertEqual(rx[Ether].src, str(self.router_mac))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004918 self.assertEqual(rx[Ether].dst, self.vlan_102.remote_mac)
Benoît Ganne286921e2019-06-05 19:08:40 +02004919
4920 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004921 # A ip4 subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08004922 #
4923 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +00004924 [VppRoutePath(eep1.ip4,
Neale Ranns36abbf12019-03-12 02:34:07 -07004925 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08004926 table_id=t4.table_id)
4927 ip_220.add_vpp_config()
4928
4929 l3o_220 = VppGbpSubnet(
4930 self, rd1, "10.220.0.0", 24,
4931 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004932 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08004933 l3o_220.add_vpp_config()
4934
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004935 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004936 # An ip6 subnet reachable through the external EP1
4937 #
4938 ip6_220 = VppIpRoute(self, "10:220::", 64,
Neale Rannsefd7bc22019-11-11 08:32:34 +00004939 [VppRoutePath(eep1.ip6,
Neale Ranns69a85b52019-06-14 07:49:50 +00004940 eep1.epg.bvi.sw_if_index)],
4941 table_id=t6.table_id)
4942 ip6_220.add_vpp_config()
4943
4944 l3o6_220 = VppGbpSubnet(
4945 self, rd1, "10:220::", 64,
4946 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4947 sclass=4220)
4948 l3o6_220.add_vpp_config()
4949
4950 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004951 # A subnet reachable through the external EP2
4952 #
4953 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +00004954 [VppRoutePath(eep2.ip4,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004955 eep2.epg.bvi.sw_if_index)],
4956 table_id=t4.table_id)
4957 ip_221.add_vpp_config()
4958
4959 l3o_221 = VppGbpSubnet(
4960 self, rd1, "10.221.0.0", 24,
4961 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4962 sclass=4221)
4963 l3o_221.add_vpp_config()
4964
4965 #
4966 # ping between hosts in remote subnets
4967 # dropped without a contract
4968 #
4969 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4970 Dot1Q(vlan=100) /
4971 IP(src="10.220.0.1", dst="10.221.0.1") /
4972 ICMP(type='echo-request'))
4973
Neale Ranns160c9232019-06-19 06:25:56 -07004974 self.send_and_assert_no_replies(self.pg0, p * 1)
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004975
4976 #
4977 # contract for the external nets to communicate
4978 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004979 rule4 = AclRule(is_permit=1, proto=17)
4980 rule6 = AclRule(src_prefix=IPv6Network((0, 0)),
4981 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
4982 acl = VppAcl(self, rules=[rule4, rule6])
4983 acl.add_vpp_config()
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004984
Neale Ranns160c9232019-06-19 06:25:56 -07004985 #
4986 # A contract with the wrong scope is not matched
4987 #
4988 c_44 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01004989 self, 44, 4220, 4221, acl.acl_index,
Neale Ranns160c9232019-06-19 06:25:56 -07004990 [VppGbpContractRule(
4991 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Rannsbb098f12019-10-22 12:32:49 +00004992 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns160c9232019-06-19 06:25:56 -07004993 []),
Neale Rannsbb098f12019-10-22 12:32:49 +00004994 VppGbpContractRule(
4995 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4996 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4997 [])],
Neale Ranns160c9232019-06-19 06:25:56 -07004998 [ETH_P_IP, ETH_P_IPV6])
4999 c_44.add_vpp_config()
5000 self.send_and_assert_no_replies(self.pg0, p * 1)
5001
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005002 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005003 self, 55, 4220, 4221, acl.acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005004 [VppGbpContractRule(
5005 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005006 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005007 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02005008 VppGbpContractRule(
5009 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005010 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02005011 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005012 [ETH_P_IP, ETH_P_IPV6])
5013 c1.add_vpp_config()
5014
5015 #
5016 # Contracts allowing ext-net 200 to talk with external EPs
5017 #
5018 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005019 self, 55, 4220, 113, acl.acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005020 [VppGbpContractRule(
5021 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005022 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005023 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02005024 VppGbpContractRule(
5025 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005026 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02005027 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005028 [ETH_P_IP, ETH_P_IPV6])
5029 c2.add_vpp_config()
5030 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005031 self, 55, 113, 4220, acl.acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005032 [VppGbpContractRule(
5033 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005034 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005035 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02005036 VppGbpContractRule(
5037 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005038 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02005039 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005040 [ETH_P_IP, ETH_P_IPV6])
5041 c3.add_vpp_config()
5042
5043 #
5044 # ping between hosts in remote subnets
5045 #
5046 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5047 Dot1Q(vlan=100) /
5048 IP(src="10.220.0.1", dst="10.221.0.1") /
5049 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005050 Raw(b'\xa5' * 100))
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005051
5052 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5053
5054 for rx in rxs:
5055 self.assertEqual(rx[Ether].src, str(self.router_mac))
5056 self.assertEqual(rx[Ether].dst, eep2.mac)
5057 self.assertEqual(rx[Dot1Q].vlan, 101)
5058
5059 # we did not learn these external hosts
5060 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
5061 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
5062
5063 #
5064 # from remote external EP to local external EP
5065 #
Neale Rannsb6a47952018-11-21 05:44:35 -08005066 p = (Ether(src=self.pg7.remote_mac,
5067 dst=self.pg7.local_mac) /
5068 IP(src=self.pg7.remote_ip4,
5069 dst=self.pg7.local_ip4) /
5070 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08005071 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01005072 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08005073 IP(src="10.0.0.101", dst="10.220.0.1") /
5074 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005075 Raw(b'\xa5' * 100))
Neale Rannsb6a47952018-11-21 05:44:35 -08005076
5077 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
5078
5079 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005080 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07005081 #
5082 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5083 Dot1Q(vlan=100) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005084 IP(src="10.220.0.1", dst=rep.ip4) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005085 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005086 Raw(b'\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07005087
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005088 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07005089
5090 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005091 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
5092 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
5093 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
5094 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
5095 self.assertEqual(rx[VXLAN].vni, 444)
5096 self.assertTrue(rx[VXLAN].flags.G)
5097 self.assertTrue(rx[VXLAN].flags.Instance)
5098 # the sclass of the ext-net the packet came from
5099 self.assertEqual(rx[VXLAN].gpid, 4220)
5100 # policy was applied to the original IP packet
5101 self.assertTrue(rx[VXLAN].gpflags.A)
5102 # since it's an external host the reciever should not learn it
5103 self.assertTrue(rx[VXLAN].gpflags.D)
5104 inner = rx[VXLAN].payload
5105 self.assertEqual(inner[IP].src, "10.220.0.1")
Neale Rannsefd7bc22019-11-11 08:32:34 +00005106 self.assertEqual(inner[IP].dst, rep.ip4)
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005107
5108 #
5109 # An external subnet reachable via the remote external EP
5110 #
5111
5112 #
5113 # first the VXLAN-GBP tunnel over which it is reached
5114 #
Neale Ranns69a85b52019-06-14 07:49:50 +00005115 vx_tun_r1 = VppVxlanGbpTunnel(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005116 self, self.pg7.local_ip4,
5117 self.pg7.remote_ip4, 445,
5118 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
5119 VXLAN_GBP_API_TUNNEL_MODE_L3))
Neale Ranns69a85b52019-06-14 07:49:50 +00005120 vx_tun_r1.add_vpp_config()
5121 VppIpInterfaceBind(self, vx_tun_r1, t4).add_vpp_config()
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005122
5123 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
5124
5125 #
5126 # then the special adj to resolve through on that tunnel
5127 #
5128 n1 = VppNeighbor(self,
Neale Ranns69a85b52019-06-14 07:49:50 +00005129 vx_tun_r1.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005130 "00:0c:0c:0c:0c:0c",
5131 self.pg7.remote_ip4)
5132 n1.add_vpp_config()
5133
5134 #
5135 # the route via the adj above
5136 #
5137 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
5138 [VppRoutePath(self.pg7.remote_ip4,
Neale Ranns69a85b52019-06-14 07:49:50 +00005139 vx_tun_r1.sw_if_index)],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005140 table_id=t4.table_id)
5141 ip_222.add_vpp_config()
5142
5143 l3o_222 = VppGbpSubnet(
5144 self, rd1, "10.222.0.0", 24,
5145 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5146 sclass=4222)
5147 l3o_222.add_vpp_config()
5148
5149 #
5150 # ping between hosts in local and remote external subnets
5151 # dropped without a contract
5152 #
5153 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5154 Dot1Q(vlan=100) /
5155 IP(src="10.220.0.1", dst="10.222.0.1") /
5156 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005157 Raw(b'\xa5' * 100))
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005158
5159 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
5160
5161 #
5162 # Add contracts ext-nets for 220 -> 222
5163 #
5164 c4 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005165 self, 55, 4220, 4222, acl.acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005166 [VppGbpContractRule(
5167 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005168 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005169 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02005170 VppGbpContractRule(
5171 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04005172 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02005173 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005174 [ETH_P_IP, ETH_P_IPV6])
5175 c4.add_vpp_config()
5176
5177 #
5178 # ping from host in local to remote external subnets
5179 #
5180 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5181 Dot1Q(vlan=100) /
5182 IP(src="10.220.0.1", dst="10.222.0.1") /
5183 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005184 Raw(b'\xa5' * 100))
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005185
5186 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
5187
5188 for rx in rxs:
5189 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
5190 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
5191 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
5192 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
5193 self.assertEqual(rx[VXLAN].vni, 445)
5194 self.assertTrue(rx[VXLAN].flags.G)
5195 self.assertTrue(rx[VXLAN].flags.Instance)
5196 # the sclass of the ext-net the packet came from
5197 self.assertEqual(rx[VXLAN].gpid, 4220)
5198 # policy was applied to the original IP packet
5199 self.assertTrue(rx[VXLAN].gpflags.A)
5200 # since it's an external host the reciever should not learn it
5201 self.assertTrue(rx[VXLAN].gpflags.D)
5202 inner = rx[VXLAN].payload
5203 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
5204 self.assertEqual(inner[IP].src, "10.220.0.1")
5205 self.assertEqual(inner[IP].dst, "10.222.0.1")
5206
5207 #
Neale Ranns69a85b52019-06-14 07:49:50 +00005208 # make the external subnet ECMP
5209 #
5210 vx_tun_r2 = VppVxlanGbpTunnel(
5211 self, self.pg7.local_ip4,
5212 self.pg7.remote_ip4, 446,
5213 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
5214 VXLAN_GBP_API_TUNNEL_MODE_L3))
5215 vx_tun_r2.add_vpp_config()
5216 VppIpInterfaceBind(self, vx_tun_r2, t4).add_vpp_config()
5217
5218 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
5219
5220 n2 = VppNeighbor(self,
5221 vx_tun_r2.sw_if_index,
5222 "00:0c:0c:0c:0c:0c",
5223 self.pg7.remote_ip4)
5224 n2.add_vpp_config()
5225
5226 ip_222.modify([VppRoutePath(self.pg7.remote_ip4,
5227 vx_tun_r1.sw_if_index),
5228 VppRoutePath(self.pg7.remote_ip4,
5229 vx_tun_r2.sw_if_index)])
5230
5231 #
5232 # now expect load-balance
5233 #
5234 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
5235 Dot1Q(vlan=100) /
5236 IP(src="10.220.0.1", dst="10.222.0.1") /
5237 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005238 Raw(b'\xa5' * 100)),
Neale Ranns69a85b52019-06-14 07:49:50 +00005239 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5240 Dot1Q(vlan=100) /
5241 IP(src="10.220.0.1", dst="10.222.0.1") /
5242 UDP(sport=1222, dport=1235) /
Ole Troan770a0de2019-11-07 13:52:21 +01005243 Raw(b'\xa5' * 100))]
Neale Ranns69a85b52019-06-14 07:49:50 +00005244
5245 rxs = self.send_and_expect(self.pg0, p, self.pg7)
5246
5247 self.assertEqual(rxs[0][VXLAN].vni, 445)
5248 self.assertEqual(rxs[1][VXLAN].vni, 446)
5249
5250 #
5251 # Same LB test for v6
5252 #
5253 n3 = VppNeighbor(self,
5254 vx_tun_r1.sw_if_index,
5255 "00:0c:0c:0c:0c:0c",
5256 self.pg7.remote_ip6)
5257 n3.add_vpp_config()
5258 n4 = VppNeighbor(self,
5259 vx_tun_r2.sw_if_index,
5260 "00:0c:0c:0c:0c:0c",
5261 self.pg7.remote_ip6)
5262 n4.add_vpp_config()
5263
5264 ip_222_6 = VppIpRoute(self, "10:222::", 64,
5265 [VppRoutePath(self.pg7.remote_ip6,
5266 vx_tun_r1.sw_if_index),
5267 VppRoutePath(self.pg7.remote_ip6,
5268 vx_tun_r2.sw_if_index)],
5269 table_id=t6.table_id)
5270 ip_222_6.add_vpp_config()
5271
5272 l3o_222_6 = VppGbpSubnet(
5273 self, rd1, "10:222::", 64,
5274 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5275 sclass=4222)
5276 l3o_222_6.add_vpp_config()
5277
5278 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
5279 Dot1Q(vlan=100) /
5280 IPv6(src="10:220::1", dst="10:222::1") /
5281 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005282 Raw(b'\xa5' * 100)),
Neale Ranns69a85b52019-06-14 07:49:50 +00005283 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
5284 Dot1Q(vlan=100) /
5285 IPv6(src="10:220::1", dst="10:222::1") /
5286 UDP(sport=7777, dport=8881) /
Ole Troan770a0de2019-11-07 13:52:21 +01005287 Raw(b'\xa5' * 100))]
Neale Ranns69a85b52019-06-14 07:49:50 +00005288
5289 self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1"))
5290 rxs = self.send_and_expect(self.pg0, p, self.pg7)
5291
Neale Ranns3d5f08a2021-01-22 16:12:38 +00005292 self.assertEqual(rxs[0][VXLAN].vni, 445)
5293 self.assertEqual(rxs[1][VXLAN].vni, 446)
Neale Ranns69a85b52019-06-14 07:49:50 +00005294
5295 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005296 # ping from host in remote to local external subnets
5297 # there's no contract for this, but the A bit is set.
5298 #
5299 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5300 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5301 UDP(sport=1234, dport=48879) /
5302 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5303 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5304 IP(src="10.222.0.1", dst="10.220.0.1") /
5305 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005306 Raw(b'\xa5' * 100))
Neale Ranns4dd4cf42019-03-27 05:06:47 -07005307
5308 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
5309 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07005310
5311 #
Neale Ranns2b600182019-03-29 05:08:27 -07005312 # ping from host in remote to remote external subnets
5313 # this is dropped by reflection check.
5314 #
5315 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5316 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5317 UDP(sport=1234, dport=48879) /
5318 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5319 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5320 IP(src="10.222.0.1", dst="10.222.0.2") /
5321 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005322 Raw(b'\xa5' * 100))
Neale Ranns2b600182019-03-29 05:08:27 -07005323
5324 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
5325
Neale Ranns69a85b52019-06-14 07:49:50 +00005326 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5327 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5328 UDP(sport=1234, dport=48879) /
5329 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5330 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5331 IPv6(src="10:222::1", dst="10:222::2") /
5332 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005333 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00005334
5335 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
5336
5337 #
5338 # local EP
5339 #
5340 lep1 = VppGbpEndpoint(self, vlan_144,
5341 epg_220, None,
5342 "10.0.0.44", "11.0.0.44",
5343 "2001:10::44", "3001::44")
5344 lep1.add_vpp_config()
5345
5346 #
5347 # local EP to local ip4 external subnet
5348 #
5349 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
5350 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005351 IP(src=lep1.ip4, dst="10.220.0.1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005352 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005353 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00005354
5355 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5356
5357 for rx in rxs:
5358 self.assertEqual(rx[Ether].src, str(self.router_mac))
5359 self.assertEqual(rx[Ether].dst, eep1.mac)
5360 self.assertEqual(rx[Dot1Q].vlan, 100)
5361
5362 #
5363 # local EP to local ip6 external subnet
5364 #
5365 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
5366 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005367 IPv6(src=lep1.ip6, dst="10:220::1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005368 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005369 Raw(b'\xa5' * 100))
Neale Ranns69a85b52019-06-14 07:49:50 +00005370
5371 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5372
5373 for rx in rxs:
5374 self.assertEqual(rx[Ether].src, str(self.router_mac))
5375 self.assertEqual(rx[Ether].dst, eep1.mac)
5376 self.assertEqual(rx[Dot1Q].vlan, 100)
5377
5378 #
5379 # ip4 and ip6 subnets that load-balance
5380 #
5381 ip_20 = VppIpRoute(self, "10.20.0.0", 24,
Neale Rannsefd7bc22019-11-11 08:32:34 +00005382 [VppRoutePath(eep1.ip4,
Neale Ranns69a85b52019-06-14 07:49:50 +00005383 eep1.epg.bvi.sw_if_index),
Neale Rannsefd7bc22019-11-11 08:32:34 +00005384 VppRoutePath(eep2.ip4,
Neale Ranns69a85b52019-06-14 07:49:50 +00005385 eep2.epg.bvi.sw_if_index)],
5386 table_id=t4.table_id)
5387 ip_20.add_vpp_config()
5388
5389 l3o_20 = VppGbpSubnet(
5390 self, rd1, "10.20.0.0", 24,
5391 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5392 sclass=4220)
5393 l3o_20.add_vpp_config()
5394
5395 ip6_20 = VppIpRoute(self, "10:20::", 64,
Neale Rannsefd7bc22019-11-11 08:32:34 +00005396 [VppRoutePath(eep1.ip6,
Neale Ranns69a85b52019-06-14 07:49:50 +00005397 eep1.epg.bvi.sw_if_index),
Neale Rannsefd7bc22019-11-11 08:32:34 +00005398 VppRoutePath(eep2.ip6,
Neale Ranns69a85b52019-06-14 07:49:50 +00005399 eep2.epg.bvi.sw_if_index)],
5400 table_id=t6.table_id)
5401 ip6_20.add_vpp_config()
5402
5403 l3o6_20 = VppGbpSubnet(
5404 self, rd1, "10:20::", 64,
5405 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5406 sclass=4220)
5407 l3o6_20.add_vpp_config()
5408
5409 self.logger.info(self.vapi.cli("sh ip fib 10.20.0.1"))
5410 self.logger.info(self.vapi.cli("sh ip6 fib 10:20::1"))
5411
5412 # two ip6 packets whose port are chosen so they load-balance
5413 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
5414 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005415 IPv6(src=lep1.ip6, dst="10:20::1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005416 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005417 Raw(b'\xa5' * 100)),
Neale Ranns69a85b52019-06-14 07:49:50 +00005418 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
5419 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005420 IPv6(src=lep1.ip6, dst="10:20::1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005421 UDP(sport=124, dport=1230) /
Ole Troan770a0de2019-11-07 13:52:21 +01005422 Raw(b'\xa5' * 100))]
Neale Ranns69a85b52019-06-14 07:49:50 +00005423
5424 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
5425
Neale Ranns3d5f08a2021-01-22 16:12:38 +00005426 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
5427 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
Neale Ranns69a85b52019-06-14 07:49:50 +00005428
5429 # two ip4 packets whose port are chosen so they load-balance
5430 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
5431 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005432 IP(src=lep1.ip4, dst="10.20.0.1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005433 UDP(sport=1235, dport=1235) /
Ole Troan770a0de2019-11-07 13:52:21 +01005434 Raw(b'\xa5' * 100)),
Neale Ranns69a85b52019-06-14 07:49:50 +00005435 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
5436 Dot1Q(vlan=144) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005437 IP(src=lep1.ip4, dst="10.20.0.1") /
Neale Ranns69a85b52019-06-14 07:49:50 +00005438 UDP(sport=124, dport=1230) /
Ole Troan770a0de2019-11-07 13:52:21 +01005439 Raw(b'\xa5' * 100))]
Neale Ranns69a85b52019-06-14 07:49:50 +00005440
5441 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
5442
5443 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
5444 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
5445
Neale Ranns2b600182019-03-29 05:08:27 -07005446 #
Neale Rannsb6a47952018-11-21 05:44:35 -08005447 # cleanup
5448 #
Neale Ranns69a85b52019-06-14 07:49:50 +00005449 ip_222.remove_vpp_config()
Neale Rannsb6a47952018-11-21 05:44:35 -08005450 self.pg7.unconfig_ip4()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005451 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
5452 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
5453
5454 def test_gbp_anon_l3_out(self):
5455 """ GBP Anonymous L3 Out """
5456
5457 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
5458 self.vapi.cli("set logging class gbp level debug")
5459
5460 routed_dst_mac = "00:0c:0c:0c:0c:0c"
5461 routed_src_mac = "00:22:bd:f8:19:ff"
5462
5463 #
5464 # IP tables
5465 #
5466 t4 = VppIpTable(self, 1)
5467 t4.add_vpp_config()
5468 t6 = VppIpTable(self, 1, True)
5469 t6.add_vpp_config()
5470
5471 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
5472 rd1.add_vpp_config()
5473
5474 self.loop0.set_mac(self.router_mac)
5475
5476 #
5477 # Bind the BVI to the RD
5478 #
Neale Ranns59f71132020-04-08 12:19:38 +00005479 bind_l0_ip4 = VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
5480 bind_l0_ip6 = VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005481
5482 #
5483 # Pg7 hosts a BD's BUM
5484 # Pg1 some other l3 interface
5485 #
5486 self.pg7.config_ip4()
5487 self.pg7.resolve_arp()
5488
5489 #
5490 # a GBP external bridge domains for the EPs
5491 #
5492 bd1 = VppBridgeDomain(self, 1)
5493 bd1.add_vpp_config()
5494 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, None)
5495 gbd1.add_vpp_config()
5496
5497 #
5498 # The Endpoint-groups in which the external endpoints exist
5499 #
5500 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
5501 None, gbd1.bvi,
5502 "10.0.0.128",
5503 "2001:10::128",
Neale Ranns8d0d8d22020-04-07 08:44:20 +00005504 VppGbpEndpointRetention(4))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005505 epg_220.add_vpp_config()
5506
5507 # the BVIs have the subnet applied ...
Neale Ranns59f71132020-04-08 12:19:38 +00005508 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi,
5509 "10.0.0.128", 24,
5510 bind=bind_l0_ip4).add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005511
5512 # ... which is an Anonymous L3-out subnets
5513 l3o_1 = VppGbpSubnet(
5514 self, rd1, "10.0.0.0", 24,
5515 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_ANON_L3_OUT,
5516 sclass=113)
5517 l3o_1.add_vpp_config()
5518
5519 #
5520 # an external interface attached to the outside world and the
5521 # external BD
5522 #
5523 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
5524 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
5525
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005526 #
5527 # vlan_100 and vlan_101 are anonymous l3-out interfaces
5528 #
5529 ext_itf = VppGbpExtItf(self, self.vlan_100, bd1, rd1, anon=True)
5530 ext_itf.add_vpp_config()
5531 ext_itf = VppGbpExtItf(self, self.vlan_101, bd1, rd1, anon=True)
5532 ext_itf.add_vpp_config()
5533
5534 #
5535 # an unicast vxlan-gbp for inter-RD traffic
5536 #
5537 vx_tun_l3 = VppGbpVxlanTunnel(
5538 self, 444, rd1.rd_id,
5539 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
5540 self.pg2.local_ip4)
5541 vx_tun_l3.add_vpp_config()
5542
5543 #
5544 # A remote external endpoint
5545 #
5546 rep = VppGbpEndpoint(self, vx_tun_l3,
5547 epg_220, None,
5548 "10.0.0.201", "11.0.0.201",
5549 "2001:10::201", "3001::101",
5550 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
5551 self.pg7.local_ip4,
5552 self.pg7.remote_ip4,
5553 mac=None)
5554 rep.add_vpp_config()
5555
5556 #
5557 # ARP packet from host in external subnet are accepted, flooded and
5558 # replied to. We expect 2 packets:
5559 # - APR request flooded over the other vlan subif
5560 # - ARP reply from BVI
5561 #
5562 p_arp = (Ether(src=self.vlan_100.remote_mac,
5563 dst="ff:ff:ff:ff:ff:ff") /
5564 Dot1Q(vlan=100) /
5565 ARP(op="who-has",
5566 psrc="10.0.0.100",
5567 pdst="10.0.0.128",
5568 hwsrc=self.vlan_100.remote_mac,
5569 hwdst="ff:ff:ff:ff:ff:ff"))
5570 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
5571
5572 p_arp = (Ether(src=self.vlan_101.remote_mac,
5573 dst="ff:ff:ff:ff:ff:ff") /
5574 Dot1Q(vlan=101) /
5575 ARP(op="who-has",
5576 psrc='10.0.0.101',
5577 pdst="10.0.0.128",
5578 hwsrc=self.vlan_101.remote_mac,
5579 hwdst="ff:ff:ff:ff:ff:ff"))
5580 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
5581
5582 #
5583 # remote to external
5584 #
5585 p = (Ether(src=self.pg7.remote_mac,
5586 dst=self.pg7.local_mac) /
5587 IP(src=self.pg7.remote_ip4,
5588 dst=self.pg7.local_ip4) /
5589 UDP(sport=1234, dport=48879) /
5590 VXLAN(vni=vx_tun_l3.vni, gpid=epg_220.sclass, flags=0x88) /
5591 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5592 IP(src=str(rep.ip4), dst="10.0.0.100") /
5593 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005594 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005595 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
5596
5597 #
5598 # local EP pings router
5599 #
5600 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5601 Dot1Q(vlan=100) /
5602 IP(src="10.0.0.100", dst="10.0.0.128") /
5603 ICMP(type='echo-request'))
5604 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5605
5606 for rx in rxs:
5607 self.assertEqual(rx[Ether].src, str(self.router_mac))
5608 self.assertEqual(rx[Ether].dst, self.vlan_100.remote_mac)
5609 self.assertEqual(rx[Dot1Q].vlan, 100)
5610
5611 #
5612 # local EP pings other local EP
5613 #
5614 p = (Ether(src=self.vlan_100.remote_mac,
5615 dst=self.vlan_101.remote_mac) /
5616 Dot1Q(vlan=100) /
5617 IP(src="10.0.0.100", dst="10.0.0.101") /
5618 ICMP(type='echo-request'))
5619 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5620
5621 for rx in rxs:
5622 self.assertEqual(rx[Ether].src, self.vlan_100.remote_mac)
5623 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
5624 self.assertEqual(rx[Dot1Q].vlan, 101)
5625
5626 #
5627 # A subnet reachable through an external router on vlan 100
5628 #
5629 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
5630 [VppRoutePath("10.0.0.100",
5631 epg_220.bvi.sw_if_index)],
5632 table_id=t4.table_id)
5633 ip_220.add_vpp_config()
5634
5635 l3o_220 = VppGbpSubnet(
5636 self, rd1, "10.220.0.0", 24,
5637 # note: this a "regular" L3 out subnet (not connected)
5638 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5639 sclass=4220)
5640 l3o_220.add_vpp_config()
5641
5642 #
5643 # A subnet reachable through an external router on vlan 101
5644 #
5645 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
5646 [VppRoutePath("10.0.0.101",
5647 epg_220.bvi.sw_if_index)],
5648 table_id=t4.table_id)
5649 ip_221.add_vpp_config()
5650
5651 l3o_221 = VppGbpSubnet(
5652 self, rd1, "10.221.0.0", 24,
5653 # note: this a "regular" L3 out subnet (not connected)
5654 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5655 sclass=4221)
5656 l3o_221.add_vpp_config()
5657
5658 #
5659 # ping between hosts in remote subnets
5660 # dropped without a contract
5661 #
5662 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5663 Dot1Q(vlan=100) /
5664 IP(src="10.220.0.1", dst="10.221.0.1") /
5665 ICMP(type='echo-request'))
5666
5667 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
5668
5669 #
5670 # contract for the external nets to communicate
5671 #
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005672 rule4 = AclRule(is_permit=1, proto=17)
5673 rule6 = AclRule(src_prefix=IPv6Network((0, 0)),
5674 dst_prefix=IPv6Network((0, 0)), is_permit=1, proto=17)
5675 acl = VppAcl(self, rules=[rule4, rule6])
5676 acl.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005677
5678 c1 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005679 self, 55, 4220, 4221, acl.acl_index,
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005680 [VppGbpContractRule(
5681 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5682 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5683 []),
5684 VppGbpContractRule(
5685 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5686 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5687 [])],
5688 [ETH_P_IP, ETH_P_IPV6])
5689 c1.add_vpp_config()
5690
5691 #
5692 # Contracts allowing ext-net 200 to talk with external EPs
5693 #
5694 c2 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005695 self, 55, 4220, 113, acl.acl_index,
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005696 [VppGbpContractRule(
5697 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5698 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5699 []),
5700 VppGbpContractRule(
5701 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5702 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5703 [])],
5704 [ETH_P_IP, ETH_P_IPV6])
5705 c2.add_vpp_config()
5706 c3 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005707 self, 55, 113, 4220, acl.acl_index,
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005708 [VppGbpContractRule(
5709 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5710 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5711 []),
5712 VppGbpContractRule(
5713 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5714 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5715 [])],
5716 [ETH_P_IP, ETH_P_IPV6])
5717 c3.add_vpp_config()
5718
5719 #
5720 # ping between hosts in remote subnets
5721 #
5722 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5723 Dot1Q(vlan=100) /
5724 IP(src="10.220.0.1", dst="10.221.0.1") /
5725 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005726 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005727
5728 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
5729
5730 for rx in rxs:
5731 self.assertEqual(rx[Ether].src, str(self.router_mac))
5732 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
5733 self.assertEqual(rx[Dot1Q].vlan, 101)
5734
5735 # we did not learn these external hosts
5736 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
5737 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
5738
5739 #
5740 # from remote external EP to local external EP
5741 #
5742 p = (Ether(src=self.pg7.remote_mac,
5743 dst=self.pg7.local_mac) /
5744 IP(src=self.pg7.remote_ip4,
5745 dst=self.pg7.local_ip4) /
5746 UDP(sport=1234, dport=48879) /
5747 VXLAN(vni=444, gpid=113, flags=0x88) /
5748 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005749 IP(src=rep.ip4, dst="10.220.0.1") /
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005750 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005751 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005752
5753 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
5754
5755 #
5756 # ping from an external host to the remote external EP
5757 #
5758 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5759 Dot1Q(vlan=100) /
Neale Rannsefd7bc22019-11-11 08:32:34 +00005760 IP(src="10.220.0.1", dst=rep.ip4) /
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005761 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005762 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005763
5764 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
5765
5766 for rx in rxs:
5767 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
5768 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
5769 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
5770 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
5771 self.assertEqual(rx[VXLAN].vni, 444)
5772 self.assertTrue(rx[VXLAN].flags.G)
5773 self.assertTrue(rx[VXLAN].flags.Instance)
5774 # the sclass of the ext-net the packet came from
5775 self.assertEqual(rx[VXLAN].gpid, 4220)
5776 # policy was applied to the original IP packet
5777 self.assertTrue(rx[VXLAN].gpflags.A)
5778 # since it's an external host the reciever should not learn it
5779 self.assertTrue(rx[VXLAN].gpflags.D)
5780 inner = rx[VXLAN].payload
5781 self.assertEqual(inner[IP].src, "10.220.0.1")
Neale Rannsefd7bc22019-11-11 08:32:34 +00005782 self.assertEqual(inner[IP].dst, rep.ip4)
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005783
5784 #
5785 # An external subnet reachable via the remote external EP
5786 #
5787
5788 #
5789 # first the VXLAN-GBP tunnel over which it is reached
5790 #
5791 vx_tun_r = VppVxlanGbpTunnel(
5792 self, self.pg7.local_ip4,
5793 self.pg7.remote_ip4, 445,
5794 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
5795 VXLAN_GBP_API_TUNNEL_MODE_L3))
5796 vx_tun_r.add_vpp_config()
5797 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
5798
5799 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
5800
5801 #
5802 # then the special adj to resolve through on that tunnel
5803 #
5804 n1 = VppNeighbor(self,
5805 vx_tun_r.sw_if_index,
5806 "00:0c:0c:0c:0c:0c",
5807 self.pg7.remote_ip4)
5808 n1.add_vpp_config()
5809
5810 #
5811 # the route via the adj above
5812 #
5813 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
5814 [VppRoutePath(self.pg7.remote_ip4,
5815 vx_tun_r.sw_if_index)],
5816 table_id=t4.table_id)
5817 ip_222.add_vpp_config()
5818
5819 l3o_222 = VppGbpSubnet(
5820 self, rd1, "10.222.0.0", 24,
5821 # note: this a "regular" l3out subnet (not connected)
5822 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5823 sclass=4222)
5824 l3o_222.add_vpp_config()
5825
5826 #
5827 # ping between hosts in local and remote external subnets
5828 # dropped without a contract
5829 #
5830 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5831 Dot1Q(vlan=100) /
5832 IP(src="10.220.0.1", dst="10.222.0.1") /
5833 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005834 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005835
5836 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
5837
5838 #
5839 # Add contracts ext-nets for 220 -> 222
5840 #
5841 c4 = VppGbpContract(
Jakub Grajciar2f8cd912020-03-27 06:55:06 +01005842 self, 55, 4220, 4222, acl.acl_index,
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005843 [VppGbpContractRule(
5844 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5845 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5846 []),
5847 VppGbpContractRule(
5848 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5849 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5850 [])],
5851 [ETH_P_IP, ETH_P_IPV6])
5852 c4.add_vpp_config()
5853
5854 #
5855 # ping from host in local to remote external subnets
5856 #
5857 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5858 Dot1Q(vlan=100) /
5859 IP(src="10.220.0.1", dst="10.222.0.1") /
5860 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005861 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005862
5863 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
5864
5865 for rx in rxs:
5866 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
5867 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
5868 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
5869 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
5870 self.assertEqual(rx[VXLAN].vni, 445)
5871 self.assertTrue(rx[VXLAN].flags.G)
5872 self.assertTrue(rx[VXLAN].flags.Instance)
5873 # the sclass of the ext-net the packet came from
5874 self.assertEqual(rx[VXLAN].gpid, 4220)
5875 # policy was applied to the original IP packet
5876 self.assertTrue(rx[VXLAN].gpflags.A)
5877 # since it's an external host the reciever should not learn it
5878 self.assertTrue(rx[VXLAN].gpflags.D)
5879 inner = rx[VXLAN].payload
5880 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
5881 self.assertEqual(inner[IP].src, "10.220.0.1")
5882 self.assertEqual(inner[IP].dst, "10.222.0.1")
5883
5884 #
5885 # ping from host in remote to local external subnets
5886 # there's no contract for this, but the A bit is set.
5887 #
5888 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5889 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5890 UDP(sport=1234, dport=48879) /
5891 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5892 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5893 IP(src="10.222.0.1", dst="10.220.0.1") /
5894 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005895 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005896
5897 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
5898 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
5899
5900 #
5901 # ping from host in remote to remote external subnets
5902 # this is dropped by reflection check.
5903 #
5904 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5905 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5906 UDP(sport=1234, dport=48879) /
5907 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5908 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5909 IP(src="10.222.0.1", dst="10.222.0.2") /
5910 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01005911 Raw(b'\xa5' * 100))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02005912
5913 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
5914
5915 #
5916 # cleanup
5917 #
5918 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
5919 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
5920 self.pg7.unconfig_ip4()
Benoît Ganne040d47c2020-04-16 16:57:00 +02005921 # make sure the programmed EP is no longer learnt from DP
5922 self.wait_for_ep_timeout(sw_if_index=rep.itf.sw_if_index, ip=rep.ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08005923
Neale Rannsbc27d1b2018-02-05 01:13:38 -08005924
5925if __name__ == '__main__':
5926 unittest.main(testRunner=VppTestRunner)