blob: ee842b3305224e85babf441a7b30327df8fc24dd [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 self.pg2.unconfig_ip4()
1909 self.pg3.unconfig_ip4()
1910 self.pg4.unconfig_ip4()
1911
1912 self.logger.info(self.vapi.cli("sh int"))
1913 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1914
Mohsin Kazmi7363d472019-04-04 13:22:15 +02001915 def test_gbp_bd_flags(self):
1916 """ GBP BD FLAGS """
1917
1918 #
1919 # IP tables
1920 #
1921 gt4 = VppIpTable(self, 1)
1922 gt4.add_vpp_config()
1923 gt6 = VppIpTable(self, 1, is_ip6=True)
1924 gt6.add_vpp_config()
1925
1926 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1927 rd1.add_vpp_config()
1928
1929 #
1930 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1931 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1932 #
1933 self.pg3.config_ip4()
1934 self.pg3.resolve_arp()
1935 self.pg4.config_ip4()
1936 self.pg4.resolve_arp()
1937
1938 #
1939 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1940 #
1941 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1942 "239.1.1.1", 88,
1943 mcast_itf=self.pg4)
1944 tun_bm.add_vpp_config()
1945
1946 #
1947 # a GBP bridge domain with a BVI and a UU-flood interface
1948 #
1949 bd1 = VppBridgeDomain(self, 1)
1950 bd1.add_vpp_config()
1951
1952 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm,
1953 uu_drop=True, bm_drop=True)
1954 gbd1.add_vpp_config()
1955
1956 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1957 self.logger.info(self.vapi.cli("sh gbp bridge"))
1958
1959 # ... and has a /32 applied
1960 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1961 ip_addr.add_vpp_config()
1962
1963 #
1964 # The Endpoint-group
1965 #
1966 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
1967 None, self.loop0,
1968 "10.0.0.128",
1969 "2001:10::128",
1970 VppGbpEndpointRetention(2))
1971 epg_220.add_vpp_config()
1972
1973 ep = VppGbpEndpoint(self, self.pg0,
1974 epg_220, None,
1975 "10.0.0.127", "11.0.0.127",
1976 "2001:10::1", "3001::1")
1977 ep.add_vpp_config()
1978 #
1979 # send UU/BM packet from the local EP with UU drop and BM drop enabled
1980 # in bd
1981 #
1982 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1983 self.logger.info(self.vapi.cli("sh gbp bridge"))
1984 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1985 IP(dst="10.0.0.133", src=ep.ip4.address) /
1986 UDP(sport=1234, dport=1234) /
1987 Raw('\xa5' * 100))
1988 self.send_and_assert_no_replies(ep.itf, [p_uu])
1989
1990 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1991 IP(dst="10.0.0.133", src=ep.ip4.address) /
1992 UDP(sport=1234, dport=1234) /
1993 Raw('\xa5' * 100))
1994 self.send_and_assert_no_replies(ep.itf, [p_bm])
1995
1996 self.pg3.unconfig_ip4()
1997 self.pg4.unconfig_ip4()
1998
1999 self.logger.info(self.vapi.cli("sh int"))
2000
Neale Rannsc29c0af2018-11-07 04:21:12 -08002001 def test_gbp_learn_vlan_l2(self):
2002 """ GBP L2 Endpoint w/ VLANs"""
2003
Neale Rannsb6a47952018-11-21 05:44:35 -08002004 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002005 learnt = [{'mac': '00:00:11:11:11:01',
2006 'ip': '10.0.0.1',
2007 'ip6': '2001:10::2'},
2008 {'mac': '00:00:11:11:11:02',
2009 'ip': '10.0.0.2',
2010 'ip6': '2001:10::3'}]
2011
2012 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002013 # IP tables
2014 #
2015 gt4 = VppIpTable(self, 1)
2016 gt4.add_vpp_config()
2017 gt6 = VppIpTable(self, 1, is_ip6=True)
2018 gt6.add_vpp_config()
2019
2020 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
2021 rd1.add_vpp_config()
2022
2023 #
2024 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2025 #
2026 self.pg2.config_ip4()
2027 self.pg2.resolve_arp()
2028 self.pg2.generate_remote_hosts(4)
2029 self.pg2.configure_ipv4_neighbors()
2030 self.pg3.config_ip4()
2031 self.pg3.resolve_arp()
2032
2033 #
2034 # The EP will be on a vlan sub-interface
2035 #
2036 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2037 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002038 self.vapi.l2_interface_vlan_tag_rewrite(
2039 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2040 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002041
2042 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2043 self.pg3.remote_ip4, 116)
2044 bd_uu_fwd.add_vpp_config()
2045
2046 #
2047 # a GBP bridge domain with a BVI and a UU-flood interface
2048 # The BD is marked as do not learn, so no endpoints are ever
2049 # learnt in this BD.
2050 #
2051 bd1 = VppBridgeDomain(self, 1)
2052 bd1.add_vpp_config()
2053 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
2054 learn=False)
2055 gbd1.add_vpp_config()
2056
2057 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2058 self.logger.info(self.vapi.cli("sh gbp bridge"))
2059
2060 # ... and has a /32 applied
2061 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2062 ip_addr.add_vpp_config()
2063
2064 #
2065 # The Endpoint-group in which we are learning endpoints
2066 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002067 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002068 None, self.loop0,
2069 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002070 "2001:10::128",
2071 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002072 epg_220.add_vpp_config()
2073
2074 #
2075 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002076 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002077 #
2078 vx_tun_l2_1 = VppGbpVxlanTunnel(
2079 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002080 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2081 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002082 vx_tun_l2_1.add_vpp_config()
2083
2084 #
2085 # A static endpoint that the learnt endpoints are trying to
2086 # talk to
2087 #
2088 ep = VppGbpEndpoint(self, vlan_11,
2089 epg_220, None,
2090 "10.0.0.127", "11.0.0.127",
2091 "2001:10::1", "3001::1")
2092 ep.add_vpp_config()
2093
2094 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2095
2096 #
2097 # Send to the static EP
2098 #
2099 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002100 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002101 # arriving on an unknown TEP
2102 p = (Ether(src=self.pg2.remote_mac,
2103 dst=self.pg2.local_mac) /
2104 IP(src=self.pg2.remote_hosts[1].ip4,
2105 dst=self.pg2.local_ip4) /
2106 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002107 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002108 Ether(src=l['mac'], dst=ep.mac) /
2109 IP(src=l['ip'], dst=ep.ip4.address) /
2110 UDP(sport=1234, dport=1234) /
2111 Raw('\xa5' * 100))
2112
2113 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2114
2115 #
2116 # packet to EP has the EP's vlan tag
2117 #
2118 for rx in rxs:
2119 self.assertEqual(rx[Dot1Q].vlan, 11)
2120
2121 #
2122 # the EP is not learnt since the BD setting prevents it
2123 # also no TEP too
2124 #
2125 self.assertFalse(find_gbp_endpoint(self,
2126 vx_tun_l2_1.sw_if_index,
2127 mac=l['mac']))
2128 self.assertEqual(INDEX_INVALID,
2129 find_vxlan_gbp_tunnel(
2130 self,
2131 self.pg2.local_ip4,
2132 self.pg2.remote_hosts[1].ip4,
2133 99))
2134
2135 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2136
2137 #
2138 # static to remotes
2139 # we didn't learn the remotes so they are sent to the UU-fwd
2140 #
2141 for l in learnt:
2142 p = (Ether(src=ep.mac, dst=l['mac']) /
2143 Dot1Q(vlan=11) /
2144 IP(dst=l['ip'], src=ep.ip4.address) /
2145 UDP(sport=1234, dport=1234) /
2146 Raw('\xa5' * 100))
2147
2148 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2149
2150 for rx in rxs:
2151 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2152 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2153 self.assertEqual(rx[UDP].dport, 48879)
2154 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002155 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002156 self.assertEqual(rx[VXLAN].vni, 116)
2157 self.assertTrue(rx[VXLAN].flags.G)
2158 self.assertTrue(rx[VXLAN].flags.Instance)
2159 self.assertFalse(rx[VXLAN].gpflags.A)
2160 self.assertFalse(rx[VXLAN].gpflags.D)
2161
2162 self.pg2.unconfig_ip4()
2163 self.pg3.unconfig_ip4()
2164
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002165 def test_gbp_learn_l3(self):
2166 """ GBP L3 Endpoint Learning """
2167
Neale Ranns13a08cc2018-11-07 09:25:54 -08002168 self.vapi.cli("set logging class gbp debug")
2169
Neale Rannsb6a47952018-11-21 05:44:35 -08002170 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002171 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2172 routed_src_mac = "00:22:bd:f8:19:ff"
2173
2174 learnt = [{'mac': '00:00:11:11:11:02',
2175 'ip': '10.0.1.2',
2176 'ip6': '2001:10::2'},
2177 {'mac': '00:00:11:11:11:03',
2178 'ip': '10.0.1.3',
2179 'ip6': '2001:10::3'}]
2180
2181 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002182 # IP tables
2183 #
2184 t4 = VppIpTable(self, 1)
2185 t4.add_vpp_config()
2186 t6 = VppIpTable(self, 1, True)
2187 t6.add_vpp_config()
2188
2189 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2190 self.pg4.remote_ip4, 114)
2191 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2192 self.pg4.remote_ip4, 116)
2193 tun_ip4_uu.add_vpp_config()
2194 tun_ip6_uu.add_vpp_config()
2195
2196 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2197 rd1.add_vpp_config()
2198
Ole Troan8006c6a2018-12-17 12:02:26 +01002199 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002200
2201 #
2202 # Bind the BVI to the RD
2203 #
2204 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2205 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2206
2207 #
2208 # Pg2 hosts the vxlan tunnel
2209 # hosts on pg2 to act as TEPs
2210 # pg3 is BD uu-fwd
2211 # pg4 is RD uu-fwd
2212 #
2213 self.pg2.config_ip4()
2214 self.pg2.resolve_arp()
2215 self.pg2.generate_remote_hosts(4)
2216 self.pg2.configure_ipv4_neighbors()
2217 self.pg3.config_ip4()
2218 self.pg3.resolve_arp()
2219 self.pg4.config_ip4()
2220 self.pg4.resolve_arp()
2221
2222 #
2223 # a GBP bridge domain with a BVI and a UU-flood interface
2224 #
2225 bd1 = VppBridgeDomain(self, 1)
2226 bd1.add_vpp_config()
2227 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2228 gbd1.add_vpp_config()
2229
2230 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2231 self.logger.info(self.vapi.cli("sh gbp bridge"))
2232 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002233
2234 # ... and has a /32 and /128 applied
2235 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2236 ip4_addr.add_vpp_config()
2237 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2238 ip6_addr.add_vpp_config()
2239
2240 #
2241 # The Endpoint-group in which we are learning endpoints
2242 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002243 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002244 None, self.loop0,
2245 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002246 "2001:10::128",
2247 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002248 epg_220.add_vpp_config()
2249
2250 #
2251 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002252 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002253 #
2254 vx_tun_l3 = VppGbpVxlanTunnel(
2255 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002256 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2257 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002258 vx_tun_l3.add_vpp_config()
2259
2260 #
2261 # A static endpoint that the learnt endpoints are trying to
2262 # talk to
2263 #
2264 ep = VppGbpEndpoint(self, self.pg0,
2265 epg_220, None,
2266 "10.0.0.127", "11.0.0.127",
2267 "2001:10::1", "3001::1")
2268 ep.add_vpp_config()
2269
2270 #
2271 # learn some remote IPv4 EPs
2272 #
2273 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002274 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002275 # arriving on an unknown TEP
2276 p = (Ether(src=self.pg2.remote_mac,
2277 dst=self.pg2.local_mac) /
2278 IP(src=self.pg2.remote_hosts[1].ip4,
2279 dst=self.pg2.local_ip4) /
2280 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002281 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002282 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2283 IP(src=l['ip'], dst=ep.ip4.address) /
2284 UDP(sport=1234, dport=1234) /
2285 Raw('\xa5' * 100))
2286
2287 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2288
2289 # the new TEP
2290 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2291 self,
2292 self.pg2.local_ip4,
2293 self.pg2.remote_hosts[1].ip4,
2294 vx_tun_l3.vni)
2295 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2296
2297 # endpoint learnt via the parent GBP-vxlan interface
2298 self.assertTrue(find_gbp_endpoint(self,
2299 vx_tun_l3._sw_if_index,
2300 ip=l['ip']))
2301
2302 #
2303 # Static IPv4 EP replies to learnt
2304 #
2305 for l in learnt:
2306 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2307 IP(dst=l['ip'], src=ep.ip4.address) /
2308 UDP(sport=1234, dport=1234) /
2309 Raw('\xa5' * 100))
2310
2311 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2312
2313 for rx in rxs:
2314 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2315 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2316 self.assertEqual(rx[UDP].dport, 48879)
2317 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002318 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002319 self.assertEqual(rx[VXLAN].vni, 101)
2320 self.assertTrue(rx[VXLAN].flags.G)
2321 self.assertTrue(rx[VXLAN].flags.Instance)
2322 self.assertTrue(rx[VXLAN].gpflags.A)
2323 self.assertFalse(rx[VXLAN].gpflags.D)
2324
2325 inner = rx[VXLAN].payload
2326
2327 self.assertEqual(inner[Ether].src, routed_src_mac)
2328 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2329 self.assertEqual(inner[IP].src, ep.ip4.address)
2330 self.assertEqual(inner[IP].dst, l['ip'])
2331
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002332 for l in learnt:
2333 self.assertFalse(find_gbp_endpoint(self,
2334 tep1_sw_if_index,
2335 ip=l['ip']))
2336
2337 #
2338 # learn some remote IPv6 EPs
2339 #
2340 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002341 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002342 # arriving on an unknown TEP
2343 p = (Ether(src=self.pg2.remote_mac,
2344 dst=self.pg2.local_mac) /
2345 IP(src=self.pg2.remote_hosts[1].ip4,
2346 dst=self.pg2.local_ip4) /
2347 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002348 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002349 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2350 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2351 UDP(sport=1234, dport=1234) /
2352 Raw('\xa5' * 100))
2353
2354 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2355
2356 # the new TEP
2357 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2358 self,
2359 self.pg2.local_ip4,
2360 self.pg2.remote_hosts[1].ip4,
2361 vx_tun_l3.vni)
2362 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2363
2364 self.logger.info(self.vapi.cli("show gbp bridge"))
2365 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2366 self.logger.info(self.vapi.cli("show gbp vxlan"))
2367 self.logger.info(self.vapi.cli("show int addr"))
2368
2369 # endpoint learnt via the TEP
2370 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2371
2372 self.logger.info(self.vapi.cli("show gbp endpoint"))
2373 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2374
2375 #
2376 # Static EP replies to learnt
2377 #
2378 for l in learnt:
2379 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2380 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2381 UDP(sport=1234, dport=1234) /
2382 Raw('\xa5' * 100))
2383
2384 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2385
2386 for rx in rxs:
2387 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2388 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2389 self.assertEqual(rx[UDP].dport, 48879)
2390 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002391 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002392 self.assertEqual(rx[VXLAN].vni, 101)
2393 self.assertTrue(rx[VXLAN].flags.G)
2394 self.assertTrue(rx[VXLAN].flags.Instance)
2395 self.assertTrue(rx[VXLAN].gpflags.A)
2396 self.assertFalse(rx[VXLAN].gpflags.D)
2397
2398 inner = rx[VXLAN].payload
2399
2400 self.assertEqual(inner[Ether].src, routed_src_mac)
2401 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2402 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2403 self.assertEqual(inner[IPv6].dst, l['ip6'])
2404
2405 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002406 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002407 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002408
2409 #
2410 # Static sends to unknown EP with no route
2411 #
2412 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2413 IP(dst="10.0.0.99", src=ep.ip4.address) /
2414 UDP(sport=1234, dport=1234) /
2415 Raw('\xa5' * 100))
2416
2417 self.send_and_assert_no_replies(self.pg0, [p])
2418
2419 #
2420 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002421 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002422 #
2423 se_10_24 = VppGbpSubnet(
2424 self, rd1, "10.0.0.0", 24,
2425 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2426 se_10_24.add_vpp_config()
2427
2428 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2429 IP(dst="10.0.0.99", src=ep.ip4.address) /
2430 UDP(sport=1234, dport=1234) /
2431 Raw('\xa5' * 100))
2432
2433 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2434 for rx in rxs:
2435 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2436 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2437 self.assertEqual(rx[UDP].dport, 48879)
2438 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002439 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002440 self.assertEqual(rx[VXLAN].vni, 114)
2441 self.assertTrue(rx[VXLAN].flags.G)
2442 self.assertTrue(rx[VXLAN].flags.Instance)
2443 # policy is not applied to packets sent to the uu-fwd interfaces
2444 self.assertFalse(rx[VXLAN].gpflags.A)
2445 self.assertFalse(rx[VXLAN].gpflags.D)
2446
2447 #
2448 # learn some remote IPv4 EPs
2449 #
2450 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002451 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002452 # arriving on an unknown TEP
2453 p = (Ether(src=self.pg2.remote_mac,
2454 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002455 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002456 dst=self.pg2.local_ip4) /
2457 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002458 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002459 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2460 IP(src=l['ip'], dst=ep.ip4.address) /
2461 UDP(sport=1234, dport=1234) /
2462 Raw('\xa5' * 100))
2463
2464 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2465
2466 # the new TEP
2467 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2468 self,
2469 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002470 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002471 vx_tun_l3.vni)
2472 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2473
2474 # endpoint learnt via the parent GBP-vxlan interface
2475 self.assertTrue(find_gbp_endpoint(self,
2476 vx_tun_l3._sw_if_index,
2477 ip=l['ip']))
2478
2479 #
2480 # Add a remote endpoint from the API
2481 #
2482 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2483 epg_220, None,
2484 "10.0.0.88", "11.0.0.88",
2485 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002486 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002487 self.pg2.local_ip4,
2488 self.pg2.remote_hosts[1].ip4,
2489 mac=None)
2490 rep_88.add_vpp_config()
2491
2492 #
2493 # Add a remote endpoint from the API that matches an existing one
2494 #
2495 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2496 epg_220, None,
2497 learnt[0]['ip'], "11.0.0.101",
2498 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002499 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002500 self.pg2.local_ip4,
2501 self.pg2.remote_hosts[1].ip4,
2502 mac=None)
2503 rep_2.add_vpp_config()
2504
2505 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002506 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002507 # packets should be send on the v4/v6 uu=fwd interface resp.
2508 #
2509 se_10_1_24 = VppGbpSubnet(
2510 self, rd1, "10.0.1.0", 24,
2511 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2512 se_10_1_24.add_vpp_config()
2513
2514 self.logger.info(self.vapi.cli("show gbp endpoint"))
2515
2516 ips = ["10.0.0.88", learnt[0]['ip']]
2517 for ip in ips:
2518 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2519 IP(dst=ip, src=ep.ip4.address) /
2520 UDP(sport=1234, dport=1234) /
2521 Raw('\xa5' * 100))
2522
2523 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2524
2525 for rx in rxs:
2526 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2527 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2528 self.assertEqual(rx[UDP].dport, 48879)
2529 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002530 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002531 self.assertEqual(rx[VXLAN].vni, 101)
2532 self.assertTrue(rx[VXLAN].flags.G)
2533 self.assertTrue(rx[VXLAN].flags.Instance)
2534 self.assertTrue(rx[VXLAN].gpflags.A)
2535 self.assertFalse(rx[VXLAN].gpflags.D)
2536
2537 inner = rx[VXLAN].payload
2538
2539 self.assertEqual(inner[Ether].src, routed_src_mac)
2540 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2541 self.assertEqual(inner[IP].src, ep.ip4.address)
2542 self.assertEqual(inner[IP].dst, ip)
2543
2544 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002545 # remove the API remote EPs, only API sourced is gone, the DP
2546 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002547 #
2548 rep_88.remove_vpp_config()
2549 rep_2.remove_vpp_config()
2550
Neale Ranns00a469d2018-12-20 06:12:19 -08002551 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2552
2553 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2554 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2555 UDP(sport=1234, dport=1234) /
2556 Raw('\xa5' * 100))
2557 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002558
Neale Ranns13a08cc2018-11-07 09:25:54 -08002559 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002560
Neale Ranns13a08cc2018-11-07 09:25:54 -08002561 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2562 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2563 UDP(sport=1234, dport=1234) /
2564 Raw('\xa5' * 100))
2565 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002566
Neale Ranns13a08cc2018-11-07 09:25:54 -08002567 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002568 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08002569 # present (because it's DP learnt) when the TC ends so wait until
2570 # it is removed
2571 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002572 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2573 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002574
2575 #
2576 # shutdown with learnt endpoint present
2577 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002578 p = (Ether(src=self.pg2.remote_mac,
2579 dst=self.pg2.local_mac) /
2580 IP(src=self.pg2.remote_hosts[1].ip4,
2581 dst=self.pg2.local_ip4) /
2582 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002583 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002584 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2585 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2586 UDP(sport=1234, dport=1234) /
2587 Raw('\xa5' * 100))
2588
2589 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2590
2591 # endpoint learnt via the parent GBP-vxlan interface
2592 self.assertTrue(find_gbp_endpoint(self,
2593 vx_tun_l3._sw_if_index,
2594 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002595
2596 #
2597 # TODO
2598 # remote endpoint becomes local
2599 #
2600 self.pg2.unconfig_ip4()
2601 self.pg3.unconfig_ip4()
2602 self.pg4.unconfig_ip4()
2603
Neale Ranns13a08cc2018-11-07 09:25:54 -08002604 def test_gbp_redirect(self):
2605 """ GBP Endpoint Redirect """
2606
2607 self.vapi.cli("set logging class gbp debug")
2608
Neale Rannsb6a47952018-11-21 05:44:35 -08002609 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002610 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2611 routed_src_mac = "00:22:bd:f8:19:ff"
2612
2613 learnt = [{'mac': '00:00:11:11:11:02',
2614 'ip': '10.0.1.2',
2615 'ip6': '2001:10::2'},
2616 {'mac': '00:00:11:11:11:03',
2617 'ip': '10.0.1.3',
2618 'ip6': '2001:10::3'}]
2619
2620 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002621 # IP tables
2622 #
2623 t4 = VppIpTable(self, 1)
2624 t4.add_vpp_config()
2625 t6 = VppIpTable(self, 1, True)
2626 t6.add_vpp_config()
2627
2628 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2629 rd1.add_vpp_config()
2630
Ole Troan8006c6a2018-12-17 12:02:26 +01002631 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002632
2633 #
2634 # Bind the BVI to the RD
2635 #
2636 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2637 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2638
2639 #
2640 # Pg7 hosts a BD's UU-fwd
2641 #
2642 self.pg7.config_ip4()
2643 self.pg7.resolve_arp()
2644
2645 #
2646 # a GBP bridge domains for the EPs
2647 #
2648 bd1 = VppBridgeDomain(self, 1)
2649 bd1.add_vpp_config()
2650 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2651 gbd1.add_vpp_config()
2652
2653 bd2 = VppBridgeDomain(self, 2)
2654 bd2.add_vpp_config()
2655 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2656 gbd2.add_vpp_config()
2657
2658 # ... and has a /32 and /128 applied
2659 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2660 ip4_addr.add_vpp_config()
2661 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2662 ip6_addr.add_vpp_config()
2663 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2664 ip4_addr.add_vpp_config()
2665 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2666 ip6_addr.add_vpp_config()
2667
2668 #
2669 # The Endpoint-groups in which we are learning endpoints
2670 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002671 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002672 None, gbd1.bvi,
2673 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002674 "2001:10::128",
2675 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002676 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002677 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002678 None, gbd2.bvi,
2679 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002680 "2001:11::128",
2681 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002682 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002683 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002684 None, gbd1.bvi,
2685 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002686 "2001:12::128",
2687 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002688 epg_222.add_vpp_config()
2689
2690 #
2691 # a GBP bridge domains for the SEPs
2692 #
2693 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2694 self.pg7.remote_ip4, 116)
2695 bd_uu1.add_vpp_config()
2696 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2697 self.pg7.remote_ip4, 117)
2698 bd_uu2.add_vpp_config()
2699
2700 bd3 = VppBridgeDomain(self, 3)
2701 bd3.add_vpp_config()
2702 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2703 gbd3.add_vpp_config()
2704 bd4 = VppBridgeDomain(self, 4)
2705 bd4.add_vpp_config()
2706 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2707 gbd4.add_vpp_config()
2708
2709 #
2710 # EPGs in which the service endpoints exist
2711 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002712 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002713 None, gbd1.bvi,
2714 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002715 "4001:10::128",
2716 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002717 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002718 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002719 None, gbd2.bvi,
2720 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002721 "4001:11::128",
2722 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002723 epg_321.add_vpp_config()
2724
2725 #
2726 # three local endpoints
2727 #
2728 ep1 = VppGbpEndpoint(self, self.pg0,
2729 epg_220, None,
2730 "10.0.0.1", "11.0.0.1",
2731 "2001:10::1", "3001:10::1")
2732 ep1.add_vpp_config()
2733 ep2 = VppGbpEndpoint(self, self.pg1,
2734 epg_221, None,
2735 "10.0.1.1", "11.0.1.1",
2736 "2001:11::1", "3001:11::1")
2737 ep2.add_vpp_config()
2738 ep3 = VppGbpEndpoint(self, self.pg2,
2739 epg_222, None,
2740 "10.0.2.2", "11.0.2.2",
2741 "2001:12::1", "3001:12::1")
2742 ep3.add_vpp_config()
2743
2744 #
2745 # service endpoints
2746 #
2747 sep1 = VppGbpEndpoint(self, self.pg3,
2748 epg_320, None,
2749 "12.0.0.1", "13.0.0.1",
2750 "4001:10::1", "5001:10::1")
2751 sep1.add_vpp_config()
2752 sep2 = VppGbpEndpoint(self, self.pg4,
2753 epg_320, None,
2754 "12.0.0.2", "13.0.0.2",
2755 "4001:10::2", "5001:10::2")
2756 sep2.add_vpp_config()
2757 sep3 = VppGbpEndpoint(self, self.pg5,
2758 epg_321, None,
2759 "12.0.1.1", "13.0.1.1",
2760 "4001:11::1", "5001:11::1")
2761 sep3.add_vpp_config()
2762 # this EP is not installed immediately
2763 sep4 = VppGbpEndpoint(self, self.pg6,
2764 epg_321, None,
2765 "12.0.1.2", "13.0.1.2",
2766 "4001:11::2", "5001:11::2")
2767
2768 #
2769 # an L2 switch packet between local EPs in different EPGs
2770 # different dest ports on each so the are LB hashed differently
2771 #
2772 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2773 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2774 UDP(sport=1234, dport=1234) /
2775 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002776 (Ether(src=ep3.mac, dst=ep1.mac) /
2777 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2778 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002779 Raw('\xa5' * 100))]
2780 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2781 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2782 UDP(sport=1234, dport=1234) /
2783 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002784 (Ether(src=ep3.mac, dst=ep1.mac) /
2785 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002786 UDP(sport=1234, dport=1230) /
2787 Raw('\xa5' * 100))]
2788
2789 # should be dropped since no contract yet
2790 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2791 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2792
2793 #
2794 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2795 # one of the next-hops is via an EP that is not known
2796 #
2797 acl = VppGbpAcl(self)
2798 rule4 = acl.create_rule(permit_deny=1, proto=17)
2799 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2800 acl_index = acl.add_vpp_config([rule4, rule6])
2801
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002802 #
2803 # test the src-ip hash mode
2804 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002805 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002806 self, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002807 [VppGbpContractRule(
2808 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002809 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002810 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2811 sep1.ip4, sep1.epg.rd),
2812 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2813 sep2.ip4, sep2.epg.rd)]),
2814 VppGbpContractRule(
2815 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002816 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002817 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2818 sep3.ip6, sep3.epg.rd),
2819 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002820 sep4.ip6, sep4.epg.rd)])],
2821 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002822 c1.add_vpp_config()
2823
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002824 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002825 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002826 [VppGbpContractRule(
2827 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2828 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2829 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2830 sep1.ip4, sep1.epg.rd),
2831 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2832 sep2.ip4, sep2.epg.rd)]),
2833 VppGbpContractRule(
2834 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2835 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2836 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2837 sep3.ip6, sep3.epg.rd),
2838 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002839 sep4.ip6, sep4.epg.rd)])],
2840 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002841 c2.add_vpp_config()
2842
Neale Ranns13a08cc2018-11-07 09:25:54 -08002843 #
2844 # send again with the contract preset, now packets arrive
2845 # at SEP1 or SEP2 depending on the hashing
2846 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002847 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002848
2849 for rx in rxs:
2850 self.assertEqual(rx[Ether].src, routed_src_mac)
2851 self.assertEqual(rx[Ether].dst, sep1.mac)
2852 self.assertEqual(rx[IP].src, ep1.ip4.address)
2853 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2854
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002855 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2856
2857 for rx in rxs:
2858 self.assertEqual(rx[Ether].src, routed_src_mac)
2859 self.assertEqual(rx[Ether].dst, sep2.mac)
2860 self.assertEqual(rx[IP].src, ep3.ip4.address)
2861 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2862
Neale Ranns13a08cc2018-11-07 09:25:54 -08002863 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2864
2865 for rx in rxs:
2866 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2867 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2868 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2869 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2870 self.assertEqual(rx[VXLAN].vni, 117)
2871 self.assertTrue(rx[VXLAN].flags.G)
2872 self.assertTrue(rx[VXLAN].flags.Instance)
2873 # redirect policy has been applied
2874 self.assertTrue(rx[VXLAN].gpflags.A)
2875 self.assertFalse(rx[VXLAN].gpflags.D)
2876
2877 inner = rx[VXLAN].payload
2878
2879 self.assertEqual(inner[Ether].src, routed_src_mac)
2880 self.assertEqual(inner[Ether].dst, sep4.mac)
2881 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2882 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2883
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002884 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002885
2886 for rx in rxs:
2887 self.assertEqual(rx[Ether].src, routed_src_mac)
2888 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002889 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2890 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002891
2892 #
2893 # programme the unknown EP
2894 #
2895 sep4.add_vpp_config()
2896
2897 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2898
2899 for rx in rxs:
2900 self.assertEqual(rx[Ether].src, routed_src_mac)
2901 self.assertEqual(rx[Ether].dst, sep4.mac)
2902 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2903 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2904
2905 #
2906 # and revert back to unprogrammed
2907 #
2908 sep4.remove_vpp_config()
2909
2910 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2911
2912 for rx in rxs:
2913 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2914 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2915 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2916 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2917 self.assertEqual(rx[VXLAN].vni, 117)
2918 self.assertTrue(rx[VXLAN].flags.G)
2919 self.assertTrue(rx[VXLAN].flags.Instance)
2920 # redirect policy has been applied
2921 self.assertTrue(rx[VXLAN].gpflags.A)
2922 self.assertFalse(rx[VXLAN].gpflags.D)
2923
2924 inner = rx[VXLAN].payload
2925
2926 self.assertEqual(inner[Ether].src, routed_src_mac)
2927 self.assertEqual(inner[Ether].dst, sep4.mac)
2928 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2929 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2930
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002931 c1.remove_vpp_config()
2932 c2.remove_vpp_config()
2933
2934 #
2935 # test the symmetric hash mode
2936 #
2937 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002938 self, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002939 [VppGbpContractRule(
2940 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2941 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2942 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2943 sep1.ip4, sep1.epg.rd),
2944 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2945 sep2.ip4, sep2.epg.rd)]),
2946 VppGbpContractRule(
2947 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2948 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2949 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2950 sep3.ip6, sep3.epg.rd),
2951 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002952 sep4.ip6, sep4.epg.rd)])],
2953 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002954 c1.add_vpp_config()
2955
2956 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002957 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002958 [VppGbpContractRule(
2959 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2960 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2961 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2962 sep1.ip4, sep1.epg.rd),
2963 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2964 sep2.ip4, sep2.epg.rd)]),
2965 VppGbpContractRule(
2966 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2967 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2968 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2969 sep3.ip6, sep3.epg.rd),
2970 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002971 sep4.ip6, sep4.epg.rd)])],
2972 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002973 c2.add_vpp_config()
2974
2975 #
2976 # send again with the contract preset, now packets arrive
2977 # at SEP1 for both directions
2978 #
2979 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2980
2981 for rx in rxs:
2982 self.assertEqual(rx[Ether].src, routed_src_mac)
2983 self.assertEqual(rx[Ether].dst, sep1.mac)
2984 self.assertEqual(rx[IP].src, ep1.ip4.address)
2985 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2986
2987 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2988
2989 for rx in rxs:
2990 self.assertEqual(rx[Ether].src, routed_src_mac)
2991 self.assertEqual(rx[Ether].dst, sep1.mac)
2992 self.assertEqual(rx[IP].src, ep3.ip4.address)
2993 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2994
Neale Ranns13a08cc2018-11-07 09:25:54 -08002995 #
2996 # programme the unknown EP for the L3 tests
2997 #
2998 sep4.add_vpp_config()
2999
3000 #
3001 # an L3 switch packet between local EPs in different EPGs
3002 # different dest ports on each so the are LB hashed differently
3003 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003004 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003005 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3006 UDP(sport=1234, dport=1234) /
3007 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003008 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003009 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3010 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003011 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003012 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003013 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3014 UDP(sport=1234, dport=1234) /
3015 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003016 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003017 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3018 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003019 Raw('\xa5' * 100))]
3020
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003021 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003022 self, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003023 [VppGbpContractRule(
3024 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3025 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3026 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3027 sep1.ip4, sep1.epg.rd),
3028 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3029 sep2.ip4, sep2.epg.rd)]),
3030 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08003031 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003032 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003033 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3034 sep3.ip6, sep3.epg.rd),
3035 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3036 sep4.ip6, sep4.epg.rd)])],
3037 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003038 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003039
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003040 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003041
3042 for rx in rxs:
3043 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003044 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003045 self.assertEqual(rx[IP].src, ep1.ip4.address)
3046 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3047
3048 #
3049 # learn a remote EP in EPG 221
3050 #
3051 vx_tun_l3 = VppGbpVxlanTunnel(
3052 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003053 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3054 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003055 vx_tun_l3.add_vpp_config()
3056
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003057 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003058 self, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003059 [VppGbpContractRule(
3060 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3061 []),
3062 VppGbpContractRule(
3063 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003064 [])],
3065 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003066 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003067
3068 p = (Ether(src=self.pg7.remote_mac,
3069 dst=self.pg7.local_mac) /
3070 IP(src=self.pg7.remote_ip4,
3071 dst=self.pg7.local_ip4) /
3072 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003073 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003074 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003075 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3076 UDP(sport=1234, dport=1234) /
3077 Raw('\xa5' * 100))
3078
3079 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3080
3081 # endpoint learnt via the parent GBP-vxlan interface
3082 self.assertTrue(find_gbp_endpoint(self,
3083 vx_tun_l3._sw_if_index,
3084 ip="10.0.0.88"))
3085
3086 p = (Ether(src=self.pg7.remote_mac,
3087 dst=self.pg7.local_mac) /
3088 IP(src=self.pg7.remote_ip4,
3089 dst=self.pg7.local_ip4) /
3090 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003091 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003092 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003093 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3094 UDP(sport=1234, dport=1234) /
3095 Raw('\xa5' * 100))
3096
3097 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3098
3099 # endpoint learnt via the parent GBP-vxlan interface
3100 self.assertTrue(find_gbp_endpoint(self,
3101 vx_tun_l3._sw_if_index,
3102 ip="2001:10::88"))
3103
3104 #
3105 # L3 switch from local to remote EP
3106 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003107 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003108 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3109 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003110 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003111 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003112 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3113 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003114 Raw('\xa5' * 100))]
3115
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003116 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003117
3118 for rx in rxs:
3119 self.assertEqual(rx[Ether].src, routed_src_mac)
3120 self.assertEqual(rx[Ether].dst, sep1.mac)
3121 self.assertEqual(rx[IP].src, ep1.ip4.address)
3122 self.assertEqual(rx[IP].dst, "10.0.0.88")
3123
3124 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3125
3126 for rx in rxs:
3127 self.assertEqual(rx[Ether].src, routed_src_mac)
3128 self.assertEqual(rx[Ether].dst, sep4.mac)
3129 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3130 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3131
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003132 #
3133 # test the dst-ip hash mode
3134 #
3135 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003136 self, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003137 [VppGbpContractRule(
3138 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3139 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3140 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3141 sep1.ip4, sep1.epg.rd),
3142 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3143 sep2.ip4, sep2.epg.rd)]),
3144 VppGbpContractRule(
3145 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3146 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3147 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3148 sep3.ip6, sep3.epg.rd),
3149 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003150 sep4.ip6, sep4.epg.rd)])],
3151 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003152 c5.add_vpp_config()
3153
3154 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3155
3156 for rx in rxs:
3157 self.assertEqual(rx[Ether].src, routed_src_mac)
3158 self.assertEqual(rx[Ether].dst, sep1.mac)
3159 self.assertEqual(rx[IP].src, ep1.ip4.address)
3160 self.assertEqual(rx[IP].dst, "10.0.0.88")
3161
3162 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003163
3164 for rx in rxs:
3165 self.assertEqual(rx[Ether].src, routed_src_mac)
3166 self.assertEqual(rx[Ether].dst, sep3.mac)
3167 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3168 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3169
Neale Rannsb6a47952018-11-21 05:44:35 -08003170 #
3171 # cleanup
3172 #
3173 self.pg7.unconfig_ip4()
3174
3175 def test_gbp_l3_out(self):
3176 """ GBP L3 Out """
3177
3178 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3179 self.vapi.cli("set logging class gbp debug")
3180
3181 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3182 routed_src_mac = "00:22:bd:f8:19:ff"
3183
3184 #
3185 # IP tables
3186 #
3187 t4 = VppIpTable(self, 1)
3188 t4.add_vpp_config()
3189 t6 = VppIpTable(self, 1, True)
3190 t6.add_vpp_config()
3191
3192 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3193 rd1.add_vpp_config()
3194
Ole Troan8006c6a2018-12-17 12:02:26 +01003195 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003196
3197 #
3198 # Bind the BVI to the RD
3199 #
3200 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3201 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3202
3203 #
3204 # Pg7 hosts a BD's BUM
3205 # Pg1 some other l3 interface
3206 #
3207 self.pg7.config_ip4()
3208 self.pg7.resolve_arp()
3209
3210 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003211 # a multicast vxlan-gbp tunnel for broadcast in the BD
3212 #
3213 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3214 "239.1.1.1", 88,
3215 mcast_itf=self.pg7)
3216 tun_bm.add_vpp_config()
3217
3218 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003219 # a GBP external bridge domains for the EPs
3220 #
3221 bd1 = VppBridgeDomain(self, 1)
3222 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003223 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003224 gbd1.add_vpp_config()
3225
3226 #
3227 # The Endpoint-groups in which the external endpoints exist
3228 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003229 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003230 None, gbd1.bvi,
3231 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003232 "2001:10::128",
3233 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003234 epg_220.add_vpp_config()
3235
3236 # the BVIs have the subnets applied ...
3237 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3238 ip4_addr.add_vpp_config()
3239 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3240 ip6_addr.add_vpp_config()
3241
3242 # ... which are L3-out subnets
3243 l3o_1 = VppGbpSubnet(
3244 self, rd1, "10.0.0.0", 24,
3245 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003246 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003247 l3o_1.add_vpp_config()
3248
3249 #
3250 # an external interface attached to the outside world and the
3251 # external BD
3252 #
3253 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3254 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003255 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3256 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3257 vlan_101.admin_up()
3258 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3259
3260 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003261 ext_itf.add_vpp_config()
3262
3263 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003264 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003265 #
3266 vx_tun_l3 = VppGbpVxlanTunnel(
3267 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003268 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3269 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003270 vx_tun_l3.add_vpp_config()
3271
3272 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003273 # External Endpoints
3274 #
3275 eep1 = VppGbpEndpoint(self, vlan_100,
3276 epg_220, None,
3277 "10.0.0.1", "11.0.0.1",
3278 "2001:10::1", "3001::1",
3279 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3280 eep1.add_vpp_config()
3281 eep2 = VppGbpEndpoint(self, vlan_101,
3282 epg_220, None,
3283 "10.0.0.2", "11.0.0.2",
3284 "2001:10::2", "3001::2",
3285 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3286 eep2.add_vpp_config()
3287
3288 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003289 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003290 #
3291 rep = VppGbpEndpoint(self, vx_tun_l3,
3292 epg_220, None,
3293 "10.0.0.101", "11.0.0.101",
3294 "2001:10::101", "3001::101",
3295 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3296 self.pg7.local_ip4,
3297 self.pg7.remote_ip4,
3298 mac=None)
3299 rep.add_vpp_config()
3300
3301 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003302 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003303 #
3304 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3305 Dot1Q(vlan=100) /
3306 ARP(op="who-has",
3307 psrc=eep1.ip4.address, pdst="10.0.0.128",
3308 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3309 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3310
3311 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003312 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003313 # are ARP'd for
3314 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003315 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003316 Dot1Q(vlan=100) /
3317 IP(src="10.0.0.1", dst="10.0.0.88") /
3318 UDP(sport=1234, dport=1234) /
3319 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003320 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003321 Dot1Q(vlan=100) /
3322 IPv6(src="2001:10::1", dst="2001:10::88") /
3323 UDP(sport=1234, dport=1234) /
3324 Raw('\xa5' * 100))
3325
3326 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3327
3328 for rx in rxs:
3329 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3330 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3331 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3332 self.assertEqual(rx[IP].dst, "239.1.1.1")
3333 self.assertEqual(rx[VXLAN].vni, 88)
3334 self.assertTrue(rx[VXLAN].flags.G)
3335 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003336 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003337 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003338 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003339 self.assertFalse(rx[VXLAN].gpflags.D)
3340
3341 inner = rx[VXLAN].payload
3342
3343 self.assertTrue(inner.haslayer(ARP))
3344
3345 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003346 # remote to external
3347 #
3348 p = (Ether(src=self.pg7.remote_mac,
3349 dst=self.pg7.local_mac) /
3350 IP(src=self.pg7.remote_ip4,
3351 dst=self.pg7.local_ip4) /
3352 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003353 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003354 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003355 IP(src="10.0.0.101", dst="10.0.0.1") /
3356 UDP(sport=1234, dport=1234) /
3357 Raw('\xa5' * 100))
3358
3359 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3360
3361 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003362 # local EP pings router
3363 #
3364 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3365 Dot1Q(vlan=100) /
3366 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3367 ICMP(type='echo-request'))
3368
3369 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3370
3371 for rx in rxs:
3372 self.assertEqual(rx[Ether].src, str(self.router_mac))
3373 self.assertEqual(rx[Ether].dst, eep1.mac)
3374 self.assertEqual(rx[Dot1Q].vlan, 100)
3375
3376 #
3377 # local EP pings other local EP
3378 #
3379 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3380 Dot1Q(vlan=100) /
3381 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3382 ICMP(type='echo-request'))
3383
3384 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3385
3386 for rx in rxs:
3387 self.assertEqual(rx[Ether].src, eep1.mac)
3388 self.assertEqual(rx[Ether].dst, eep2.mac)
3389 self.assertEqual(rx[Dot1Q].vlan, 101)
3390
3391 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003392 # A subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08003393 #
3394 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003395 [VppRoutePath(eep1.ip4.address,
3396 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003397 table_id=t4.table_id)
3398 ip_220.add_vpp_config()
3399
3400 l3o_220 = VppGbpSubnet(
3401 self, rd1, "10.220.0.0", 24,
3402 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003403 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003404 l3o_220.add_vpp_config()
3405
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003406 #
3407 # A subnet reachable through the external EP2
3408 #
3409 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3410 [VppRoutePath(eep2.ip4.address,
3411 eep2.epg.bvi.sw_if_index)],
3412 table_id=t4.table_id)
3413 ip_221.add_vpp_config()
3414
3415 l3o_221 = VppGbpSubnet(
3416 self, rd1, "10.221.0.0", 24,
3417 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3418 sclass=4221)
3419 l3o_221.add_vpp_config()
3420
3421 #
3422 # ping between hosts in remote subnets
3423 # dropped without a contract
3424 #
3425 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3426 Dot1Q(vlan=100) /
3427 IP(src="10.220.0.1", dst="10.221.0.1") /
3428 ICMP(type='echo-request'))
3429
3430 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3431
3432 #
3433 # contract for the external nets to communicate
3434 #
3435 acl = VppGbpAcl(self)
3436 rule4 = acl.create_rule(permit_deny=1, proto=17)
3437 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3438 acl_index = acl.add_vpp_config([rule4, rule6])
3439
3440 c1 = VppGbpContract(
3441 self, 4220, 4221, acl_index,
3442 [VppGbpContractRule(
3443 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3444 []),
3445 VppGbpContractRule(
3446 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3447 [])],
3448 [ETH_P_IP, ETH_P_IPV6])
3449 c1.add_vpp_config()
3450
3451 #
3452 # Contracts allowing ext-net 200 to talk with external EPs
3453 #
3454 c2 = VppGbpContract(
3455 self, 4220, 113, acl_index,
3456 [VppGbpContractRule(
3457 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3458 []),
3459 VppGbpContractRule(
3460 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3461 [])],
3462 [ETH_P_IP, ETH_P_IPV6])
3463 c2.add_vpp_config()
3464 c3 = VppGbpContract(
3465 self, 113, 4220, acl_index,
3466 [VppGbpContractRule(
3467 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3468 []),
3469 VppGbpContractRule(
3470 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3471 [])],
3472 [ETH_P_IP, ETH_P_IPV6])
3473 c3.add_vpp_config()
3474
3475 #
3476 # ping between hosts in remote subnets
3477 #
3478 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3479 Dot1Q(vlan=100) /
3480 IP(src="10.220.0.1", dst="10.221.0.1") /
3481 UDP(sport=1234, dport=1234) /
3482 Raw('\xa5' * 100))
3483
3484 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3485
3486 for rx in rxs:
3487 self.assertEqual(rx[Ether].src, str(self.router_mac))
3488 self.assertEqual(rx[Ether].dst, eep2.mac)
3489 self.assertEqual(rx[Dot1Q].vlan, 101)
3490
3491 # we did not learn these external hosts
3492 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
3493 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
3494
3495 #
3496 # from remote external EP to local external EP
3497 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003498 p = (Ether(src=self.pg7.remote_mac,
3499 dst=self.pg7.local_mac) /
3500 IP(src=self.pg7.remote_ip4,
3501 dst=self.pg7.local_ip4) /
3502 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003503 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003504 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003505 IP(src="10.0.0.101", dst="10.220.0.1") /
3506 UDP(sport=1234, dport=1234) /
3507 Raw('\xa5' * 100))
3508
3509 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3510
3511 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003512 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07003513 #
3514 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3515 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003516 IP(src="10.220.0.1", dst=rep.ip4.address) /
3517 UDP(sport=1234, dport=1234) /
3518 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003519
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003520 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07003521
3522 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003523 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3524 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3525 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3526 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3527 self.assertEqual(rx[VXLAN].vni, 444)
3528 self.assertTrue(rx[VXLAN].flags.G)
3529 self.assertTrue(rx[VXLAN].flags.Instance)
3530 # the sclass of the ext-net the packet came from
3531 self.assertEqual(rx[VXLAN].gpid, 4220)
3532 # policy was applied to the original IP packet
3533 self.assertTrue(rx[VXLAN].gpflags.A)
3534 # since it's an external host the reciever should not learn it
3535 self.assertTrue(rx[VXLAN].gpflags.D)
3536 inner = rx[VXLAN].payload
3537 self.assertEqual(inner[IP].src, "10.220.0.1")
3538 self.assertEqual(inner[IP].dst, rep.ip4.address)
3539
3540 #
3541 # An external subnet reachable via the remote external EP
3542 #
3543
3544 #
3545 # first the VXLAN-GBP tunnel over which it is reached
3546 #
3547 vx_tun_r = VppVxlanGbpTunnel(
3548 self, self.pg7.local_ip4,
3549 self.pg7.remote_ip4, 445,
3550 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
3551 VXLAN_GBP_API_TUNNEL_MODE_L3))
3552 vx_tun_r.add_vpp_config()
3553 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
3554
3555 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
3556
3557 #
3558 # then the special adj to resolve through on that tunnel
3559 #
3560 n1 = VppNeighbor(self,
3561 vx_tun_r.sw_if_index,
3562 "00:0c:0c:0c:0c:0c",
3563 self.pg7.remote_ip4)
3564 n1.add_vpp_config()
3565
3566 #
3567 # the route via the adj above
3568 #
3569 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
3570 [VppRoutePath(self.pg7.remote_ip4,
3571 vx_tun_r.sw_if_index)],
3572 table_id=t4.table_id)
3573 ip_222.add_vpp_config()
3574
3575 l3o_222 = VppGbpSubnet(
3576 self, rd1, "10.222.0.0", 24,
3577 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3578 sclass=4222)
3579 l3o_222.add_vpp_config()
3580
3581 #
3582 # ping between hosts in local and remote external subnets
3583 # dropped without a contract
3584 #
3585 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3586 Dot1Q(vlan=100) /
3587 IP(src="10.220.0.1", dst="10.222.0.1") /
3588 UDP(sport=1234, dport=1234) /
3589 Raw('\xa5' * 100))
3590
3591 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3592
3593 #
3594 # Add contracts ext-nets for 220 -> 222
3595 #
3596 c4 = VppGbpContract(
3597 self, 4220, 4222, acl_index,
3598 [VppGbpContractRule(
3599 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3600 []),
3601 VppGbpContractRule(
3602 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3603 [])],
3604 [ETH_P_IP, ETH_P_IPV6])
3605 c4.add_vpp_config()
3606
3607 #
3608 # ping from host in local to remote external subnets
3609 #
3610 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3611 Dot1Q(vlan=100) /
3612 IP(src="10.220.0.1", dst="10.222.0.1") /
3613 UDP(sport=1234, dport=1234) /
3614 Raw('\xa5' * 100))
3615
3616 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
3617
3618 for rx in rxs:
3619 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3620 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3621 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3622 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3623 self.assertEqual(rx[VXLAN].vni, 445)
3624 self.assertTrue(rx[VXLAN].flags.G)
3625 self.assertTrue(rx[VXLAN].flags.Instance)
3626 # the sclass of the ext-net the packet came from
3627 self.assertEqual(rx[VXLAN].gpid, 4220)
3628 # policy was applied to the original IP packet
3629 self.assertTrue(rx[VXLAN].gpflags.A)
3630 # since it's an external host the reciever should not learn it
3631 self.assertTrue(rx[VXLAN].gpflags.D)
3632 inner = rx[VXLAN].payload
3633 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
3634 self.assertEqual(inner[IP].src, "10.220.0.1")
3635 self.assertEqual(inner[IP].dst, "10.222.0.1")
3636
3637 #
3638 # ping from host in remote to local external subnets
3639 # there's no contract for this, but the A bit is set.
3640 #
3641 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3642 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3643 UDP(sport=1234, dport=48879) /
3644 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3645 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3646 IP(src="10.222.0.1", dst="10.220.0.1") /
3647 UDP(sport=1234, dport=1234) /
3648 Raw('\xa5' * 100))
3649
3650 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3651 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07003652
3653 #
Neale Ranns2b600182019-03-29 05:08:27 -07003654 # ping from host in remote to remote external subnets
3655 # this is dropped by reflection check.
3656 #
3657 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3658 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3659 UDP(sport=1234, dport=48879) /
3660 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3661 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3662 IP(src="10.222.0.1", dst="10.222.0.2") /
3663 UDP(sport=1234, dport=1234) /
3664 Raw('\xa5' * 100))
3665
3666 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
3667
3668 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003669 # cleanup
3670 #
3671 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003672 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003673
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003674
3675if __name__ == '__main__':
3676 unittest.main(testRunner=VppTestRunner)