blob: b9bca811cbce74b96df2b453d6a3d2a5cd8fb38f [file] [log] [blame]
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001#!/usr/bin/env python
2
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08003from socket import AF_INET, AF_INET6
Neale Rannsbc27d1b2018-02-05 01:13:38 -08004import unittest
Neale Rannsbc27d1b2018-02-05 01:13:38 -08005
Neale Rannsbc27d1b2018-02-05 01:13:38 -08006from scapy.packet import Raw
Neale Rannsc29c0af2018-11-07 04:21:12 -08007from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Ranns36abbf12019-03-12 02:34:07 -07008from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns25b04942018-04-04 09:34:50 -07009from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
Klement Sekerab9ef2732018-06-24 22:49:33 +020010 ICMPv6ND_NA
Neale Ranns25b04942018-04-04 09:34:50 -070011from scapy.utils6 import in6_getnsma, in6_getnsmac
Neale Ranns93cc3ee2018-10-10 07:22:51 -070012from scapy.layers.vxlan import VXLAN
Neale Ranns1c17e2e2018-12-20 12:03:59 -080013from scapy.data import ETH_P_IP, ETH_P_IPV6
Neale Ranns25b04942018-04-04 09:34:50 -070014from scapy.utils import inet_pton, inet_ntop
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080015
16from framework import VppTestCase, VppTestRunner
17from vpp_object import VppObject
18from vpp_interface import VppInterface
19from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \
20 VppIpInterfaceAddress, VppIpInterfaceBind, find_route
21from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
Neale Ranns36abbf12019-03-12 02:34:07 -070022 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -070023from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080024from vpp_ip import VppIpAddress, VppIpPrefix
25from vpp_papi import VppEnum, MACAddress
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080026from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \
27 VppVxlanGbpTunnel
Neale Ranns4dd4cf42019-03-27 05:06:47 -070028from vpp_neighbor import VppNeighbor
Neale Rannsbc27d1b2018-02-05 01:13:38 -080029
30
Neale Ranns93cc3ee2018-10-10 07:22:51 -070031def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None):
32 if ip:
33 vip = VppIpAddress(ip)
34 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010035 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070036
37 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070038
Neale Rannsc0a93142018-09-05 15:42:26 -070039 for ep in eps:
Neale Ranns93cc3ee2018-10-10 07:22:51 -070040 if sw_if_index:
41 if ep.endpoint.sw_if_index != sw_if_index:
42 continue
43 if ip:
44 for eip in ep.endpoint.ips:
45 if vip == eip:
46 return True
47 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010048 if vmac.packed == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070049 return True
50 return False
51
52
Neale Ranns93cc3ee2018-10-10 07:22:51 -070053def find_gbp_vxlan(test, vni):
54 ts = test.vapi.gbp_vxlan_tunnel_dump()
55 for t in ts:
56 if t.tunnel.vni == vni:
57 return True
58 return False
59
60
Neale Rannsbc27d1b2018-02-05 01:13:38 -080061class VppGbpEndpoint(VppObject):
62 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020063 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080064 """
65
Neale Ranns25b04942018-04-04 09:34:50 -070066 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -070067 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +010068 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -070069
70 @property
Neale Rannsc0a93142018-09-05 15:42:26 -070071 def ip4(self):
72 return self._ip4
73
74 @property
75 def fip4(self):
76 return self._fip4
77
78 @property
79 def ip6(self):
80 return self._ip6
81
82 @property
83 def fip6(self):
84 return self._fip6
85
86 @property
87 def ips(self):
88 return [self.ip4, self.ip6]
89
90 @property
91 def fips(self):
92 return [self.fip4, self.fip6]
93
Neale Ranns93cc3ee2018-10-10 07:22:51 -070094 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
95 flags=0,
96 tun_src="0.0.0.0",
97 tun_dst="0.0.0.0",
98 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -080099 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700100 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800101 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700102 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700103
104 self._ip4 = VppIpAddress(ip4)
105 self._fip4 = VppIpAddress(fip4)
106 self._ip6 = VppIpAddress(ip6)
107 self._fip6 = VppIpAddress(fip6)
108
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700109 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100110 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700111 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100112 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700113
114 self.flags = flags
115 self.tun_src = VppIpAddress(tun_src)
116 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800117
118 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700119 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700120 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700121 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100122 self.vmac.packed,
Neale Ranns4ba67722019-02-28 11:11:39 +0000123 self.epg.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700124 self.flags,
125 self.tun_src.encode(),
126 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700127 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800128 self._test.registry.register(self, self._test.logger)
129
130 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700131 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800132
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800133 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700134 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
135 self.itf.sw_if_index,
136 self.ip4.address,
Neale Ranns4ba67722019-02-28 11:11:39 +0000137 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800138
139 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700140 return find_gbp_endpoint(self._test,
141 self.itf.sw_if_index,
142 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700143
144
145class VppGbpRecirc(VppObject):
146 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200147 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700148 """
149
150 def __init__(self, test, epg, recirc, is_ext=False):
151 self._test = test
152 self.recirc = recirc
153 self.epg = epg
154 self.is_ext = is_ext
155
156 def add_vpp_config(self):
157 self._test.vapi.gbp_recirc_add_del(
158 1,
159 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000160 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700161 self.is_ext)
162 self._test.registry.register(self, self._test.logger)
163
164 def remove_vpp_config(self):
165 self._test.vapi.gbp_recirc_add_del(
166 0,
167 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000168 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700169 self.is_ext)
170
Neale Ranns25b04942018-04-04 09:34:50 -0700171 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700172 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700173
174 def query_vpp_config(self):
175 rs = self._test.vapi.gbp_recirc_dump()
176 for r in rs:
177 if r.recirc.sw_if_index == self.recirc.sw_if_index:
178 return True
179 return False
180
181
Neale Rannsb6a47952018-11-21 05:44:35 -0800182class VppGbpExtItf(VppObject):
183 """
184 GBP ExtItfulation Interface
185 """
186
187 def __init__(self, test, itf, bd, rd):
188 self._test = test
189 self.itf = itf
190 self.bd = bd
191 self.rd = rd
192
193 def add_vpp_config(self):
194 self._test.vapi.gbp_ext_itf_add_del(
195 1,
196 self.itf.sw_if_index,
197 self.bd.bd_id,
198 self.rd.rd_id)
199 self._test.registry.register(self, self._test.logger)
200
201 def remove_vpp_config(self):
202 self._test.vapi.gbp_ext_itf_add_del(
203 0,
204 self.itf.sw_if_index,
205 self.bd.bd_id,
206 self.rd.rd_id)
207
Neale Rannsb6a47952018-11-21 05:44:35 -0800208 def object_id(self):
209 return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index)
210
211 def query_vpp_config(self):
212 rs = self._test.vapi.gbp_ext_itf_dump()
213 for r in rs:
214 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
215 return True
216 return False
217
218
Neale Ranns25b04942018-04-04 09:34:50 -0700219class VppGbpSubnet(VppObject):
220 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200221 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700222 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700223 def __init__(self, test, rd, address, address_len,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700224 type, sw_if_index=None, sclass=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700225 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700226 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200227 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700228 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700229 self.sw_if_index = sw_if_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700230 self.sclass = sclass
Neale Ranns25b04942018-04-04 09:34:50 -0700231
232 def add_vpp_config(self):
233 self._test.vapi.gbp_subnet_add_del(
234 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700235 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200236 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700237 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700238 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700239 sclass=self.sclass if self.sclass else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700240 self._test.registry.register(self, self._test.logger)
241
242 def remove_vpp_config(self):
243 self._test.vapi.gbp_subnet_add_del(
244 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700245 self.rd_id,
246 self.prefix.encode(),
247 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700248
Neale Ranns25b04942018-04-04 09:34:50 -0700249 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700250 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700251
252 def query_vpp_config(self):
253 ss = self._test.vapi.gbp_subnet_dump()
254 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700255 if s.subnet.rd_id == self.rd_id and \
256 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200257 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700258 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700259 return False
260
261
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800262class VppGbpEndpointRetention(object):
263 def __init__(self, remote_ep_timeout=0xffffffff):
264 self.remote_ep_timeout = remote_ep_timeout
265
266 def encode(self):
267 return {'remote_ep_timeout': self.remote_ep_timeout}
268
269
Neale Ranns25b04942018-04-04 09:34:50 -0700270class VppGbpEndpointGroup(VppObject):
271 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200272 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700273 """
274
Neale Ranns4ba67722019-02-28 11:11:39 +0000275 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800276 bvi, bvi_ip4, bvi_ip6=None,
277 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700278 self._test = test
279 self.uplink = uplink
280 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700281 self.bvi_ip4 = VppIpAddress(bvi_ip4)
282 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000283 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700284 self.bd = bd
285 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800286 self.sclass = sclass
287 if 0 == self.sclass:
288 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800289 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700290
291 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700292 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000293 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800294 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700295 self.bd.bd.bd_id,
296 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800297 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
298 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700299 self._test.registry.register(self, self._test.logger)
300
301 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000302 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700303
Neale Ranns25b04942018-04-04 09:34:50 -0700304 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000305 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700306
307 def query_vpp_config(self):
308 epgs = self._test.vapi.gbp_endpoint_group_dump()
309 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000310 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800311 return True
312 return False
313
314
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700315class VppGbpBridgeDomain(VppObject):
316 """
317 GBP Bridge Domain
318 """
319
Neale Ranns879d11c2019-01-21 23:34:18 -0800320 def __init__(self, test, bd, bvi, uu_fwd=None,
Mohsin Kazmi8ea109e2019-03-22 15:13:31 +0100321 bm_flood=None, learn=True, uu_drop=False, bm_drop=False):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700322 self._test = test
323 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800324 self.uu_fwd = uu_fwd
325 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700326 self.bd = bd
327
Neale Rannsc29c0af2018-11-07 04:21:12 -0800328 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
329 if (learn):
330 self.learn = e.GBP_BD_API_FLAG_NONE
331 else:
332 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
Mohsin Kazmi8ea109e2019-03-22 15:13:31 +0100333 if (uu_drop):
334 self.learn |= e.GBP_BD_API_FLAG_UU_FWD_DROP
335 if (bm_drop):
336 self.learn |= e.GBP_BD_API_FLAG_MCAST_DROP
Neale Rannsc29c0af2018-11-07 04:21:12 -0800337
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700338 def add_vpp_config(self):
339 self._test.vapi.gbp_bridge_domain_add(
340 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800341 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700342 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800343 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
344 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700345 self._test.registry.register(self, self._test.logger)
346
347 def remove_vpp_config(self):
348 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
349
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700350 def object_id(self):
351 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
352
353 def query_vpp_config(self):
354 bds = self._test.vapi.gbp_bridge_domain_dump()
355 for bd in bds:
356 if bd.bd.bd_id == self.bd.bd_id:
357 return True
358 return False
359
360
361class VppGbpRouteDomain(VppObject):
362 """
363 GBP Route Domain
364 """
365
366 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
367 self._test = test
368 self.rd_id = rd_id
369 self.t4 = t4
370 self.t6 = t6
371 self.ip4_uu = ip4_uu
372 self.ip6_uu = ip6_uu
373
374 def add_vpp_config(self):
375 self._test.vapi.gbp_route_domain_add(
376 self.rd_id,
377 self.t4.table_id,
378 self.t6.table_id,
379 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
380 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
381 self._test.registry.register(self, self._test.logger)
382
383 def remove_vpp_config(self):
384 self._test.vapi.gbp_route_domain_del(self.rd_id)
385
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700386 def object_id(self):
387 return "gbp-route-domain:[%d]" % (self.rd_id)
388
389 def query_vpp_config(self):
390 rds = self._test.vapi.gbp_route_domain_dump()
391 for rd in rds:
392 if rd.rd.rd_id == self.rd_id:
393 return True
394 return False
395
396
Neale Ranns13a08cc2018-11-07 09:25:54 -0800397class VppGbpContractNextHop():
398 def __init__(self, mac, bd, ip, rd):
399 self.mac = mac
400 self.ip = ip
401 self.bd = bd
402 self.rd = rd
403
404 def encode(self):
405 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100406 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800407 'bd_id': self.bd.bd.bd_id,
408 'rd_id': self.rd.rd_id}
409
410
411class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100412 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800413 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100414 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800415 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800416
417 def encode(self):
418 nhs = []
419 for nh in self.nhs:
420 nhs.append(nh.encode())
421 while len(nhs) < 8:
422 nhs.append({})
423 return {'action': self.action,
424 'nh_set': {
425 'hash_mode': self.hash_mode,
426 'n_nhs': len(self.nhs),
427 'nhs': nhs}}
428
429
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800430class VppGbpContract(VppObject):
431 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200432 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800433 """
434
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700435 def __init__(self, test, sclass, dclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800436 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800437 self._test = test
438 self.acl_index = acl_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700439 self.sclass = sclass
440 self.dclass = dclass
Neale Ranns13a08cc2018-11-07 09:25:54 -0800441 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800442 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700443 while (len(self.allowed_ethertypes) < 16):
444 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800445
446 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800447 rules = []
448 for r in self.rules:
449 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800450 self._test.vapi.gbp_contract_add_del(
451 1,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700452 self.sclass,
453 self.dclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800454 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800455 rules,
456 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800457 self._test.registry.register(self, self._test.logger)
458
459 def remove_vpp_config(self):
460 self._test.vapi.gbp_contract_add_del(
461 0,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700462 self.sclass,
463 self.dclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800464 self.acl_index,
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700465 [],
466 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800467
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800468 def object_id(self):
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700469 return "gbp-contract:[%d:%s:%d]" % (self.sclass,
470 self.dclass,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800471 self.acl_index)
472
473 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700474 cs = self._test.vapi.gbp_contract_dump()
475 for c in cs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700476 if c.contract.sclass == self.sclass \
477 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800478 return True
479 return False
480
481
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700482class VppGbpVxlanTunnel(VppInterface):
483 """
484 GBP VXLAN tunnel
485 """
486
Neale Ranns8da9fc62019-03-04 14:08:11 -0800487 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700488 super(VppGbpVxlanTunnel, self).__init__(test)
489 self._test = test
490 self.vni = vni
491 self.bd_rd_id = bd_rd_id
492 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800493 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700494
495 def add_vpp_config(self):
496 r = self._test.vapi.gbp_vxlan_tunnel_add(
497 self.vni,
498 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800499 self.mode,
500 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700501 self.set_sw_if_index(r.sw_if_index)
502 self._test.registry.register(self, self._test.logger)
503
504 def remove_vpp_config(self):
505 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
506
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700507 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800508 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700509
510 def query_vpp_config(self):
511 return find_gbp_vxlan(self._test, self.vni)
512
513
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200514class VppGbpAcl(VppObject):
515 """
516 GBP Acl
517 """
518
519 def __init__(self, test):
520 self._test = test
521 self.acl_index = 4294967295
522
523 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800524 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
525 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200526 dport_from=0, dport_to=65535):
527 if proto == -1 or proto == 0:
528 sport_to = 0
529 dport_to = sport_to
530 elif proto == 1 or proto == 58:
531 sport_to = 255
532 dport_to = sport_to
533 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
534 'srcport_or_icmptype_first': sport_from,
535 'srcport_or_icmptype_last': sport_to,
536 'src_ip_prefix_len': s_prefix,
537 'src_ip_addr': s_ip,
538 'dstport_or_icmpcode_first': dport_from,
539 'dstport_or_icmpcode_last': dport_to,
540 'dst_ip_prefix_len': d_prefix,
541 'dst_ip_addr': d_ip})
542 return rule
543
544 def add_vpp_config(self, rules):
545
546 reply = self._test.vapi.acl_add_replace(self.acl_index,
547 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800548 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200549 self.acl_index = reply.acl_index
550 return self.acl_index
551
552 def remove_vpp_config(self):
553 self._test.vapi.acl_del(self.acl_index)
554
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200555 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700556 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200557
558 def query_vpp_config(self):
559 cs = self._test.vapi.acl_dump()
560 for c in cs:
561 if c.acl_index == self.acl_index:
562 return True
563 return False
564
565
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800566class TestGBP(VppTestCase):
567 """ GBP Test Case """
568
569 def setUp(self):
570 super(TestGBP, self).setUp()
571
Neale Ranns25b04942018-04-04 09:34:50 -0700572 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700573 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700574
Ole Troan8006c6a2018-12-17 12:02:26 +0100575 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800576
577 for i in self.pg_interfaces:
578 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700579 for i in self.lo_interfaces:
580 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800581
582 def tearDown(self):
583 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700584 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800585
586 super(TestGBP, self).tearDown()
587
Neale Ranns25b04942018-04-04 09:34:50 -0700588 def send_and_expect_bridged(self, src, tx, dst):
589 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800590
Neale Ranns25b04942018-04-04 09:34:50 -0700591 for r in rx:
592 self.assertEqual(r[Ether].src, tx[0][Ether].src)
593 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
594 self.assertEqual(r[IP].src, tx[0][IP].src)
595 self.assertEqual(r[IP].dst, tx[0][IP].dst)
596 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800597
Neale Ranns25b04942018-04-04 09:34:50 -0700598 def send_and_expect_bridged6(self, src, tx, dst):
599 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800600
Neale Ranns25b04942018-04-04 09:34:50 -0700601 for r in rx:
602 self.assertEqual(r[Ether].src, tx[0][Ether].src)
603 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
604 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
605 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
606 return rx
607
608 def send_and_expect_routed(self, src, tx, dst, src_mac):
609 rx = self.send_and_expect(src, tx, dst)
610
611 for r in rx:
612 self.assertEqual(r[Ether].src, src_mac)
613 self.assertEqual(r[Ether].dst, dst.remote_mac)
614 self.assertEqual(r[IP].src, tx[0][IP].src)
615 self.assertEqual(r[IP].dst, tx[0][IP].dst)
616 return rx
617
618 def send_and_expect_natted(self, src, tx, dst, src_ip):
619 rx = self.send_and_expect(src, tx, dst)
620
621 for r in rx:
622 self.assertEqual(r[Ether].src, tx[0][Ether].src)
623 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
624 self.assertEqual(r[IP].src, src_ip)
625 self.assertEqual(r[IP].dst, tx[0][IP].dst)
626 return rx
627
Neale Ranns4a6d0232018-04-24 07:45:33 -0700628 def send_and_expect_natted6(self, src, tx, dst, src_ip):
629 rx = self.send_and_expect(src, tx, dst)
630
631 for r in rx:
632 self.assertEqual(r[Ether].src, tx[0][Ether].src)
633 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
634 self.assertEqual(r[IPv6].src, src_ip)
635 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
636 return rx
637
Neale Ranns25b04942018-04-04 09:34:50 -0700638 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
639 rx = self.send_and_expect(src, tx, dst)
640
641 for r in rx:
642 self.assertEqual(r[Ether].src, tx[0][Ether].src)
643 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
644 self.assertEqual(r[IP].dst, dst_ip)
645 self.assertEqual(r[IP].src, tx[0][IP].src)
646 return rx
647
Neale Ranns4a6d0232018-04-24 07:45:33 -0700648 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
649 rx = self.send_and_expect(src, tx, dst)
650
651 for r in rx:
652 self.assertEqual(r[Ether].src, tx[0][Ether].src)
653 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
654 self.assertEqual(r[IPv6].dst, dst_ip)
655 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
656 return rx
657
Neale Ranns25b04942018-04-04 09:34:50 -0700658 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
659 rx = self.send_and_expect(src, tx, dst)
660
661 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100662 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700663 self.assertEqual(r[Ether].dst, dst.remote_mac)
664 self.assertEqual(r[IP].dst, dst_ip)
665 self.assertEqual(r[IP].src, src_ip)
666 return rx
667
Neale Ranns4a6d0232018-04-24 07:45:33 -0700668 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
669 rx = self.send_and_expect(src, tx, dst)
670
671 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100672 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700673 self.assertEqual(r[Ether].dst, dst.remote_mac)
674 self.assertEqual(r[IPv6].dst, dst_ip)
675 self.assertEqual(r[IPv6].src, src_ip)
676 return rx
677
Neale Ranns25b04942018-04-04 09:34:50 -0700678 def test_gbp(self):
679 """ Group Based Policy """
680
Neale Rannsb6a47952018-11-21 05:44:35 -0800681 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
682
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800683 #
Neale Ranns25b04942018-04-04 09:34:50 -0700684 # Bridge Domains
685 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700686 bd1 = VppBridgeDomain(self, 1)
687 bd2 = VppBridgeDomain(self, 2)
688 bd20 = VppBridgeDomain(self, 20)
689
690 bd1.add_vpp_config()
691 bd2.add_vpp_config()
692 bd20.add_vpp_config()
693
694 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
695 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
696 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
697
698 gbd1.add_vpp_config()
699 gbd2.add_vpp_config()
700 gbd20.add_vpp_config()
701
702 #
703 # Route Domains
704 #
705 gt4 = VppIpTable(self, 0)
706 gt4.add_vpp_config()
707 gt6 = VppIpTable(self, 0, is_ip6=True)
708 gt6.add_vpp_config()
709 nt4 = VppIpTable(self, 20)
710 nt4.add_vpp_config()
711 nt6 = VppIpTable(self, 20, is_ip6=True)
712 nt6.add_vpp_config()
713
714 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
715 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
716
717 rd0.add_vpp_config()
718 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700719
720 #
721 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700722 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
723 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000724 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
725 self.pg4, self.loop0,
726 "10.0.0.128", "2001:10::128"),
727 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
728 self.pg5, self.loop0,
729 "10.0.1.128", "2001:10:1::128"),
730 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
731 self.pg6, self.loop1,
732 "10.0.2.128", "2001:10:2::128"),
733 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
734 self.pg7, self.loop2,
735 "11.0.0.128", "3001::128"),
736 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
737 self.pg8, self.loop2,
738 "11.0.0.129", "3001::129")]
739 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
740 VppGbpRecirc(self, epgs[1], self.loop4),
741 VppGbpRecirc(self, epgs[2], self.loop5),
742 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
743 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700744
745 epg_nat = epgs[3]
746 recirc_nat = recircs[3]
747
748 #
749 # 4 end-points, 2 in the same subnet, 3 in the same BD
750 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700751 eps = [VppGbpEndpoint(self, self.pg0,
752 epgs[0], recircs[0],
753 "10.0.0.1", "11.0.0.1",
754 "2001:10::1", "3001::1"),
755 VppGbpEndpoint(self, self.pg1,
756 epgs[0], recircs[0],
757 "10.0.0.2", "11.0.0.2",
758 "2001:10::2", "3001::2"),
759 VppGbpEndpoint(self, self.pg2,
760 epgs[1], recircs[1],
761 "10.0.1.1", "11.0.0.3",
762 "2001:10:1::1", "3001::3"),
763 VppGbpEndpoint(self, self.pg3,
764 epgs[2], recircs[2],
765 "10.0.2.1", "11.0.0.4",
766 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700767
768 #
769 # Config related to each of the EPGs
770 #
771 for epg in epgs:
772 # IP config on the BVI interfaces
773 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700774 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
775 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
776 self.vapi.sw_interface_set_mac_address(
777 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100778 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700779
780 # The BVIs are NAT inside interfaces
781 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
782 is_inside=1,
783 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700784 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
785 is_inside=1,
786 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700787
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700788 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
789 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
790 if_ip4.add_vpp_config()
791 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700792
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700793 # EPG uplink interfaces in the RD
794 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
795 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700796
797 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700798 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100799 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700800 epg.bvi_ip4)
801 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100802 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700803 epg.bvi_ip6)
804 epg.bd_arp_ip4.add_vpp_config()
805 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700806
807 # EPG in VPP
808 epg.add_vpp_config()
809
810 for recirc in recircs:
811 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700812 VppIpInterfaceBind(self, recirc.recirc,
813 recirc.epg.rd.t4).add_vpp_config()
814 VppIpInterfaceBind(self, recirc.recirc,
815 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700816
Neale Ranns4a6d0232018-04-24 07:45:33 -0700817 self.vapi.nat44_interface_add_del_feature(
818 recirc.recirc.sw_if_index,
819 is_inside=0,
820 is_add=1)
821 self.vapi.nat66_add_del_interface(
822 recirc.recirc.sw_if_index,
823 is_inside=0,
824 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700825
826 recirc.add_vpp_config()
827
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700828 for recirc in recircs:
829 self.assertTrue(find_bridge_domain_port(self,
830 recirc.epg.bd.bd.bd_id,
831 recirc.recirc.sw_if_index))
832
Neale Ranns25b04942018-04-04 09:34:50 -0700833 for ep in eps:
834 self.pg_enable_capture(self.pg_interfaces)
835 self.pg_start()
836 #
837 # routes to the endpoints. We need these since there are no
838 # adj-fibs due to the fact the the BVI address has /32 and
839 # the subnet is not attached.
840 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700841 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700842 # Add static mappings for each EP from the 10/8 to 11/8 network
843 if ip.af == AF_INET:
844 self.vapi.nat44_add_del_static_mapping(ip.bytes,
845 fip.bytes,
846 vrf_id=0,
847 addr_only=1)
848 else:
849 self.vapi.nat66_add_del_static_mapping(ip.bytes,
850 fip.bytes,
851 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700852
Neale Ranns25b04942018-04-04 09:34:50 -0700853 # VPP EP create ...
854 ep.add_vpp_config()
855
Neale Rannsc0a93142018-09-05 15:42:26 -0700856 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700857
Neale Rannsc0a93142018-09-05 15:42:26 -0700858 # ... results in a Gratuitous ARP/ND on the EPG's uplink
859 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
860
861 for ii, ip in enumerate(ep.ips):
862 p = rx[ii]
863
864 if ip.is_ip6:
865 self.assertTrue(p.haslayer(ICMPv6ND_NA))
866 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
867 else:
868 self.assertTrue(p.haslayer(ARP))
869 self.assertEqual(p[ARP].psrc, ip.address)
870 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700871
872 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700873 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700874 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
875 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700876
Neale Rannsc0a93142018-09-05 15:42:26 -0700877 # floating IPs route via EPG recirc
878 r = VppIpRoute(self, fip.address, fip.length,
879 [VppRoutePath(fip.address,
880 ep.recirc.recirc.sw_if_index,
881 is_dvr=1,
882 proto=fip.dpo_proto)],
883 table_id=20,
884 is_ip6=fip.is_ip6)
885 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700886
887 # L2 FIB entries in the NAT EPG BD to bridge the packets from
888 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700889 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
890 ep.recirc.recirc, bvi_mac=0)
891 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700892
893 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700894 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700895 #
896 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
897 src=self.pg0.remote_mac) /
898 ARP(op="who-has",
899 hwdst="ff:ff:ff:ff:ff:ff",
900 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700901 pdst="10.0.0.88",
902 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700903
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700904 self.vapi.cli("clear trace")
905 self.pg0.add_stream(pkt_arp)
906
907 self.pg_enable_capture(self.pg_interfaces)
908 self.pg_start()
909
910 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700911
912 #
913 # ARP/ND packets get a response
914 #
915 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
916 src=self.pg0.remote_mac) /
917 ARP(op="who-has",
918 hwdst="ff:ff:ff:ff:ff:ff",
919 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700920 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700921 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700922
923 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
924
Neale Rannsc0a93142018-09-05 15:42:26 -0700925 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700926 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700927 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
928 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700929 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700930 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700931 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
932 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
933
934 #
935 # broadcast packets are flooded
936 #
937 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
938 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700939 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700940 UDP(sport=1234, dport=1234) /
941 Raw('\xa5' * 100))
942
943 self.vapi.cli("clear trace")
944 self.pg0.add_stream(pkt_bcast)
945
946 self.pg_enable_capture(self.pg_interfaces)
947 self.pg_start()
948
949 rxd = eps[1].itf.get_capture(1)
950 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
951 rxd = epgs[0].uplink.get_capture(1)
952 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
953
954 #
955 # packets to non-local L3 destinations dropped
956 #
957 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100958 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700959 IP(src=eps[0].ip4.address,
960 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700961 UDP(sport=1234, dport=1234) /
962 Raw('\xa5' * 100))
963 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100964 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700965 IP(src=eps[0].ip4.address,
966 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700967 UDP(sport=1234, dport=1234) /
968 Raw('\xa5' * 100))
969
970 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
971
972 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100973 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700974 IPv6(src=eps[0].ip6.address,
975 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700976 UDP(sport=1234, dport=1234) /
977 Raw('\xa5' * 100))
978 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
979
980 #
981 # Add the subnet routes
982 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700983 s41 = VppGbpSubnet(
984 self, rd0, "10.0.0.0", 24,
985 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
986 s42 = VppGbpSubnet(
987 self, rd0, "10.0.1.0", 24,
988 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
989 s43 = VppGbpSubnet(
990 self, rd0, "10.0.2.0", 24,
991 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
992 s61 = VppGbpSubnet(
993 self, rd0, "2001:10::1", 64,
994 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
995 s62 = VppGbpSubnet(
996 self, rd0, "2001:10:1::1", 64,
997 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
998 s63 = VppGbpSubnet(
999 self, rd0, "2001:10:2::1", 64,
1000 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001001 s41.add_vpp_config()
1002 s42.add_vpp_config()
1003 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001004 s61.add_vpp_config()
1005 s62.add_vpp_config()
1006 s63.add_vpp_config()
1007
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001008 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001009 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001010 eps[0].epg.uplink)
1011 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001012 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001013 eps[0].epg.uplink)
1014 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001015 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001016 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001017
1018 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1019 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1020 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1021 self.logger.info(self.vapi.cli("sh gbp recirc"))
1022 self.logger.info(self.vapi.cli("sh int"))
1023 self.logger.info(self.vapi.cli("sh int addr"))
1024 self.logger.info(self.vapi.cli("sh int feat loop6"))
1025 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1026 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001027 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001028
1029 #
1030 # Packet destined to unknown unicast is sent on the epg uplink ...
1031 #
1032 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1033 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001034 IP(src=eps[0].ip4.address,
1035 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001036 UDP(sport=1234, dport=1234) /
1037 Raw('\xa5' * 100))
1038
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001039 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001040 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001041 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001042 # ... and nowhere else
1043 self.pg1.get_capture(0, timeout=0.1)
1044 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1045
1046 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1047 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001048 IP(src=eps[0].ip4.address,
1049 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001050 UDP(sport=1234, dport=1234) /
1051 Raw('\xa5' * 100))
1052
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001053 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001054 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001055 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001056
1057 #
1058 # Packets from the uplink are forwarded in the absence of a contract
1059 #
1060 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1061 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001062 IP(src=eps[0].ip4.address,
1063 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001064 UDP(sport=1234, dport=1234) /
1065 Raw('\xa5' * 100))
1066
1067 self.send_and_expect_bridged(self.pg4,
1068 pkt_intra_epg_220_from_uplink * 65,
1069 self.pg0)
1070
1071 #
1072 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001073 # can communicate
1074 #
1075 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001076 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001077 IP(src=eps[0].ip4.address,
1078 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001079 UDP(sport=1234, dport=1234) /
1080 Raw('\xa5' * 100))
1081
Neale Ranns25b04942018-04-04 09:34:50 -07001082 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001083
1084 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001085 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001086 # cannot communicate
1087 #
1088 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001089 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001090 IP(src=eps[0].ip4.address,
1091 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001092 UDP(sport=1234, dport=1234) /
1093 Raw('\xa5' * 100))
1094 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001095 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001096 IP(src=eps[2].ip4.address,
1097 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001098 UDP(sport=1234, dport=1234) /
1099 Raw('\xa5' * 100))
1100 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001101 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001102 IP(src=eps[0].ip4.address,
1103 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001104 UDP(sport=1234, dport=1234) /
1105 Raw('\xa5' * 100))
1106
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001107 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001108 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001109 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001110 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001111
1112 #
1113 # A uni-directional contract from EPG 220 -> 221
1114 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001115 acl = VppGbpAcl(self)
1116 rule = acl.create_rule(permit_deny=1, proto=17)
1117 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1118 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001119 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001120 self, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001121 [VppGbpContractRule(
1122 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1123 []),
1124 VppGbpContractRule(
1125 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001126 [])],
1127 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001128 c1.add_vpp_config()
1129
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001130 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001131 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001132 eps[2].itf)
1133 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001134 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001135
1136 #
1137 # contract for the return direction
1138 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001139 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001140 self, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001141 [VppGbpContractRule(
1142 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1143 []),
1144 VppGbpContractRule(
1145 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001146 [])],
1147 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001148 c2.add_vpp_config()
1149
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001150 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001151 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001152 eps[2].itf)
1153 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001154 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001155 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001156
1157 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001158 # the contract does not allow non-IP
1159 #
1160 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1161 dst=self.pg2.remote_mac) /
1162 ARP())
1163 self.send_and_assert_no_replies(eps[0].itf,
1164 pkt_non_ip_inter_epg_220_to_221 * 17)
1165
1166 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001167 # check that inter group is still disabled for the groups
1168 # not in the contract.
1169 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001170 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001171 pkt_inter_epg_220_to_222 * 65)
1172
Neale Ranns25b04942018-04-04 09:34:50 -07001173 #
1174 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1175 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001176 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001177 self, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001178 [VppGbpContractRule(
1179 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1180 []),
1181 VppGbpContractRule(
1182 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001183 [])],
1184 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001185 c3.add_vpp_config()
1186
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001187 self.logger.info(self.vapi.cli("sh gbp contract"))
1188
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001189 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001190 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001191 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001192 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001193
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001194 #
1195 # remove both contracts, traffic stops in both directions
1196 #
1197 c2.remove_vpp_config()
1198 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001199 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001200 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001201
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001202 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001203 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001204 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001205 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001206 self.send_and_expect_bridged(eps[0].itf,
1207 pkt_intra_epg * 65,
1208 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001209
1210 #
Neale Ranns25b04942018-04-04 09:34:50 -07001211 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001212 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001213
Neale Ranns25b04942018-04-04 09:34:50 -07001214 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001215 se1 = VppGbpSubnet(
1216 self, rd0, "0.0.0.0", 0,
1217 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1218 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001219 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001220 se2 = VppGbpSubnet(
1221 self, rd0, "11.0.0.0", 8,
1222 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1223 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001224 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001225 se16 = VppGbpSubnet(
1226 self, rd0, "::", 0,
1227 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1228 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001229 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001230 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001231 se3 = VppGbpSubnet(
1232 self, rd20, "0.0.0.0", 0,
1233 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1234 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001235 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001236 se36 = VppGbpSubnet(
1237 self, rd20, "::", 0,
1238 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1239 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001240 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001241 se4 = VppGbpSubnet(
1242 self, rd20, "11.0.0.0", 8,
1243 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1244 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001245 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001246 se1.add_vpp_config()
1247 se2.add_vpp_config()
1248 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001249 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001250 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001251 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001252
Neale Ranns25b04942018-04-04 09:34:50 -07001253 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1254 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001255 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1256 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001257 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001258
Neale Ranns4a6d0232018-04-24 07:45:33 -07001259 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001260 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001261 #
Neale Ranns25b04942018-04-04 09:34:50 -07001262 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001263 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001264 IP(src=eps[0].ip4.address,
1265 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001266 UDP(sport=1234, dport=1234) /
1267 Raw('\xa5' * 100))
1268
1269 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001270 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001271 pkt_inter_epg_220_to_global * 65)
1272
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001273 acl2 = VppGbpAcl(self)
1274 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1275 sport_to=1234, dport_from=1234, dport_to=1234)
1276 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1277 sport_from=1234, sport_to=1234,
1278 dport_from=1234, dport_to=1234)
1279
1280 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001281 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001282 self, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001283 [VppGbpContractRule(
1284 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1285 []),
1286 VppGbpContractRule(
1287 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001288 [])],
1289 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001290 c4.add_vpp_config()
1291
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001292 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001293 pkt_inter_epg_220_to_global * 65,
1294 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001295 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001296
Neale Ranns4a6d0232018-04-24 07:45:33 -07001297 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001298 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001299 IPv6(src=eps[0].ip6.address,
1300 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001301 UDP(sport=1234, dport=1234) /
1302 Raw('\xa5' * 100))
1303
1304 self.send_and_expect_natted6(self.pg0,
1305 pkt_inter_epg_220_to_global * 65,
1306 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001307 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001308
1309 #
1310 # From a global address to an EP: OUT2IN
1311 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001312 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001313 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001314 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001315 src="1.1.1.1") /
1316 UDP(sport=1234, dport=1234) /
1317 Raw('\xa5' * 100))
1318
1319 self.send_and_assert_no_replies(self.pg7,
1320 pkt_inter_epg_220_from_global * 65)
1321
Neale Ranns13a08cc2018-11-07 09:25:54 -08001322 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001323 self, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001324 [VppGbpContractRule(
1325 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1326 []),
1327 VppGbpContractRule(
1328 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001329 [])],
1330 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001331 c5.add_vpp_config()
1332
1333 self.send_and_expect_unnatted(self.pg7,
1334 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001335 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001336 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001337
Ole Troan8006c6a2018-12-17 12:02:26 +01001338 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001339 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001340 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001341 src="6001::1") /
1342 UDP(sport=1234, dport=1234) /
1343 Raw('\xa5' * 100))
1344
1345 self.send_and_expect_unnatted6(self.pg7,
1346 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001347 eps[0].itf,
1348 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001349
1350 #
1351 # From a local VM to another local VM using resp. public addresses:
1352 # IN2OUT2IN
1353 #
Neale Ranns25b04942018-04-04 09:34:50 -07001354 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001355 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001356 IP(src=eps[0].ip4.address,
1357 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001358 UDP(sport=1234, dport=1234) /
1359 Raw('\xa5' * 100))
1360
Neale Ranns4a6d0232018-04-24 07:45:33 -07001361 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001362 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001363 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001364 eps[0].fip4.address,
1365 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001366
Neale Rannsc0a93142018-09-05 15:42:26 -07001367 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001368 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001369 IPv6(src=eps[0].ip6.address,
1370 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001371 UDP(sport=1234, dport=1234) /
1372 Raw('\xa5' * 100))
1373
Neale Rannsc0a93142018-09-05 15:42:26 -07001374 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001375 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001376 eps[1].itf,
1377 eps[0].fip6.address,
1378 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001379
1380 #
Neale Ranns25b04942018-04-04 09:34:50 -07001381 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001382 #
Neale Ranns25b04942018-04-04 09:34:50 -07001383 for ep in eps:
1384 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001385 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1386 ep.fip4.bytes,
1387 vrf_id=0,
1388 addr_only=1,
1389 is_add=0)
1390 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1391 ep.fip6.bytes,
1392 vrf_id=0,
1393 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001394
Neale Ranns25b04942018-04-04 09:34:50 -07001395 for epg in epgs:
1396 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001397 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001398 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1399 is_inside=1,
1400 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001401 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1402 is_inside=1,
1403 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001404
Neale Ranns25b04942018-04-04 09:34:50 -07001405 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001406 self.vapi.nat44_interface_add_del_feature(
1407 recirc.recirc.sw_if_index,
1408 is_inside=0,
1409 is_add=0)
1410 self.vapi.nat66_add_del_interface(
1411 recirc.recirc.sw_if_index,
1412 is_inside=0,
1413 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001414
Neale Ranns774356a2018-11-29 12:02:16 +00001415 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1416 n_tries=100, s_time=1):
1417 while (n_tries):
1418 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1419 return True
1420 n_tries = n_tries - 1
1421 self.sleep(s_time)
1422 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1423 return False
1424
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001425 def test_gbp_learn_l2(self):
1426 """ GBP L2 Endpoint Learning """
1427
Neale Rannsb6a47952018-11-21 05:44:35 -08001428 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001429 learnt = [{'mac': '00:00:11:11:11:01',
1430 'ip': '10.0.0.1',
1431 'ip6': '2001:10::2'},
1432 {'mac': '00:00:11:11:11:02',
1433 'ip': '10.0.0.2',
1434 'ip6': '2001:10::3'}]
1435
1436 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001437 # IP tables
1438 #
1439 gt4 = VppIpTable(self, 1)
1440 gt4.add_vpp_config()
1441 gt6 = VppIpTable(self, 1, is_ip6=True)
1442 gt6.add_vpp_config()
1443
1444 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1445 rd1.add_vpp_config()
1446
1447 #
1448 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1449 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1450 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1451 #
1452 self.pg2.config_ip4()
1453 self.pg2.resolve_arp()
1454 self.pg2.generate_remote_hosts(4)
1455 self.pg2.configure_ipv4_neighbors()
1456 self.pg3.config_ip4()
1457 self.pg3.resolve_arp()
1458 self.pg4.config_ip4()
1459 self.pg4.resolve_arp()
1460
1461 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001462 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1463 #
1464 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1465 "239.1.1.1", 88,
1466 mcast_itf=self.pg4)
1467 tun_bm.add_vpp_config()
1468
1469 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001470 # a GBP bridge domain with a BVI and a UU-flood interface
1471 #
1472 bd1 = VppBridgeDomain(self, 1)
1473 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001474 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001475 gbd1.add_vpp_config()
1476
1477 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1478 self.logger.info(self.vapi.cli("sh gbp bridge"))
1479
1480 # ... and has a /32 applied
1481 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1482 ip_addr.add_vpp_config()
1483
1484 #
1485 # The Endpoint-group in which we are learning endpoints
1486 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001487 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001488 None, self.loop0,
1489 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001490 "2001:10::128",
1491 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001492 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001493 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001494 None, self.loop1,
1495 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001496 "2001:11::128",
1497 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001498 epg_330.add_vpp_config()
1499
1500 #
1501 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001502 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001503 #
1504 vx_tun_l2_1 = VppGbpVxlanTunnel(
1505 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001506 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1507 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001508 vx_tun_l2_1.add_vpp_config()
1509
1510 #
1511 # A static endpoint that the learnt endpoints are trying to
1512 # talk to
1513 #
1514 ep = VppGbpEndpoint(self, self.pg0,
1515 epg_220, None,
1516 "10.0.0.127", "11.0.0.127",
1517 "2001:10::1", "3001::1")
1518 ep.add_vpp_config()
1519
1520 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1521
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001522 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001523 p = (Ether(src=self.pg2.remote_mac,
1524 dst=self.pg2.local_mac) /
1525 IP(src=self.pg2.remote_hosts[0].ip4,
1526 dst=self.pg2.local_ip4) /
1527 UDP(sport=1234, dport=48879) /
1528 VXLAN(vni=99, gpid=88, flags=0x88) /
1529 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1530 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1531 UDP(sport=1234, dport=1234) /
1532 Raw('\xa5' * 100))
1533
1534 self.send_and_assert_no_replies(self.pg2, p)
1535
1536 #
1537 # we should not have learnt a new tunnel endpoint, since
1538 # the EPG was not learnt.
1539 #
1540 self.assertEqual(INDEX_INVALID,
1541 find_vxlan_gbp_tunnel(self,
1542 self.pg2.local_ip4,
1543 self.pg2.remote_hosts[0].ip4,
1544 99))
1545
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001546 # epg is not learnt, because the EPG is unknwon
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001547 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1548
Neale Ranns8da9fc62019-03-04 14:08:11 -08001549 #
1550 # Learn new EPs from IP packets
1551 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001552 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001553 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001554 # arriving on an unknown TEP
1555 p = (Ether(src=self.pg2.remote_mac,
1556 dst=self.pg2.local_mac) /
1557 IP(src=self.pg2.remote_hosts[1].ip4,
1558 dst=self.pg2.local_ip4) /
1559 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001560 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001561 Ether(src=l['mac'], dst=ep.mac) /
1562 IP(src=l['ip'], dst=ep.ip4.address) /
1563 UDP(sport=1234, dport=1234) /
1564 Raw('\xa5' * 100))
1565
1566 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1567
1568 # the new TEP
1569 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1570 self,
1571 self.pg2.local_ip4,
1572 self.pg2.remote_hosts[1].ip4,
1573 99)
1574 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1575
1576 #
1577 # the EP is learnt via the learnt TEP
1578 # both from its MAC and its IP
1579 #
1580 self.assertTrue(find_gbp_endpoint(self,
1581 vx_tun_l2_1.sw_if_index,
1582 mac=l['mac']))
1583 self.assertTrue(find_gbp_endpoint(self,
1584 vx_tun_l2_1.sw_if_index,
1585 ip=l['ip']))
1586
1587 self.logger.info(self.vapi.cli("show gbp endpoint"))
1588 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001589 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001590
1591 #
1592 # If we sleep for the threshold time, the learnt endpoints should
1593 # age out
1594 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001595 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001596 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1597 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001598
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001599 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001600 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1601 #
1602 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001603 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001604 # arriving on an unknown TEP
1605 p = (Ether(src=self.pg2.remote_mac,
1606 dst=self.pg2.local_mac) /
1607 IP(src=self.pg2.remote_hosts[1].ip4,
1608 dst="239.1.1.1") /
1609 UDP(sport=1234, dport=48879) /
1610 VXLAN(vni=88, gpid=112, flags=0x88) /
1611 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1612 ARP(op="who-has",
1613 psrc=l['ip'], pdst=l['ip'],
1614 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1615
1616 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1617
1618 # the new TEP
1619 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1620 self,
1621 self.pg2.local_ip4,
1622 self.pg2.remote_hosts[1].ip4,
1623 99)
1624 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1625
1626 #
1627 # the EP is learnt via the learnt TEP
1628 # both from its MAC and its IP
1629 #
1630 self.assertTrue(find_gbp_endpoint(self,
1631 vx_tun_l2_1.sw_if_index,
1632 mac=l['mac']))
1633 self.assertTrue(find_gbp_endpoint(self,
1634 vx_tun_l2_1.sw_if_index,
1635 ip=l['ip']))
1636
1637 #
1638 # wait for the learnt endpoints to age out
1639 #
1640 for l in learnt:
1641 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1642 mac=l['mac'])
1643
1644 #
1645 # Learn new EPs from L2 packets
1646 #
1647 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001648 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001649 # arriving on an unknown TEP
1650 p = (Ether(src=self.pg2.remote_mac,
1651 dst=self.pg2.local_mac) /
1652 IP(src=self.pg2.remote_hosts[1].ip4,
1653 dst=self.pg2.local_ip4) /
1654 UDP(sport=1234, dport=48879) /
1655 VXLAN(vni=99, gpid=112, flags=0x88) /
1656 Ether(src=l['mac'], dst=ep.mac) /
1657 Raw('\xa5' * 100))
1658
1659 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1660
1661 # the new TEP
1662 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1663 self,
1664 self.pg2.local_ip4,
1665 self.pg2.remote_hosts[1].ip4,
1666 99)
1667 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1668
1669 #
1670 # the EP is learnt via the learnt TEP
1671 # both from its MAC and its IP
1672 #
1673 self.assertTrue(find_gbp_endpoint(self,
1674 vx_tun_l2_1.sw_if_index,
1675 mac=l['mac']))
1676
1677 self.logger.info(self.vapi.cli("show gbp endpoint"))
1678 self.logger.info(self.vapi.cli("show gbp vxlan"))
1679 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1680
1681 #
1682 # wait for the learnt endpoints to age out
1683 #
1684 for l in learnt:
1685 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1686 mac=l['mac'])
1687
1688 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001689 # repeat. the do not learn bit is set so the EPs are not learnt
1690 #
1691 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001692 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001693 p = (Ether(src=self.pg2.remote_mac,
1694 dst=self.pg2.local_mac) /
1695 IP(src=self.pg2.remote_hosts[1].ip4,
1696 dst=self.pg2.local_ip4) /
1697 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001698 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001699 Ether(src=l['mac'], dst=ep.mac) /
1700 IP(src=l['ip'], dst=ep.ip4.address) /
1701 UDP(sport=1234, dport=1234) /
1702 Raw('\xa5' * 100))
1703
1704 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1705
1706 for l in learnt:
1707 self.assertFalse(find_gbp_endpoint(self,
1708 vx_tun_l2_1.sw_if_index,
1709 mac=l['mac']))
1710
1711 #
1712 # repeat
1713 #
1714 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001715 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001716 p = (Ether(src=self.pg2.remote_mac,
1717 dst=self.pg2.local_mac) /
1718 IP(src=self.pg2.remote_hosts[1].ip4,
1719 dst=self.pg2.local_ip4) /
1720 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001721 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001722 Ether(src=l['mac'], dst=ep.mac) /
1723 IP(src=l['ip'], dst=ep.ip4.address) /
1724 UDP(sport=1234, dport=1234) /
1725 Raw('\xa5' * 100))
1726
1727 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1728
1729 self.assertTrue(find_gbp_endpoint(self,
1730 vx_tun_l2_1.sw_if_index,
1731 mac=l['mac']))
1732
1733 #
1734 # Static EP replies to dynamics
1735 #
1736 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1737 for l in learnt:
1738 p = (Ether(src=ep.mac, dst=l['mac']) /
1739 IP(dst=l['ip'], src=ep.ip4.address) /
1740 UDP(sport=1234, dport=1234) /
1741 Raw('\xa5' * 100))
1742
1743 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1744
1745 for rx in rxs:
1746 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1747 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1748 self.assertEqual(rx[UDP].dport, 48879)
1749 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001750 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001751 self.assertEqual(rx[VXLAN].vni, 99)
1752 self.assertTrue(rx[VXLAN].flags.G)
1753 self.assertTrue(rx[VXLAN].flags.Instance)
1754 self.assertTrue(rx[VXLAN].gpflags.A)
1755 self.assertFalse(rx[VXLAN].gpflags.D)
1756
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001757 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001758 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1759 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001760
1761 #
1762 # repeat in the other EPG
1763 # there's no contract between 220 and 330, but the A-bit is set
1764 # so the packet is cleared for delivery
1765 #
1766 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001767 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001768 p = (Ether(src=self.pg2.remote_mac,
1769 dst=self.pg2.local_mac) /
1770 IP(src=self.pg2.remote_hosts[1].ip4,
1771 dst=self.pg2.local_ip4) /
1772 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001773 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001774 Ether(src=l['mac'], dst=ep.mac) /
1775 IP(src=l['ip'], dst=ep.ip4.address) /
1776 UDP(sport=1234, dport=1234) /
1777 Raw('\xa5' * 100))
1778
1779 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1780
1781 self.assertTrue(find_gbp_endpoint(self,
1782 vx_tun_l2_1.sw_if_index,
1783 mac=l['mac']))
1784
1785 #
1786 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001787 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001788 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001789 p = (Ether(src=ep.mac, dst=l['mac']) /
1790 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1791 UDP(sport=1234, dport=1234) /
1792 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001793
Neale Ranns13a08cc2018-11-07 09:25:54 -08001794 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001795
1796 #
1797 # refresh the entries after the check for no replies above
1798 #
1799 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001800 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001801 p = (Ether(src=self.pg2.remote_mac,
1802 dst=self.pg2.local_mac) /
1803 IP(src=self.pg2.remote_hosts[1].ip4,
1804 dst=self.pg2.local_ip4) /
1805 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001806 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001807 Ether(src=l['mac'], dst=ep.mac) /
1808 IP(src=l['ip'], dst=ep.ip4.address) /
1809 UDP(sport=1234, dport=1234) /
1810 Raw('\xa5' * 100))
1811
1812 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1813
1814 self.assertTrue(find_gbp_endpoint(self,
1815 vx_tun_l2_1.sw_if_index,
1816 mac=l['mac']))
1817
1818 #
1819 # Add the contract so they can talk
1820 #
1821 acl = VppGbpAcl(self)
1822 rule = acl.create_rule(permit_deny=1, proto=17)
1823 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1824 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001825 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001826 self, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001827 [VppGbpContractRule(
1828 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1829 []),
1830 VppGbpContractRule(
1831 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001832 [])],
1833 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001834 c1.add_vpp_config()
1835
1836 for l in learnt:
1837 p = (Ether(src=ep.mac, dst=l['mac']) /
1838 IP(dst=l['ip'], src=ep.ip4.address) /
1839 UDP(sport=1234, dport=1234) /
1840 Raw('\xa5' * 100))
1841
1842 self.send_and_expect(self.pg0, [p], self.pg2)
1843
1844 #
1845 # send UU packets from the local EP
1846 #
1847 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1848 self.logger.info(self.vapi.cli("sh gbp bridge"))
1849 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1850 IP(dst="10.0.0.133", src=ep.ip4.address) /
1851 UDP(sport=1234, dport=1234) /
1852 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001853 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001854
1855 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1856
1857 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1858 IP(dst="10.0.0.133", src=ep.ip4.address) /
1859 UDP(sport=1234, dport=1234) /
1860 Raw('\xa5' * 100))
1861 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1862
Neale Ranns879d11c2019-01-21 23:34:18 -08001863 for rx in rxs:
1864 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1865 self.assertEqual(rx[IP].dst, "239.1.1.1")
1866 self.assertEqual(rx[UDP].dport, 48879)
1867 # the UDP source port is a random value for hashing
1868 self.assertEqual(rx[VXLAN].gpid, 112)
1869 self.assertEqual(rx[VXLAN].vni, 88)
1870 self.assertTrue(rx[VXLAN].flags.G)
1871 self.assertTrue(rx[VXLAN].flags.Instance)
1872 self.assertFalse(rx[VXLAN].gpflags.A)
1873 self.assertFalse(rx[VXLAN].gpflags.D)
1874
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001875 #
1876 # Check v6 Endpoints
1877 #
1878 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001879 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001880 p = (Ether(src=self.pg2.remote_mac,
1881 dst=self.pg2.local_mac) /
1882 IP(src=self.pg2.remote_hosts[1].ip4,
1883 dst=self.pg2.local_ip4) /
1884 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001885 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001886 Ether(src=l['mac'], dst=ep.mac) /
1887 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1888 UDP(sport=1234, dport=1234) /
1889 Raw('\xa5' * 100))
1890
1891 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1892
1893 self.assertTrue(find_gbp_endpoint(self,
1894 vx_tun_l2_1.sw_if_index,
1895 mac=l['mac']))
1896
1897 #
1898 # L3 Endpoint Learning
1899 # - configured on the bridge's BVI
1900 #
1901
1902 #
1903 # clean up
1904 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001905 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001906 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1907 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001908
1909 self.pg2.unconfig_ip4()
1910 self.pg3.unconfig_ip4()
1911 self.pg4.unconfig_ip4()
1912
1913 self.logger.info(self.vapi.cli("sh int"))
1914 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1915
Neale Rannsc29c0af2018-11-07 04:21:12 -08001916 def test_gbp_learn_vlan_l2(self):
1917 """ GBP L2 Endpoint w/ VLANs"""
1918
Neale Rannsb6a47952018-11-21 05:44:35 -08001919 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001920 learnt = [{'mac': '00:00:11:11:11:01',
1921 'ip': '10.0.0.1',
1922 'ip6': '2001:10::2'},
1923 {'mac': '00:00:11:11:11:02',
1924 'ip': '10.0.0.2',
1925 'ip6': '2001:10::3'}]
1926
1927 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08001928 # IP tables
1929 #
1930 gt4 = VppIpTable(self, 1)
1931 gt4.add_vpp_config()
1932 gt6 = VppIpTable(self, 1, is_ip6=True)
1933 gt6.add_vpp_config()
1934
1935 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1936 rd1.add_vpp_config()
1937
1938 #
1939 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1940 #
1941 self.pg2.config_ip4()
1942 self.pg2.resolve_arp()
1943 self.pg2.generate_remote_hosts(4)
1944 self.pg2.configure_ipv4_neighbors()
1945 self.pg3.config_ip4()
1946 self.pg3.resolve_arp()
1947
1948 #
1949 # The EP will be on a vlan sub-interface
1950 #
1951 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1952 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01001953 self.vapi.l2_interface_vlan_tag_rewrite(
1954 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
1955 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001956
1957 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1958 self.pg3.remote_ip4, 116)
1959 bd_uu_fwd.add_vpp_config()
1960
1961 #
1962 # a GBP bridge domain with a BVI and a UU-flood interface
1963 # The BD is marked as do not learn, so no endpoints are ever
1964 # learnt in this BD.
1965 #
1966 bd1 = VppBridgeDomain(self, 1)
1967 bd1.add_vpp_config()
1968 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1969 learn=False)
1970 gbd1.add_vpp_config()
1971
1972 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1973 self.logger.info(self.vapi.cli("sh gbp bridge"))
1974
1975 # ... and has a /32 applied
1976 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1977 ip_addr.add_vpp_config()
1978
1979 #
1980 # The Endpoint-group in which we are learning endpoints
1981 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001982 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08001983 None, self.loop0,
1984 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001985 "2001:10::128",
1986 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08001987 epg_220.add_vpp_config()
1988
1989 #
1990 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001991 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08001992 #
1993 vx_tun_l2_1 = VppGbpVxlanTunnel(
1994 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001995 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1996 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08001997 vx_tun_l2_1.add_vpp_config()
1998
1999 #
2000 # A static endpoint that the learnt endpoints are trying to
2001 # talk to
2002 #
2003 ep = VppGbpEndpoint(self, vlan_11,
2004 epg_220, None,
2005 "10.0.0.127", "11.0.0.127",
2006 "2001:10::1", "3001::1")
2007 ep.add_vpp_config()
2008
2009 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2010
2011 #
2012 # Send to the static EP
2013 #
2014 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002015 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002016 # arriving on an unknown TEP
2017 p = (Ether(src=self.pg2.remote_mac,
2018 dst=self.pg2.local_mac) /
2019 IP(src=self.pg2.remote_hosts[1].ip4,
2020 dst=self.pg2.local_ip4) /
2021 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002022 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002023 Ether(src=l['mac'], dst=ep.mac) /
2024 IP(src=l['ip'], dst=ep.ip4.address) /
2025 UDP(sport=1234, dport=1234) /
2026 Raw('\xa5' * 100))
2027
2028 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2029
2030 #
2031 # packet to EP has the EP's vlan tag
2032 #
2033 for rx in rxs:
2034 self.assertEqual(rx[Dot1Q].vlan, 11)
2035
2036 #
2037 # the EP is not learnt since the BD setting prevents it
2038 # also no TEP too
2039 #
2040 self.assertFalse(find_gbp_endpoint(self,
2041 vx_tun_l2_1.sw_if_index,
2042 mac=l['mac']))
2043 self.assertEqual(INDEX_INVALID,
2044 find_vxlan_gbp_tunnel(
2045 self,
2046 self.pg2.local_ip4,
2047 self.pg2.remote_hosts[1].ip4,
2048 99))
2049
2050 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2051
2052 #
2053 # static to remotes
2054 # we didn't learn the remotes so they are sent to the UU-fwd
2055 #
2056 for l in learnt:
2057 p = (Ether(src=ep.mac, dst=l['mac']) /
2058 Dot1Q(vlan=11) /
2059 IP(dst=l['ip'], src=ep.ip4.address) /
2060 UDP(sport=1234, dport=1234) /
2061 Raw('\xa5' * 100))
2062
2063 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2064
2065 for rx in rxs:
2066 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2067 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2068 self.assertEqual(rx[UDP].dport, 48879)
2069 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002070 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002071 self.assertEqual(rx[VXLAN].vni, 116)
2072 self.assertTrue(rx[VXLAN].flags.G)
2073 self.assertTrue(rx[VXLAN].flags.Instance)
2074 self.assertFalse(rx[VXLAN].gpflags.A)
2075 self.assertFalse(rx[VXLAN].gpflags.D)
2076
2077 self.pg2.unconfig_ip4()
2078 self.pg3.unconfig_ip4()
2079
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002080 def test_gbp_learn_l3(self):
2081 """ GBP L3 Endpoint Learning """
2082
Neale Ranns13a08cc2018-11-07 09:25:54 -08002083 self.vapi.cli("set logging class gbp debug")
2084
Neale Rannsb6a47952018-11-21 05:44:35 -08002085 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002086 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2087 routed_src_mac = "00:22:bd:f8:19:ff"
2088
2089 learnt = [{'mac': '00:00:11:11:11:02',
2090 'ip': '10.0.1.2',
2091 'ip6': '2001:10::2'},
2092 {'mac': '00:00:11:11:11:03',
2093 'ip': '10.0.1.3',
2094 'ip6': '2001:10::3'}]
2095
2096 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002097 # IP tables
2098 #
2099 t4 = VppIpTable(self, 1)
2100 t4.add_vpp_config()
2101 t6 = VppIpTable(self, 1, True)
2102 t6.add_vpp_config()
2103
2104 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2105 self.pg4.remote_ip4, 114)
2106 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2107 self.pg4.remote_ip4, 116)
2108 tun_ip4_uu.add_vpp_config()
2109 tun_ip6_uu.add_vpp_config()
2110
2111 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2112 rd1.add_vpp_config()
2113
Ole Troan8006c6a2018-12-17 12:02:26 +01002114 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002115
2116 #
2117 # Bind the BVI to the RD
2118 #
2119 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2120 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2121
2122 #
2123 # Pg2 hosts the vxlan tunnel
2124 # hosts on pg2 to act as TEPs
2125 # pg3 is BD uu-fwd
2126 # pg4 is RD uu-fwd
2127 #
2128 self.pg2.config_ip4()
2129 self.pg2.resolve_arp()
2130 self.pg2.generate_remote_hosts(4)
2131 self.pg2.configure_ipv4_neighbors()
2132 self.pg3.config_ip4()
2133 self.pg3.resolve_arp()
2134 self.pg4.config_ip4()
2135 self.pg4.resolve_arp()
2136
2137 #
2138 # a GBP bridge domain with a BVI and a UU-flood interface
2139 #
2140 bd1 = VppBridgeDomain(self, 1)
2141 bd1.add_vpp_config()
2142 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2143 gbd1.add_vpp_config()
2144
2145 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2146 self.logger.info(self.vapi.cli("sh gbp bridge"))
2147 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002148
2149 # ... and has a /32 and /128 applied
2150 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2151 ip4_addr.add_vpp_config()
2152 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2153 ip6_addr.add_vpp_config()
2154
2155 #
2156 # The Endpoint-group in which we are learning endpoints
2157 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002158 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002159 None, self.loop0,
2160 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002161 "2001:10::128",
2162 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002163 epg_220.add_vpp_config()
2164
2165 #
2166 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002167 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002168 #
2169 vx_tun_l3 = VppGbpVxlanTunnel(
2170 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002171 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2172 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002173 vx_tun_l3.add_vpp_config()
2174
2175 #
2176 # A static endpoint that the learnt endpoints are trying to
2177 # talk to
2178 #
2179 ep = VppGbpEndpoint(self, self.pg0,
2180 epg_220, None,
2181 "10.0.0.127", "11.0.0.127",
2182 "2001:10::1", "3001::1")
2183 ep.add_vpp_config()
2184
2185 #
2186 # learn some remote IPv4 EPs
2187 #
2188 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002189 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002190 # arriving on an unknown TEP
2191 p = (Ether(src=self.pg2.remote_mac,
2192 dst=self.pg2.local_mac) /
2193 IP(src=self.pg2.remote_hosts[1].ip4,
2194 dst=self.pg2.local_ip4) /
2195 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002196 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002197 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2198 IP(src=l['ip'], dst=ep.ip4.address) /
2199 UDP(sport=1234, dport=1234) /
2200 Raw('\xa5' * 100))
2201
2202 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2203
2204 # the new TEP
2205 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2206 self,
2207 self.pg2.local_ip4,
2208 self.pg2.remote_hosts[1].ip4,
2209 vx_tun_l3.vni)
2210 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2211
2212 # endpoint learnt via the parent GBP-vxlan interface
2213 self.assertTrue(find_gbp_endpoint(self,
2214 vx_tun_l3._sw_if_index,
2215 ip=l['ip']))
2216
2217 #
2218 # Static IPv4 EP replies to learnt
2219 #
2220 for l in learnt:
2221 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2222 IP(dst=l['ip'], src=ep.ip4.address) /
2223 UDP(sport=1234, dport=1234) /
2224 Raw('\xa5' * 100))
2225
2226 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2227
2228 for rx in rxs:
2229 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2230 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2231 self.assertEqual(rx[UDP].dport, 48879)
2232 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002233 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002234 self.assertEqual(rx[VXLAN].vni, 101)
2235 self.assertTrue(rx[VXLAN].flags.G)
2236 self.assertTrue(rx[VXLAN].flags.Instance)
2237 self.assertTrue(rx[VXLAN].gpflags.A)
2238 self.assertFalse(rx[VXLAN].gpflags.D)
2239
2240 inner = rx[VXLAN].payload
2241
2242 self.assertEqual(inner[Ether].src, routed_src_mac)
2243 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2244 self.assertEqual(inner[IP].src, ep.ip4.address)
2245 self.assertEqual(inner[IP].dst, l['ip'])
2246
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002247 for l in learnt:
2248 self.assertFalse(find_gbp_endpoint(self,
2249 tep1_sw_if_index,
2250 ip=l['ip']))
2251
2252 #
2253 # learn some remote IPv6 EPs
2254 #
2255 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002256 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002257 # arriving on an unknown TEP
2258 p = (Ether(src=self.pg2.remote_mac,
2259 dst=self.pg2.local_mac) /
2260 IP(src=self.pg2.remote_hosts[1].ip4,
2261 dst=self.pg2.local_ip4) /
2262 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002263 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002264 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2265 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2266 UDP(sport=1234, dport=1234) /
2267 Raw('\xa5' * 100))
2268
2269 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2270
2271 # the new TEP
2272 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2273 self,
2274 self.pg2.local_ip4,
2275 self.pg2.remote_hosts[1].ip4,
2276 vx_tun_l3.vni)
2277 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2278
2279 self.logger.info(self.vapi.cli("show gbp bridge"))
2280 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2281 self.logger.info(self.vapi.cli("show gbp vxlan"))
2282 self.logger.info(self.vapi.cli("show int addr"))
2283
2284 # endpoint learnt via the TEP
2285 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2286
2287 self.logger.info(self.vapi.cli("show gbp endpoint"))
2288 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2289
2290 #
2291 # Static EP replies to learnt
2292 #
2293 for l in learnt:
2294 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2295 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2296 UDP(sport=1234, dport=1234) /
2297 Raw('\xa5' * 100))
2298
2299 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2300
2301 for rx in rxs:
2302 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2303 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2304 self.assertEqual(rx[UDP].dport, 48879)
2305 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002306 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002307 self.assertEqual(rx[VXLAN].vni, 101)
2308 self.assertTrue(rx[VXLAN].flags.G)
2309 self.assertTrue(rx[VXLAN].flags.Instance)
2310 self.assertTrue(rx[VXLAN].gpflags.A)
2311 self.assertFalse(rx[VXLAN].gpflags.D)
2312
2313 inner = rx[VXLAN].payload
2314
2315 self.assertEqual(inner[Ether].src, routed_src_mac)
2316 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2317 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2318 self.assertEqual(inner[IPv6].dst, l['ip6'])
2319
2320 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002321 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002322 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002323
2324 #
2325 # Static sends to unknown EP with no route
2326 #
2327 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2328 IP(dst="10.0.0.99", src=ep.ip4.address) /
2329 UDP(sport=1234, dport=1234) /
2330 Raw('\xa5' * 100))
2331
2332 self.send_and_assert_no_replies(self.pg0, [p])
2333
2334 #
2335 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002336 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002337 #
2338 se_10_24 = VppGbpSubnet(
2339 self, rd1, "10.0.0.0", 24,
2340 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2341 se_10_24.add_vpp_config()
2342
2343 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2344 IP(dst="10.0.0.99", src=ep.ip4.address) /
2345 UDP(sport=1234, dport=1234) /
2346 Raw('\xa5' * 100))
2347
2348 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2349 for rx in rxs:
2350 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2351 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2352 self.assertEqual(rx[UDP].dport, 48879)
2353 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002354 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002355 self.assertEqual(rx[VXLAN].vni, 114)
2356 self.assertTrue(rx[VXLAN].flags.G)
2357 self.assertTrue(rx[VXLAN].flags.Instance)
2358 # policy is not applied to packets sent to the uu-fwd interfaces
2359 self.assertFalse(rx[VXLAN].gpflags.A)
2360 self.assertFalse(rx[VXLAN].gpflags.D)
2361
2362 #
2363 # learn some remote IPv4 EPs
2364 #
2365 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002366 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002367 # arriving on an unknown TEP
2368 p = (Ether(src=self.pg2.remote_mac,
2369 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002370 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002371 dst=self.pg2.local_ip4) /
2372 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002373 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002374 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2375 IP(src=l['ip'], dst=ep.ip4.address) /
2376 UDP(sport=1234, dport=1234) /
2377 Raw('\xa5' * 100))
2378
2379 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2380
2381 # the new TEP
2382 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2383 self,
2384 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002385 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002386 vx_tun_l3.vni)
2387 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2388
2389 # endpoint learnt via the parent GBP-vxlan interface
2390 self.assertTrue(find_gbp_endpoint(self,
2391 vx_tun_l3._sw_if_index,
2392 ip=l['ip']))
2393
2394 #
2395 # Add a remote endpoint from the API
2396 #
2397 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2398 epg_220, None,
2399 "10.0.0.88", "11.0.0.88",
2400 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002401 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002402 self.pg2.local_ip4,
2403 self.pg2.remote_hosts[1].ip4,
2404 mac=None)
2405 rep_88.add_vpp_config()
2406
2407 #
2408 # Add a remote endpoint from the API that matches an existing one
2409 #
2410 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2411 epg_220, None,
2412 learnt[0]['ip'], "11.0.0.101",
2413 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002414 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002415 self.pg2.local_ip4,
2416 self.pg2.remote_hosts[1].ip4,
2417 mac=None)
2418 rep_2.add_vpp_config()
2419
2420 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002421 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002422 # packets should be send on the v4/v6 uu=fwd interface resp.
2423 #
2424 se_10_1_24 = VppGbpSubnet(
2425 self, rd1, "10.0.1.0", 24,
2426 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2427 se_10_1_24.add_vpp_config()
2428
2429 self.logger.info(self.vapi.cli("show gbp endpoint"))
2430
2431 ips = ["10.0.0.88", learnt[0]['ip']]
2432 for ip in ips:
2433 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2434 IP(dst=ip, src=ep.ip4.address) /
2435 UDP(sport=1234, dport=1234) /
2436 Raw('\xa5' * 100))
2437
2438 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2439
2440 for rx in rxs:
2441 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2442 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2443 self.assertEqual(rx[UDP].dport, 48879)
2444 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002445 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002446 self.assertEqual(rx[VXLAN].vni, 101)
2447 self.assertTrue(rx[VXLAN].flags.G)
2448 self.assertTrue(rx[VXLAN].flags.Instance)
2449 self.assertTrue(rx[VXLAN].gpflags.A)
2450 self.assertFalse(rx[VXLAN].gpflags.D)
2451
2452 inner = rx[VXLAN].payload
2453
2454 self.assertEqual(inner[Ether].src, routed_src_mac)
2455 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2456 self.assertEqual(inner[IP].src, ep.ip4.address)
2457 self.assertEqual(inner[IP].dst, ip)
2458
2459 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002460 # remove the API remote EPs, only API sourced is gone, the DP
2461 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002462 #
2463 rep_88.remove_vpp_config()
2464 rep_2.remove_vpp_config()
2465
Neale Ranns00a469d2018-12-20 06:12:19 -08002466 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2467
2468 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2469 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2470 UDP(sport=1234, dport=1234) /
2471 Raw('\xa5' * 100))
2472 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002473
Neale Ranns13a08cc2018-11-07 09:25:54 -08002474 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002475
Neale Ranns13a08cc2018-11-07 09:25:54 -08002476 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2477 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2478 UDP(sport=1234, dport=1234) /
2479 Raw('\xa5' * 100))
2480 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002481
Neale Ranns13a08cc2018-11-07 09:25:54 -08002482 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002483 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08002484 # present (because it's DP learnt) when the TC ends so wait until
2485 # it is removed
2486 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002487 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2488 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002489
2490 #
2491 # shutdown with learnt endpoint present
2492 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002493 p = (Ether(src=self.pg2.remote_mac,
2494 dst=self.pg2.local_mac) /
2495 IP(src=self.pg2.remote_hosts[1].ip4,
2496 dst=self.pg2.local_ip4) /
2497 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002498 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002499 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2500 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2501 UDP(sport=1234, dport=1234) /
2502 Raw('\xa5' * 100))
2503
2504 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2505
2506 # endpoint learnt via the parent GBP-vxlan interface
2507 self.assertTrue(find_gbp_endpoint(self,
2508 vx_tun_l3._sw_if_index,
2509 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002510
2511 #
2512 # TODO
2513 # remote endpoint becomes local
2514 #
2515 self.pg2.unconfig_ip4()
2516 self.pg3.unconfig_ip4()
2517 self.pg4.unconfig_ip4()
2518
Neale Ranns13a08cc2018-11-07 09:25:54 -08002519 def test_gbp_redirect(self):
2520 """ GBP Endpoint Redirect """
2521
2522 self.vapi.cli("set logging class gbp debug")
2523
Neale Rannsb6a47952018-11-21 05:44:35 -08002524 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002525 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2526 routed_src_mac = "00:22:bd:f8:19:ff"
2527
2528 learnt = [{'mac': '00:00:11:11:11:02',
2529 'ip': '10.0.1.2',
2530 'ip6': '2001:10::2'},
2531 {'mac': '00:00:11:11:11:03',
2532 'ip': '10.0.1.3',
2533 'ip6': '2001:10::3'}]
2534
2535 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002536 # IP tables
2537 #
2538 t4 = VppIpTable(self, 1)
2539 t4.add_vpp_config()
2540 t6 = VppIpTable(self, 1, True)
2541 t6.add_vpp_config()
2542
2543 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2544 rd1.add_vpp_config()
2545
Ole Troan8006c6a2018-12-17 12:02:26 +01002546 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002547
2548 #
2549 # Bind the BVI to the RD
2550 #
2551 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2552 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2553
2554 #
2555 # Pg7 hosts a BD's UU-fwd
2556 #
2557 self.pg7.config_ip4()
2558 self.pg7.resolve_arp()
2559
2560 #
2561 # a GBP bridge domains for the EPs
2562 #
2563 bd1 = VppBridgeDomain(self, 1)
2564 bd1.add_vpp_config()
2565 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2566 gbd1.add_vpp_config()
2567
2568 bd2 = VppBridgeDomain(self, 2)
2569 bd2.add_vpp_config()
2570 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2571 gbd2.add_vpp_config()
2572
2573 # ... and has a /32 and /128 applied
2574 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2575 ip4_addr.add_vpp_config()
2576 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2577 ip6_addr.add_vpp_config()
2578 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2579 ip4_addr.add_vpp_config()
2580 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2581 ip6_addr.add_vpp_config()
2582
2583 #
2584 # The Endpoint-groups in which we are learning endpoints
2585 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002586 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002587 None, gbd1.bvi,
2588 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002589 "2001:10::128",
2590 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002591 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002592 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002593 None, gbd2.bvi,
2594 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002595 "2001:11::128",
2596 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002597 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002598 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002599 None, gbd1.bvi,
2600 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002601 "2001:12::128",
2602 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002603 epg_222.add_vpp_config()
2604
2605 #
2606 # a GBP bridge domains for the SEPs
2607 #
2608 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2609 self.pg7.remote_ip4, 116)
2610 bd_uu1.add_vpp_config()
2611 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2612 self.pg7.remote_ip4, 117)
2613 bd_uu2.add_vpp_config()
2614
2615 bd3 = VppBridgeDomain(self, 3)
2616 bd3.add_vpp_config()
2617 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2618 gbd3.add_vpp_config()
2619 bd4 = VppBridgeDomain(self, 4)
2620 bd4.add_vpp_config()
2621 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2622 gbd4.add_vpp_config()
2623
2624 #
2625 # EPGs in which the service endpoints exist
2626 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002627 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002628 None, gbd1.bvi,
2629 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002630 "4001:10::128",
2631 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002632 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002633 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002634 None, gbd2.bvi,
2635 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002636 "4001:11::128",
2637 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002638 epg_321.add_vpp_config()
2639
2640 #
2641 # three local endpoints
2642 #
2643 ep1 = VppGbpEndpoint(self, self.pg0,
2644 epg_220, None,
2645 "10.0.0.1", "11.0.0.1",
2646 "2001:10::1", "3001:10::1")
2647 ep1.add_vpp_config()
2648 ep2 = VppGbpEndpoint(self, self.pg1,
2649 epg_221, None,
2650 "10.0.1.1", "11.0.1.1",
2651 "2001:11::1", "3001:11::1")
2652 ep2.add_vpp_config()
2653 ep3 = VppGbpEndpoint(self, self.pg2,
2654 epg_222, None,
2655 "10.0.2.2", "11.0.2.2",
2656 "2001:12::1", "3001:12::1")
2657 ep3.add_vpp_config()
2658
2659 #
2660 # service endpoints
2661 #
2662 sep1 = VppGbpEndpoint(self, self.pg3,
2663 epg_320, None,
2664 "12.0.0.1", "13.0.0.1",
2665 "4001:10::1", "5001:10::1")
2666 sep1.add_vpp_config()
2667 sep2 = VppGbpEndpoint(self, self.pg4,
2668 epg_320, None,
2669 "12.0.0.2", "13.0.0.2",
2670 "4001:10::2", "5001:10::2")
2671 sep2.add_vpp_config()
2672 sep3 = VppGbpEndpoint(self, self.pg5,
2673 epg_321, None,
2674 "12.0.1.1", "13.0.1.1",
2675 "4001:11::1", "5001:11::1")
2676 sep3.add_vpp_config()
2677 # this EP is not installed immediately
2678 sep4 = VppGbpEndpoint(self, self.pg6,
2679 epg_321, None,
2680 "12.0.1.2", "13.0.1.2",
2681 "4001:11::2", "5001:11::2")
2682
2683 #
2684 # an L2 switch packet between local EPs in different EPGs
2685 # different dest ports on each so the are LB hashed differently
2686 #
2687 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2688 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2689 UDP(sport=1234, dport=1234) /
2690 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002691 (Ether(src=ep3.mac, dst=ep1.mac) /
2692 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2693 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002694 Raw('\xa5' * 100))]
2695 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2696 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2697 UDP(sport=1234, dport=1234) /
2698 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002699 (Ether(src=ep3.mac, dst=ep1.mac) /
2700 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002701 UDP(sport=1234, dport=1230) /
2702 Raw('\xa5' * 100))]
2703
2704 # should be dropped since no contract yet
2705 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2706 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2707
2708 #
2709 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2710 # one of the next-hops is via an EP that is not known
2711 #
2712 acl = VppGbpAcl(self)
2713 rule4 = acl.create_rule(permit_deny=1, proto=17)
2714 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2715 acl_index = acl.add_vpp_config([rule4, rule6])
2716
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002717 #
2718 # test the src-ip hash mode
2719 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002720 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002721 self, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002722 [VppGbpContractRule(
2723 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002724 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002725 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2726 sep1.ip4, sep1.epg.rd),
2727 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2728 sep2.ip4, sep2.epg.rd)]),
2729 VppGbpContractRule(
2730 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002731 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002732 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2733 sep3.ip6, sep3.epg.rd),
2734 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002735 sep4.ip6, sep4.epg.rd)])],
2736 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002737 c1.add_vpp_config()
2738
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002739 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002740 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002741 [VppGbpContractRule(
2742 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2743 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2744 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2745 sep1.ip4, sep1.epg.rd),
2746 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2747 sep2.ip4, sep2.epg.rd)]),
2748 VppGbpContractRule(
2749 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2750 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2751 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2752 sep3.ip6, sep3.epg.rd),
2753 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002754 sep4.ip6, sep4.epg.rd)])],
2755 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002756 c2.add_vpp_config()
2757
Neale Ranns13a08cc2018-11-07 09:25:54 -08002758 #
2759 # send again with the contract preset, now packets arrive
2760 # at SEP1 or SEP2 depending on the hashing
2761 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002762 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002763
2764 for rx in rxs:
2765 self.assertEqual(rx[Ether].src, routed_src_mac)
2766 self.assertEqual(rx[Ether].dst, sep1.mac)
2767 self.assertEqual(rx[IP].src, ep1.ip4.address)
2768 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2769
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002770 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2771
2772 for rx in rxs:
2773 self.assertEqual(rx[Ether].src, routed_src_mac)
2774 self.assertEqual(rx[Ether].dst, sep2.mac)
2775 self.assertEqual(rx[IP].src, ep3.ip4.address)
2776 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2777
Neale Ranns13a08cc2018-11-07 09:25:54 -08002778 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2779
2780 for rx in rxs:
2781 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2782 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2783 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2784 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2785 self.assertEqual(rx[VXLAN].vni, 117)
2786 self.assertTrue(rx[VXLAN].flags.G)
2787 self.assertTrue(rx[VXLAN].flags.Instance)
2788 # redirect policy has been applied
2789 self.assertTrue(rx[VXLAN].gpflags.A)
2790 self.assertFalse(rx[VXLAN].gpflags.D)
2791
2792 inner = rx[VXLAN].payload
2793
2794 self.assertEqual(inner[Ether].src, routed_src_mac)
2795 self.assertEqual(inner[Ether].dst, sep4.mac)
2796 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2797 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2798
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002799 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002800
2801 for rx in rxs:
2802 self.assertEqual(rx[Ether].src, routed_src_mac)
2803 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002804 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2805 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002806
2807 #
2808 # programme the unknown EP
2809 #
2810 sep4.add_vpp_config()
2811
2812 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2813
2814 for rx in rxs:
2815 self.assertEqual(rx[Ether].src, routed_src_mac)
2816 self.assertEqual(rx[Ether].dst, sep4.mac)
2817 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2818 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2819
2820 #
2821 # and revert back to unprogrammed
2822 #
2823 sep4.remove_vpp_config()
2824
2825 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2826
2827 for rx in rxs:
2828 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2829 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2830 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2831 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2832 self.assertEqual(rx[VXLAN].vni, 117)
2833 self.assertTrue(rx[VXLAN].flags.G)
2834 self.assertTrue(rx[VXLAN].flags.Instance)
2835 # redirect policy has been applied
2836 self.assertTrue(rx[VXLAN].gpflags.A)
2837 self.assertFalse(rx[VXLAN].gpflags.D)
2838
2839 inner = rx[VXLAN].payload
2840
2841 self.assertEqual(inner[Ether].src, routed_src_mac)
2842 self.assertEqual(inner[Ether].dst, sep4.mac)
2843 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2844 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2845
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002846 c1.remove_vpp_config()
2847 c2.remove_vpp_config()
2848
2849 #
2850 # test the symmetric hash mode
2851 #
2852 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002853 self, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002854 [VppGbpContractRule(
2855 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2856 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2857 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2858 sep1.ip4, sep1.epg.rd),
2859 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2860 sep2.ip4, sep2.epg.rd)]),
2861 VppGbpContractRule(
2862 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2863 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2864 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2865 sep3.ip6, sep3.epg.rd),
2866 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002867 sep4.ip6, sep4.epg.rd)])],
2868 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002869 c1.add_vpp_config()
2870
2871 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002872 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002873 [VppGbpContractRule(
2874 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2875 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2876 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2877 sep1.ip4, sep1.epg.rd),
2878 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2879 sep2.ip4, sep2.epg.rd)]),
2880 VppGbpContractRule(
2881 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2882 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2883 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2884 sep3.ip6, sep3.epg.rd),
2885 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002886 sep4.ip6, sep4.epg.rd)])],
2887 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002888 c2.add_vpp_config()
2889
2890 #
2891 # send again with the contract preset, now packets arrive
2892 # at SEP1 for both directions
2893 #
2894 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2895
2896 for rx in rxs:
2897 self.assertEqual(rx[Ether].src, routed_src_mac)
2898 self.assertEqual(rx[Ether].dst, sep1.mac)
2899 self.assertEqual(rx[IP].src, ep1.ip4.address)
2900 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2901
2902 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2903
2904 for rx in rxs:
2905 self.assertEqual(rx[Ether].src, routed_src_mac)
2906 self.assertEqual(rx[Ether].dst, sep1.mac)
2907 self.assertEqual(rx[IP].src, ep3.ip4.address)
2908 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2909
Neale Ranns13a08cc2018-11-07 09:25:54 -08002910 #
2911 # programme the unknown EP for the L3 tests
2912 #
2913 sep4.add_vpp_config()
2914
2915 #
2916 # an L3 switch packet between local EPs in different EPGs
2917 # different dest ports on each so the are LB hashed differently
2918 #
Ole Troan8006c6a2018-12-17 12:02:26 +01002919 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002920 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2921 UDP(sport=1234, dport=1234) /
2922 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002923 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002924 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2925 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002926 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01002927 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002928 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2929 UDP(sport=1234, dport=1234) /
2930 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01002931 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002932 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2933 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002934 Raw('\xa5' * 100))]
2935
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002936 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002937 self, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002938 [VppGbpContractRule(
2939 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2940 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2941 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2942 sep1.ip4, sep1.epg.rd),
2943 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2944 sep2.ip4, sep2.epg.rd)]),
2945 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002946 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002947 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002948 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2949 sep3.ip6, sep3.epg.rd),
2950 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2951 sep4.ip6, sep4.epg.rd)])],
2952 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002953 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002954
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002955 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002956
2957 for rx in rxs:
2958 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002959 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002960 self.assertEqual(rx[IP].src, ep1.ip4.address)
2961 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2962
2963 #
2964 # learn a remote EP in EPG 221
2965 #
2966 vx_tun_l3 = VppGbpVxlanTunnel(
2967 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002968 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2969 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002970 vx_tun_l3.add_vpp_config()
2971
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002972 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002973 self, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002974 [VppGbpContractRule(
2975 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2976 []),
2977 VppGbpContractRule(
2978 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002979 [])],
2980 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002981 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002982
2983 p = (Ether(src=self.pg7.remote_mac,
2984 dst=self.pg7.local_mac) /
2985 IP(src=self.pg7.remote_ip4,
2986 dst=self.pg7.local_ip4) /
2987 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002988 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01002989 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002990 IP(src="10.0.0.88", dst=ep1.ip4.address) /
2991 UDP(sport=1234, dport=1234) /
2992 Raw('\xa5' * 100))
2993
2994 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2995
2996 # endpoint learnt via the parent GBP-vxlan interface
2997 self.assertTrue(find_gbp_endpoint(self,
2998 vx_tun_l3._sw_if_index,
2999 ip="10.0.0.88"))
3000
3001 p = (Ether(src=self.pg7.remote_mac,
3002 dst=self.pg7.local_mac) /
3003 IP(src=self.pg7.remote_ip4,
3004 dst=self.pg7.local_ip4) /
3005 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003006 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003007 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003008 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3009 UDP(sport=1234, dport=1234) /
3010 Raw('\xa5' * 100))
3011
3012 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3013
3014 # endpoint learnt via the parent GBP-vxlan interface
3015 self.assertTrue(find_gbp_endpoint(self,
3016 vx_tun_l3._sw_if_index,
3017 ip="2001:10::88"))
3018
3019 #
3020 # L3 switch from local to remote EP
3021 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003022 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003023 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3024 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003025 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003026 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003027 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3028 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003029 Raw('\xa5' * 100))]
3030
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003031 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003032
3033 for rx in rxs:
3034 self.assertEqual(rx[Ether].src, routed_src_mac)
3035 self.assertEqual(rx[Ether].dst, sep1.mac)
3036 self.assertEqual(rx[IP].src, ep1.ip4.address)
3037 self.assertEqual(rx[IP].dst, "10.0.0.88")
3038
3039 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3040
3041 for rx in rxs:
3042 self.assertEqual(rx[Ether].src, routed_src_mac)
3043 self.assertEqual(rx[Ether].dst, sep4.mac)
3044 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3045 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3046
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003047 #
3048 # test the dst-ip hash mode
3049 #
3050 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003051 self, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003052 [VppGbpContractRule(
3053 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3054 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3055 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3056 sep1.ip4, sep1.epg.rd),
3057 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3058 sep2.ip4, sep2.epg.rd)]),
3059 VppGbpContractRule(
3060 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3061 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3062 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3063 sep3.ip6, sep3.epg.rd),
3064 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003065 sep4.ip6, sep4.epg.rd)])],
3066 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003067 c5.add_vpp_config()
3068
3069 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3070
3071 for rx in rxs:
3072 self.assertEqual(rx[Ether].src, routed_src_mac)
3073 self.assertEqual(rx[Ether].dst, sep1.mac)
3074 self.assertEqual(rx[IP].src, ep1.ip4.address)
3075 self.assertEqual(rx[IP].dst, "10.0.0.88")
3076
3077 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003078
3079 for rx in rxs:
3080 self.assertEqual(rx[Ether].src, routed_src_mac)
3081 self.assertEqual(rx[Ether].dst, sep3.mac)
3082 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3083 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3084
Neale Rannsb6a47952018-11-21 05:44:35 -08003085 #
3086 # cleanup
3087 #
3088 self.pg7.unconfig_ip4()
3089
3090 def test_gbp_l3_out(self):
3091 """ GBP L3 Out """
3092
3093 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3094 self.vapi.cli("set logging class gbp debug")
3095
3096 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3097 routed_src_mac = "00:22:bd:f8:19:ff"
3098
3099 #
3100 # IP tables
3101 #
3102 t4 = VppIpTable(self, 1)
3103 t4.add_vpp_config()
3104 t6 = VppIpTable(self, 1, True)
3105 t6.add_vpp_config()
3106
3107 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3108 rd1.add_vpp_config()
3109
Ole Troan8006c6a2018-12-17 12:02:26 +01003110 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003111
3112 #
3113 # Bind the BVI to the RD
3114 #
3115 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3116 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3117
3118 #
3119 # Pg7 hosts a BD's BUM
3120 # Pg1 some other l3 interface
3121 #
3122 self.pg7.config_ip4()
3123 self.pg7.resolve_arp()
3124
3125 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003126 # a multicast vxlan-gbp tunnel for broadcast in the BD
3127 #
3128 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3129 "239.1.1.1", 88,
3130 mcast_itf=self.pg7)
3131 tun_bm.add_vpp_config()
3132
3133 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003134 # a GBP external bridge domains for the EPs
3135 #
3136 bd1 = VppBridgeDomain(self, 1)
3137 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003138 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003139 gbd1.add_vpp_config()
3140
3141 #
3142 # The Endpoint-groups in which the external endpoints exist
3143 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003144 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003145 None, gbd1.bvi,
3146 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003147 "2001:10::128",
3148 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003149 epg_220.add_vpp_config()
3150
3151 # the BVIs have the subnets applied ...
3152 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3153 ip4_addr.add_vpp_config()
3154 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3155 ip6_addr.add_vpp_config()
3156
3157 # ... which are L3-out subnets
3158 l3o_1 = VppGbpSubnet(
3159 self, rd1, "10.0.0.0", 24,
3160 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003161 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003162 l3o_1.add_vpp_config()
3163
3164 #
3165 # an external interface attached to the outside world and the
3166 # external BD
3167 #
3168 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3169 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003170 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3171 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3172 vlan_101.admin_up()
3173 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3174
3175 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003176 ext_itf.add_vpp_config()
3177
3178 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003179 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003180 #
3181 vx_tun_l3 = VppGbpVxlanTunnel(
3182 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003183 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3184 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003185 vx_tun_l3.add_vpp_config()
3186
3187 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003188 # External Endpoints
3189 #
3190 eep1 = VppGbpEndpoint(self, vlan_100,
3191 epg_220, None,
3192 "10.0.0.1", "11.0.0.1",
3193 "2001:10::1", "3001::1",
3194 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3195 eep1.add_vpp_config()
3196 eep2 = VppGbpEndpoint(self, vlan_101,
3197 epg_220, None,
3198 "10.0.0.2", "11.0.0.2",
3199 "2001:10::2", "3001::2",
3200 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3201 eep2.add_vpp_config()
3202
3203 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003204 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003205 #
3206 rep = VppGbpEndpoint(self, vx_tun_l3,
3207 epg_220, None,
3208 "10.0.0.101", "11.0.0.101",
3209 "2001:10::101", "3001::101",
3210 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3211 self.pg7.local_ip4,
3212 self.pg7.remote_ip4,
3213 mac=None)
3214 rep.add_vpp_config()
3215
3216 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003217 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003218 #
3219 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3220 Dot1Q(vlan=100) /
3221 ARP(op="who-has",
3222 psrc=eep1.ip4.address, pdst="10.0.0.128",
3223 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3224 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3225
3226 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003227 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003228 # are ARP'd for
3229 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003230 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003231 Dot1Q(vlan=100) /
3232 IP(src="10.0.0.1", dst="10.0.0.88") /
3233 UDP(sport=1234, dport=1234) /
3234 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003235 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003236 Dot1Q(vlan=100) /
3237 IPv6(src="2001:10::1", dst="2001:10::88") /
3238 UDP(sport=1234, dport=1234) /
3239 Raw('\xa5' * 100))
3240
3241 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3242
3243 for rx in rxs:
3244 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3245 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3246 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3247 self.assertEqual(rx[IP].dst, "239.1.1.1")
3248 self.assertEqual(rx[VXLAN].vni, 88)
3249 self.assertTrue(rx[VXLAN].flags.G)
3250 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003251 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003252 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003253 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003254 self.assertFalse(rx[VXLAN].gpflags.D)
3255
3256 inner = rx[VXLAN].payload
3257
3258 self.assertTrue(inner.haslayer(ARP))
3259
3260 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003261 # remote to external
3262 #
3263 p = (Ether(src=self.pg7.remote_mac,
3264 dst=self.pg7.local_mac) /
3265 IP(src=self.pg7.remote_ip4,
3266 dst=self.pg7.local_ip4) /
3267 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003268 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003269 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003270 IP(src="10.0.0.101", dst="10.0.0.1") /
3271 UDP(sport=1234, dport=1234) /
3272 Raw('\xa5' * 100))
3273
3274 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3275
3276 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003277 # local EP pings router
3278 #
3279 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3280 Dot1Q(vlan=100) /
3281 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3282 ICMP(type='echo-request'))
3283
3284 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3285
3286 for rx in rxs:
3287 self.assertEqual(rx[Ether].src, str(self.router_mac))
3288 self.assertEqual(rx[Ether].dst, eep1.mac)
3289 self.assertEqual(rx[Dot1Q].vlan, 100)
3290
3291 #
3292 # local EP pings other local EP
3293 #
3294 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3295 Dot1Q(vlan=100) /
3296 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3297 ICMP(type='echo-request'))
3298
3299 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3300
3301 for rx in rxs:
3302 self.assertEqual(rx[Ether].src, eep1.mac)
3303 self.assertEqual(rx[Ether].dst, eep2.mac)
3304 self.assertEqual(rx[Dot1Q].vlan, 101)
3305
3306 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003307 # A subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08003308 #
3309 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003310 [VppRoutePath(eep1.ip4.address,
3311 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003312 table_id=t4.table_id)
3313 ip_220.add_vpp_config()
3314
3315 l3o_220 = VppGbpSubnet(
3316 self, rd1, "10.220.0.0", 24,
3317 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003318 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003319 l3o_220.add_vpp_config()
3320
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003321 #
3322 # A subnet reachable through the external EP2
3323 #
3324 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3325 [VppRoutePath(eep2.ip4.address,
3326 eep2.epg.bvi.sw_if_index)],
3327 table_id=t4.table_id)
3328 ip_221.add_vpp_config()
3329
3330 l3o_221 = VppGbpSubnet(
3331 self, rd1, "10.221.0.0", 24,
3332 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3333 sclass=4221)
3334 l3o_221.add_vpp_config()
3335
3336 #
3337 # ping between hosts in remote subnets
3338 # dropped without a contract
3339 #
3340 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3341 Dot1Q(vlan=100) /
3342 IP(src="10.220.0.1", dst="10.221.0.1") /
3343 ICMP(type='echo-request'))
3344
3345 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3346
3347 #
3348 # contract for the external nets to communicate
3349 #
3350 acl = VppGbpAcl(self)
3351 rule4 = acl.create_rule(permit_deny=1, proto=17)
3352 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3353 acl_index = acl.add_vpp_config([rule4, rule6])
3354
3355 c1 = VppGbpContract(
3356 self, 4220, 4221, acl_index,
3357 [VppGbpContractRule(
3358 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3359 []),
3360 VppGbpContractRule(
3361 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3362 [])],
3363 [ETH_P_IP, ETH_P_IPV6])
3364 c1.add_vpp_config()
3365
3366 #
3367 # Contracts allowing ext-net 200 to talk with external EPs
3368 #
3369 c2 = VppGbpContract(
3370 self, 4220, 113, acl_index,
3371 [VppGbpContractRule(
3372 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3373 []),
3374 VppGbpContractRule(
3375 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3376 [])],
3377 [ETH_P_IP, ETH_P_IPV6])
3378 c2.add_vpp_config()
3379 c3 = VppGbpContract(
3380 self, 113, 4220, acl_index,
3381 [VppGbpContractRule(
3382 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3383 []),
3384 VppGbpContractRule(
3385 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3386 [])],
3387 [ETH_P_IP, ETH_P_IPV6])
3388 c3.add_vpp_config()
3389
3390 #
3391 # ping between hosts in remote subnets
3392 #
3393 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3394 Dot1Q(vlan=100) /
3395 IP(src="10.220.0.1", dst="10.221.0.1") /
3396 UDP(sport=1234, dport=1234) /
3397 Raw('\xa5' * 100))
3398
3399 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3400
3401 for rx in rxs:
3402 self.assertEqual(rx[Ether].src, str(self.router_mac))
3403 self.assertEqual(rx[Ether].dst, eep2.mac)
3404 self.assertEqual(rx[Dot1Q].vlan, 101)
3405
3406 # we did not learn these external hosts
3407 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
3408 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
3409
3410 #
3411 # from remote external EP to local external EP
3412 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003413 p = (Ether(src=self.pg7.remote_mac,
3414 dst=self.pg7.local_mac) /
3415 IP(src=self.pg7.remote_ip4,
3416 dst=self.pg7.local_ip4) /
3417 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003418 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003419 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003420 IP(src="10.0.0.101", dst="10.220.0.1") /
3421 UDP(sport=1234, dport=1234) /
3422 Raw('\xa5' * 100))
3423
3424 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3425
3426 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003427 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07003428 #
3429 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3430 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003431 IP(src="10.220.0.1", dst=rep.ip4.address) /
3432 UDP(sport=1234, dport=1234) /
3433 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003434
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003435 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07003436
3437 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003438 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3439 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3440 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3441 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3442 self.assertEqual(rx[VXLAN].vni, 444)
3443 self.assertTrue(rx[VXLAN].flags.G)
3444 self.assertTrue(rx[VXLAN].flags.Instance)
3445 # the sclass of the ext-net the packet came from
3446 self.assertEqual(rx[VXLAN].gpid, 4220)
3447 # policy was applied to the original IP packet
3448 self.assertTrue(rx[VXLAN].gpflags.A)
3449 # since it's an external host the reciever should not learn it
3450 self.assertTrue(rx[VXLAN].gpflags.D)
3451 inner = rx[VXLAN].payload
3452 self.assertEqual(inner[IP].src, "10.220.0.1")
3453 self.assertEqual(inner[IP].dst, rep.ip4.address)
3454
3455 #
3456 # An external subnet reachable via the remote external EP
3457 #
3458
3459 #
3460 # first the VXLAN-GBP tunnel over which it is reached
3461 #
3462 vx_tun_r = VppVxlanGbpTunnel(
3463 self, self.pg7.local_ip4,
3464 self.pg7.remote_ip4, 445,
3465 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
3466 VXLAN_GBP_API_TUNNEL_MODE_L3))
3467 vx_tun_r.add_vpp_config()
3468 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
3469
3470 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
3471
3472 #
3473 # then the special adj to resolve through on that tunnel
3474 #
3475 n1 = VppNeighbor(self,
3476 vx_tun_r.sw_if_index,
3477 "00:0c:0c:0c:0c:0c",
3478 self.pg7.remote_ip4)
3479 n1.add_vpp_config()
3480
3481 #
3482 # the route via the adj above
3483 #
3484 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
3485 [VppRoutePath(self.pg7.remote_ip4,
3486 vx_tun_r.sw_if_index)],
3487 table_id=t4.table_id)
3488 ip_222.add_vpp_config()
3489
3490 l3o_222 = VppGbpSubnet(
3491 self, rd1, "10.222.0.0", 24,
3492 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3493 sclass=4222)
3494 l3o_222.add_vpp_config()
3495
3496 #
3497 # ping between hosts in local and remote external subnets
3498 # dropped without a contract
3499 #
3500 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3501 Dot1Q(vlan=100) /
3502 IP(src="10.220.0.1", dst="10.222.0.1") /
3503 UDP(sport=1234, dport=1234) /
3504 Raw('\xa5' * 100))
3505
3506 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3507
3508 #
3509 # Add contracts ext-nets for 220 -> 222
3510 #
3511 c4 = VppGbpContract(
3512 self, 4220, 4222, acl_index,
3513 [VppGbpContractRule(
3514 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3515 []),
3516 VppGbpContractRule(
3517 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3518 [])],
3519 [ETH_P_IP, ETH_P_IPV6])
3520 c4.add_vpp_config()
3521
3522 #
3523 # ping from host in local to remote external subnets
3524 #
3525 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3526 Dot1Q(vlan=100) /
3527 IP(src="10.220.0.1", dst="10.222.0.1") /
3528 UDP(sport=1234, dport=1234) /
3529 Raw('\xa5' * 100))
3530
3531 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
3532
3533 for rx in rxs:
3534 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3535 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3536 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3537 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3538 self.assertEqual(rx[VXLAN].vni, 445)
3539 self.assertTrue(rx[VXLAN].flags.G)
3540 self.assertTrue(rx[VXLAN].flags.Instance)
3541 # the sclass of the ext-net the packet came from
3542 self.assertEqual(rx[VXLAN].gpid, 4220)
3543 # policy was applied to the original IP packet
3544 self.assertTrue(rx[VXLAN].gpflags.A)
3545 # since it's an external host the reciever should not learn it
3546 self.assertTrue(rx[VXLAN].gpflags.D)
3547 inner = rx[VXLAN].payload
3548 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
3549 self.assertEqual(inner[IP].src, "10.220.0.1")
3550 self.assertEqual(inner[IP].dst, "10.222.0.1")
3551
3552 #
3553 # ping from host in remote to local external subnets
3554 # there's no contract for this, but the A bit is set.
3555 #
3556 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3557 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3558 UDP(sport=1234, dport=48879) /
3559 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3560 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3561 IP(src="10.222.0.1", dst="10.220.0.1") /
3562 UDP(sport=1234, dport=1234) /
3563 Raw('\xa5' * 100))
3564
3565 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3566 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07003567
3568 #
Neale Ranns2b600182019-03-29 05:08:27 -07003569 # ping from host in remote to remote external subnets
3570 # this is dropped by reflection check.
3571 #
3572 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3573 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3574 UDP(sport=1234, dport=48879) /
3575 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3576 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3577 IP(src="10.222.0.1", dst="10.222.0.2") /
3578 UDP(sport=1234, dport=1234) /
3579 Raw('\xa5' * 100))
3580
3581 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
3582
3583 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003584 # cleanup
3585 #
3586 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003587 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003588
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003589
3590if __name__ == '__main__':
3591 unittest.main(testRunner=VppTestRunner)