blob: df529c6c8809cd7e31b04f23adacf2863f015180 [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 Ranns796c84b2019-03-28 07:56:23 -0700450 r = self._test.vapi.gbp_contract_add_del(
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800451 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 Ranns796c84b2019-03-28 07:56:23 -0700457 self.stats_index = r.stats_index
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800458 self._test.registry.register(self, self._test.logger)
459
460 def remove_vpp_config(self):
461 self._test.vapi.gbp_contract_add_del(
462 0,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700463 self.sclass,
464 self.dclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800465 self.acl_index,
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700466 [],
467 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800468
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800469 def object_id(self):
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700470 return "gbp-contract:[%d:%s:%d]" % (self.sclass,
471 self.dclass,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800472 self.acl_index)
473
474 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700475 cs = self._test.vapi.gbp_contract_dump()
476 for c in cs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700477 if c.contract.sclass == self.sclass \
478 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800479 return True
480 return False
481
Neale Ranns796c84b2019-03-28 07:56:23 -0700482 def get_drop_stats(self):
483 c = self._test.statistics.get_counter("/net/gbp/contract/drop")
484 return c[0][self.stats_index]
485
486 def get_permit_stats(self):
487 c = self._test.statistics.get_counter("/net/gbp/contract/permit")
488 return c[0][self.stats_index]
489
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800490
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700491class VppGbpVxlanTunnel(VppInterface):
492 """
493 GBP VXLAN tunnel
494 """
495
Neale Ranns8da9fc62019-03-04 14:08:11 -0800496 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700497 super(VppGbpVxlanTunnel, self).__init__(test)
498 self._test = test
499 self.vni = vni
500 self.bd_rd_id = bd_rd_id
501 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800502 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700503
504 def add_vpp_config(self):
505 r = self._test.vapi.gbp_vxlan_tunnel_add(
506 self.vni,
507 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800508 self.mode,
509 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700510 self.set_sw_if_index(r.sw_if_index)
511 self._test.registry.register(self, self._test.logger)
512
513 def remove_vpp_config(self):
514 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
515
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700516 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800517 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700518
519 def query_vpp_config(self):
520 return find_gbp_vxlan(self._test, self.vni)
521
522
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200523class VppGbpAcl(VppObject):
524 """
525 GBP Acl
526 """
527
528 def __init__(self, test):
529 self._test = test
530 self.acl_index = 4294967295
531
532 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800533 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
534 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200535 dport_from=0, dport_to=65535):
536 if proto == -1 or proto == 0:
537 sport_to = 0
538 dport_to = sport_to
539 elif proto == 1 or proto == 58:
540 sport_to = 255
541 dport_to = sport_to
542 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
543 'srcport_or_icmptype_first': sport_from,
544 'srcport_or_icmptype_last': sport_to,
545 'src_ip_prefix_len': s_prefix,
546 'src_ip_addr': s_ip,
547 'dstport_or_icmpcode_first': dport_from,
548 'dstport_or_icmpcode_last': dport_to,
549 'dst_ip_prefix_len': d_prefix,
550 'dst_ip_addr': d_ip})
551 return rule
552
553 def add_vpp_config(self, rules):
554
555 reply = self._test.vapi.acl_add_replace(self.acl_index,
556 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800557 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200558 self.acl_index = reply.acl_index
559 return self.acl_index
560
561 def remove_vpp_config(self):
562 self._test.vapi.acl_del(self.acl_index)
563
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200564 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700565 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200566
567 def query_vpp_config(self):
568 cs = self._test.vapi.acl_dump()
569 for c in cs:
570 if c.acl_index == self.acl_index:
571 return True
572 return False
573
574
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800575class TestGBP(VppTestCase):
576 """ GBP Test Case """
577
578 def setUp(self):
579 super(TestGBP, self).setUp()
580
Neale Ranns25b04942018-04-04 09:34:50 -0700581 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700582 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700583
Ole Troan8006c6a2018-12-17 12:02:26 +0100584 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800585
586 for i in self.pg_interfaces:
587 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700588 for i in self.lo_interfaces:
589 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800590
591 def tearDown(self):
592 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700593 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800594
595 super(TestGBP, self).tearDown()
596
Neale Ranns25b04942018-04-04 09:34:50 -0700597 def send_and_expect_bridged(self, src, tx, dst):
598 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800599
Neale Ranns25b04942018-04-04 09:34:50 -0700600 for r in rx:
601 self.assertEqual(r[Ether].src, tx[0][Ether].src)
602 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
603 self.assertEqual(r[IP].src, tx[0][IP].src)
604 self.assertEqual(r[IP].dst, tx[0][IP].dst)
605 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800606
Neale Ranns25b04942018-04-04 09:34:50 -0700607 def send_and_expect_bridged6(self, src, tx, dst):
608 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800609
Neale Ranns25b04942018-04-04 09:34:50 -0700610 for r in rx:
611 self.assertEqual(r[Ether].src, tx[0][Ether].src)
612 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
613 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
614 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
615 return rx
616
617 def send_and_expect_routed(self, src, tx, dst, src_mac):
618 rx = self.send_and_expect(src, tx, dst)
619
620 for r in rx:
621 self.assertEqual(r[Ether].src, src_mac)
622 self.assertEqual(r[Ether].dst, dst.remote_mac)
623 self.assertEqual(r[IP].src, tx[0][IP].src)
624 self.assertEqual(r[IP].dst, tx[0][IP].dst)
625 return rx
626
627 def send_and_expect_natted(self, src, tx, dst, src_ip):
628 rx = self.send_and_expect(src, tx, dst)
629
630 for r in rx:
631 self.assertEqual(r[Ether].src, tx[0][Ether].src)
632 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
633 self.assertEqual(r[IP].src, src_ip)
634 self.assertEqual(r[IP].dst, tx[0][IP].dst)
635 return rx
636
Neale Ranns4a6d0232018-04-24 07:45:33 -0700637 def send_and_expect_natted6(self, src, tx, dst, src_ip):
638 rx = self.send_and_expect(src, tx, dst)
639
640 for r in rx:
641 self.assertEqual(r[Ether].src, tx[0][Ether].src)
642 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
643 self.assertEqual(r[IPv6].src, src_ip)
644 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
645 return rx
646
Neale Ranns25b04942018-04-04 09:34:50 -0700647 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
648 rx = self.send_and_expect(src, tx, dst)
649
650 for r in rx:
651 self.assertEqual(r[Ether].src, tx[0][Ether].src)
652 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
653 self.assertEqual(r[IP].dst, dst_ip)
654 self.assertEqual(r[IP].src, tx[0][IP].src)
655 return rx
656
Neale Ranns4a6d0232018-04-24 07:45:33 -0700657 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
658 rx = self.send_and_expect(src, tx, dst)
659
660 for r in rx:
661 self.assertEqual(r[Ether].src, tx[0][Ether].src)
662 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
663 self.assertEqual(r[IPv6].dst, dst_ip)
664 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
665 return rx
666
Neale Ranns25b04942018-04-04 09:34:50 -0700667 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
668 rx = self.send_and_expect(src, tx, dst)
669
670 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100671 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700672 self.assertEqual(r[Ether].dst, dst.remote_mac)
673 self.assertEqual(r[IP].dst, dst_ip)
674 self.assertEqual(r[IP].src, src_ip)
675 return rx
676
Neale Ranns4a6d0232018-04-24 07:45:33 -0700677 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
678 rx = self.send_and_expect(src, tx, dst)
679
680 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100681 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700682 self.assertEqual(r[Ether].dst, dst.remote_mac)
683 self.assertEqual(r[IPv6].dst, dst_ip)
684 self.assertEqual(r[IPv6].src, src_ip)
685 return rx
686
Neale Ranns25b04942018-04-04 09:34:50 -0700687 def test_gbp(self):
688 """ Group Based Policy """
689
Neale Rannsb6a47952018-11-21 05:44:35 -0800690 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
691
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800692 #
Neale Ranns25b04942018-04-04 09:34:50 -0700693 # Bridge Domains
694 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700695 bd1 = VppBridgeDomain(self, 1)
696 bd2 = VppBridgeDomain(self, 2)
697 bd20 = VppBridgeDomain(self, 20)
698
699 bd1.add_vpp_config()
700 bd2.add_vpp_config()
701 bd20.add_vpp_config()
702
703 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
704 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
705 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
706
707 gbd1.add_vpp_config()
708 gbd2.add_vpp_config()
709 gbd20.add_vpp_config()
710
711 #
712 # Route Domains
713 #
714 gt4 = VppIpTable(self, 0)
715 gt4.add_vpp_config()
716 gt6 = VppIpTable(self, 0, is_ip6=True)
717 gt6.add_vpp_config()
718 nt4 = VppIpTable(self, 20)
719 nt4.add_vpp_config()
720 nt6 = VppIpTable(self, 20, is_ip6=True)
721 nt6.add_vpp_config()
722
723 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
724 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
725
726 rd0.add_vpp_config()
727 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700728
729 #
730 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700731 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
732 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000733 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
734 self.pg4, self.loop0,
735 "10.0.0.128", "2001:10::128"),
736 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
737 self.pg5, self.loop0,
738 "10.0.1.128", "2001:10:1::128"),
739 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
740 self.pg6, self.loop1,
741 "10.0.2.128", "2001:10:2::128"),
742 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
743 self.pg7, self.loop2,
744 "11.0.0.128", "3001::128"),
745 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
746 self.pg8, self.loop2,
747 "11.0.0.129", "3001::129")]
748 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
749 VppGbpRecirc(self, epgs[1], self.loop4),
750 VppGbpRecirc(self, epgs[2], self.loop5),
751 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
752 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700753
754 epg_nat = epgs[3]
755 recirc_nat = recircs[3]
756
757 #
758 # 4 end-points, 2 in the same subnet, 3 in the same BD
759 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700760 eps = [VppGbpEndpoint(self, self.pg0,
761 epgs[0], recircs[0],
762 "10.0.0.1", "11.0.0.1",
763 "2001:10::1", "3001::1"),
764 VppGbpEndpoint(self, self.pg1,
765 epgs[0], recircs[0],
766 "10.0.0.2", "11.0.0.2",
767 "2001:10::2", "3001::2"),
768 VppGbpEndpoint(self, self.pg2,
769 epgs[1], recircs[1],
770 "10.0.1.1", "11.0.0.3",
771 "2001:10:1::1", "3001::3"),
772 VppGbpEndpoint(self, self.pg3,
773 epgs[2], recircs[2],
774 "10.0.2.1", "11.0.0.4",
775 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700776
777 #
778 # Config related to each of the EPGs
779 #
780 for epg in epgs:
781 # IP config on the BVI interfaces
782 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700783 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
784 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
785 self.vapi.sw_interface_set_mac_address(
786 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100787 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700788
789 # The BVIs are NAT inside interfaces
790 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
791 is_inside=1,
792 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700793 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
794 is_inside=1,
795 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700796
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700797 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
798 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
799 if_ip4.add_vpp_config()
800 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700801
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700802 # EPG uplink interfaces in the RD
803 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
804 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700805
806 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700807 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100808 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700809 epg.bvi_ip4)
810 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100811 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700812 epg.bvi_ip6)
813 epg.bd_arp_ip4.add_vpp_config()
814 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700815
816 # EPG in VPP
817 epg.add_vpp_config()
818
819 for recirc in recircs:
820 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700821 VppIpInterfaceBind(self, recirc.recirc,
822 recirc.epg.rd.t4).add_vpp_config()
823 VppIpInterfaceBind(self, recirc.recirc,
824 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700825
Neale Ranns4a6d0232018-04-24 07:45:33 -0700826 self.vapi.nat44_interface_add_del_feature(
827 recirc.recirc.sw_if_index,
828 is_inside=0,
829 is_add=1)
830 self.vapi.nat66_add_del_interface(
831 recirc.recirc.sw_if_index,
832 is_inside=0,
833 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700834
835 recirc.add_vpp_config()
836
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700837 for recirc in recircs:
838 self.assertTrue(find_bridge_domain_port(self,
839 recirc.epg.bd.bd.bd_id,
840 recirc.recirc.sw_if_index))
841
Neale Ranns25b04942018-04-04 09:34:50 -0700842 for ep in eps:
843 self.pg_enable_capture(self.pg_interfaces)
844 self.pg_start()
845 #
846 # routes to the endpoints. We need these since there are no
847 # adj-fibs due to the fact the the BVI address has /32 and
848 # the subnet is not attached.
849 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700850 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700851 # Add static mappings for each EP from the 10/8 to 11/8 network
852 if ip.af == AF_INET:
853 self.vapi.nat44_add_del_static_mapping(ip.bytes,
854 fip.bytes,
855 vrf_id=0,
856 addr_only=1)
857 else:
858 self.vapi.nat66_add_del_static_mapping(ip.bytes,
859 fip.bytes,
860 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700861
Neale Ranns25b04942018-04-04 09:34:50 -0700862 # VPP EP create ...
863 ep.add_vpp_config()
864
Neale Rannsc0a93142018-09-05 15:42:26 -0700865 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700866
Neale Rannsc0a93142018-09-05 15:42:26 -0700867 # ... results in a Gratuitous ARP/ND on the EPG's uplink
868 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
869
870 for ii, ip in enumerate(ep.ips):
871 p = rx[ii]
872
873 if ip.is_ip6:
874 self.assertTrue(p.haslayer(ICMPv6ND_NA))
875 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
876 else:
877 self.assertTrue(p.haslayer(ARP))
878 self.assertEqual(p[ARP].psrc, ip.address)
879 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700880
881 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700882 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700883 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
884 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700885
Neale Rannsc0a93142018-09-05 15:42:26 -0700886 # floating IPs route via EPG recirc
887 r = VppIpRoute(self, fip.address, fip.length,
888 [VppRoutePath(fip.address,
889 ep.recirc.recirc.sw_if_index,
890 is_dvr=1,
891 proto=fip.dpo_proto)],
892 table_id=20,
893 is_ip6=fip.is_ip6)
894 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700895
896 # L2 FIB entries in the NAT EPG BD to bridge the packets from
897 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700898 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
899 ep.recirc.recirc, bvi_mac=0)
900 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700901
902 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700903 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700904 #
905 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
906 src=self.pg0.remote_mac) /
907 ARP(op="who-has",
908 hwdst="ff:ff:ff:ff:ff:ff",
909 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700910 pdst="10.0.0.88",
911 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700912
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700913 self.vapi.cli("clear trace")
914 self.pg0.add_stream(pkt_arp)
915
916 self.pg_enable_capture(self.pg_interfaces)
917 self.pg_start()
918
919 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700920
921 #
922 # ARP/ND packets get a response
923 #
924 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
925 src=self.pg0.remote_mac) /
926 ARP(op="who-has",
927 hwdst="ff:ff:ff:ff:ff:ff",
928 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700929 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700930 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700931
932 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
933
Neale Rannsc0a93142018-09-05 15:42:26 -0700934 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700935 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700936 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
937 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700938 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700939 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700940 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
941 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
942
943 #
944 # broadcast packets are flooded
945 #
946 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
947 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700948 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700949 UDP(sport=1234, dport=1234) /
950 Raw('\xa5' * 100))
951
952 self.vapi.cli("clear trace")
953 self.pg0.add_stream(pkt_bcast)
954
955 self.pg_enable_capture(self.pg_interfaces)
956 self.pg_start()
957
958 rxd = eps[1].itf.get_capture(1)
959 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
960 rxd = epgs[0].uplink.get_capture(1)
961 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
962
963 #
964 # packets to non-local L3 destinations dropped
965 #
966 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100967 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700968 IP(src=eps[0].ip4.address,
969 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700970 UDP(sport=1234, dport=1234) /
971 Raw('\xa5' * 100))
972 pkt_inter_epg_222_ip4 = (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 IP(src=eps[0].ip4.address,
975 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700976 UDP(sport=1234, dport=1234) /
977 Raw('\xa5' * 100))
978
979 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
980
981 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100982 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700983 IPv6(src=eps[0].ip6.address,
984 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700985 UDP(sport=1234, dport=1234) /
986 Raw('\xa5' * 100))
987 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
988
989 #
990 # Add the subnet routes
991 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700992 s41 = VppGbpSubnet(
993 self, rd0, "10.0.0.0", 24,
994 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
995 s42 = VppGbpSubnet(
996 self, rd0, "10.0.1.0", 24,
997 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
998 s43 = VppGbpSubnet(
999 self, rd0, "10.0.2.0", 24,
1000 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1001 s61 = VppGbpSubnet(
1002 self, rd0, "2001:10::1", 64,
1003 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1004 s62 = VppGbpSubnet(
1005 self, rd0, "2001:10:1::1", 64,
1006 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1007 s63 = VppGbpSubnet(
1008 self, rd0, "2001:10:2::1", 64,
1009 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001010 s41.add_vpp_config()
1011 s42.add_vpp_config()
1012 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001013 s61.add_vpp_config()
1014 s62.add_vpp_config()
1015 s63.add_vpp_config()
1016
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001017 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001018 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001019 eps[0].epg.uplink)
1020 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001021 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001022 eps[0].epg.uplink)
1023 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001024 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001025 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001026
1027 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1028 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1029 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1030 self.logger.info(self.vapi.cli("sh gbp recirc"))
1031 self.logger.info(self.vapi.cli("sh int"))
1032 self.logger.info(self.vapi.cli("sh int addr"))
1033 self.logger.info(self.vapi.cli("sh int feat loop6"))
1034 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1035 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001036 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001037
1038 #
1039 # Packet destined to unknown unicast is sent on the epg uplink ...
1040 #
1041 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1042 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001043 IP(src=eps[0].ip4.address,
1044 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001045 UDP(sport=1234, dport=1234) /
1046 Raw('\xa5' * 100))
1047
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001048 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001049 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001050 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001051 # ... and nowhere else
1052 self.pg1.get_capture(0, timeout=0.1)
1053 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1054
1055 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1056 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001057 IP(src=eps[0].ip4.address,
1058 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001059 UDP(sport=1234, dport=1234) /
1060 Raw('\xa5' * 100))
1061
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001062 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001063 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001064 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001065
1066 #
1067 # Packets from the uplink are forwarded in the absence of a contract
1068 #
1069 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1070 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001071 IP(src=eps[0].ip4.address,
1072 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001073 UDP(sport=1234, dport=1234) /
1074 Raw('\xa5' * 100))
1075
1076 self.send_and_expect_bridged(self.pg4,
1077 pkt_intra_epg_220_from_uplink * 65,
1078 self.pg0)
1079
1080 #
1081 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001082 # can communicate
1083 #
1084 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001085 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001086 IP(src=eps[0].ip4.address,
1087 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001088 UDP(sport=1234, dport=1234) /
1089 Raw('\xa5' * 100))
1090
Neale Ranns25b04942018-04-04 09:34:50 -07001091 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001092
1093 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001094 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001095 # cannot communicate
1096 #
1097 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001098 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001099 IP(src=eps[0].ip4.address,
1100 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001101 UDP(sport=1234, dport=1234) /
1102 Raw('\xa5' * 100))
1103 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001104 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001105 IP(src=eps[2].ip4.address,
1106 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001107 UDP(sport=1234, dport=1234) /
1108 Raw('\xa5' * 100))
1109 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001110 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001111 IP(src=eps[0].ip4.address,
1112 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001113 UDP(sport=1234, dport=1234) /
1114 Raw('\xa5' * 100))
1115
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001116 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001117 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001118 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001119 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001120
1121 #
1122 # A uni-directional contract from EPG 220 -> 221
1123 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001124 acl = VppGbpAcl(self)
1125 rule = acl.create_rule(permit_deny=1, proto=17)
1126 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1127 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001128 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001129 self, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001130 [VppGbpContractRule(
1131 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1132 []),
1133 VppGbpContractRule(
1134 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001135 [])],
1136 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001137 c1.add_vpp_config()
1138
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001139 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001140 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001141 eps[2].itf)
1142 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001143 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001144
1145 #
1146 # contract for the return direction
1147 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001148 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001149 self, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001150 [VppGbpContractRule(
1151 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1152 []),
1153 VppGbpContractRule(
1154 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001155 [])],
1156 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001157 c2.add_vpp_config()
1158
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001159 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001160 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001161 eps[2].itf)
1162 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001163 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001164 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001165
Neale Ranns796c84b2019-03-28 07:56:23 -07001166 ds = c2.get_drop_stats()
1167 self.assertEqual(ds['packets'], 0)
1168 ps = c2.get_permit_stats()
1169 self.assertEqual(ps['packets'], 65)
1170
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001171 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001172 # the contract does not allow non-IP
1173 #
1174 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1175 dst=self.pg2.remote_mac) /
1176 ARP())
1177 self.send_and_assert_no_replies(eps[0].itf,
1178 pkt_non_ip_inter_epg_220_to_221 * 17)
1179
1180 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001181 # check that inter group is still disabled for the groups
1182 # not in the contract.
1183 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001184 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001185 pkt_inter_epg_220_to_222 * 65)
1186
Neale Ranns25b04942018-04-04 09:34:50 -07001187 #
1188 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1189 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001190 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001191 self, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001192 [VppGbpContractRule(
1193 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1194 []),
1195 VppGbpContractRule(
1196 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001197 [])],
1198 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001199 c3.add_vpp_config()
1200
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001201 self.logger.info(self.vapi.cli("sh gbp contract"))
1202
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001203 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001204 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001205 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001206 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001207
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001208 #
1209 # remove both contracts, traffic stops in both directions
1210 #
1211 c2.remove_vpp_config()
1212 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001213 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001214 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001215
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001216 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001217 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001218 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001219 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001220 self.send_and_expect_bridged(eps[0].itf,
1221 pkt_intra_epg * 65,
1222 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001223
1224 #
Neale Ranns25b04942018-04-04 09:34:50 -07001225 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001226 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001227
Neale Ranns25b04942018-04-04 09:34:50 -07001228 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001229 se1 = VppGbpSubnet(
1230 self, rd0, "0.0.0.0", 0,
1231 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1232 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001233 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001234 se2 = VppGbpSubnet(
1235 self, rd0, "11.0.0.0", 8,
1236 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1237 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001238 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001239 se16 = VppGbpSubnet(
1240 self, rd0, "::", 0,
1241 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1242 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001243 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001244 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001245 se3 = VppGbpSubnet(
1246 self, rd20, "0.0.0.0", 0,
1247 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1248 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001249 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001250 se36 = VppGbpSubnet(
1251 self, rd20, "::", 0,
1252 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1253 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001254 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001255 se4 = VppGbpSubnet(
1256 self, rd20, "11.0.0.0", 8,
1257 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1258 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001259 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001260 se1.add_vpp_config()
1261 se2.add_vpp_config()
1262 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001263 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001264 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001265 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001266
Neale Ranns25b04942018-04-04 09:34:50 -07001267 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1268 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001269 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1270 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001271 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001272
Neale Ranns4a6d0232018-04-24 07:45:33 -07001273 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001274 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001275 #
Neale Ranns25b04942018-04-04 09:34:50 -07001276 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001277 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001278 IP(src=eps[0].ip4.address,
1279 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001280 UDP(sport=1234, dport=1234) /
1281 Raw('\xa5' * 100))
1282
1283 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001284 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001285 pkt_inter_epg_220_to_global * 65)
1286
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001287 acl2 = VppGbpAcl(self)
1288 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1289 sport_to=1234, dport_from=1234, dport_to=1234)
1290 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1291 sport_from=1234, sport_to=1234,
1292 dport_from=1234, dport_to=1234)
1293
1294 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001295 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001296 self, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001297 [VppGbpContractRule(
1298 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1299 []),
1300 VppGbpContractRule(
1301 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001302 [])],
1303 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001304 c4.add_vpp_config()
1305
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001306 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001307 pkt_inter_epg_220_to_global * 65,
1308 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001309 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001310
Neale Ranns4a6d0232018-04-24 07:45:33 -07001311 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001312 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001313 IPv6(src=eps[0].ip6.address,
1314 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001315 UDP(sport=1234, dport=1234) /
1316 Raw('\xa5' * 100))
1317
1318 self.send_and_expect_natted6(self.pg0,
1319 pkt_inter_epg_220_to_global * 65,
1320 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001321 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001322
1323 #
1324 # From a global address to an EP: OUT2IN
1325 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001326 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001327 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001328 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001329 src="1.1.1.1") /
1330 UDP(sport=1234, dport=1234) /
1331 Raw('\xa5' * 100))
1332
1333 self.send_and_assert_no_replies(self.pg7,
1334 pkt_inter_epg_220_from_global * 65)
1335
Neale Ranns13a08cc2018-11-07 09:25:54 -08001336 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001337 self, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001338 [VppGbpContractRule(
1339 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1340 []),
1341 VppGbpContractRule(
1342 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001343 [])],
1344 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001345 c5.add_vpp_config()
1346
1347 self.send_and_expect_unnatted(self.pg7,
1348 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001349 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001350 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001351
Ole Troan8006c6a2018-12-17 12:02:26 +01001352 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001353 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001354 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001355 src="6001::1") /
1356 UDP(sport=1234, dport=1234) /
1357 Raw('\xa5' * 100))
1358
1359 self.send_and_expect_unnatted6(self.pg7,
1360 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001361 eps[0].itf,
1362 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001363
1364 #
1365 # From a local VM to another local VM using resp. public addresses:
1366 # IN2OUT2IN
1367 #
Neale Ranns25b04942018-04-04 09:34:50 -07001368 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001369 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001370 IP(src=eps[0].ip4.address,
1371 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001372 UDP(sport=1234, dport=1234) /
1373 Raw('\xa5' * 100))
1374
Neale Ranns4a6d0232018-04-24 07:45:33 -07001375 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001376 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001377 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001378 eps[0].fip4.address,
1379 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001380
Neale Rannsc0a93142018-09-05 15:42:26 -07001381 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001382 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001383 IPv6(src=eps[0].ip6.address,
1384 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001385 UDP(sport=1234, dport=1234) /
1386 Raw('\xa5' * 100))
1387
Neale Rannsc0a93142018-09-05 15:42:26 -07001388 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001389 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001390 eps[1].itf,
1391 eps[0].fip6.address,
1392 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001393
1394 #
Neale Ranns25b04942018-04-04 09:34:50 -07001395 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001396 #
Neale Ranns25b04942018-04-04 09:34:50 -07001397 for ep in eps:
1398 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001399 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1400 ep.fip4.bytes,
1401 vrf_id=0,
1402 addr_only=1,
1403 is_add=0)
1404 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1405 ep.fip6.bytes,
1406 vrf_id=0,
1407 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001408
Neale Ranns25b04942018-04-04 09:34:50 -07001409 for epg in epgs:
1410 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001411 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001412 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1413 is_inside=1,
1414 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001415 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1416 is_inside=1,
1417 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001418
Neale Ranns25b04942018-04-04 09:34:50 -07001419 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001420 self.vapi.nat44_interface_add_del_feature(
1421 recirc.recirc.sw_if_index,
1422 is_inside=0,
1423 is_add=0)
1424 self.vapi.nat66_add_del_interface(
1425 recirc.recirc.sw_if_index,
1426 is_inside=0,
1427 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001428
Neale Ranns774356a2018-11-29 12:02:16 +00001429 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1430 n_tries=100, s_time=1):
1431 while (n_tries):
1432 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1433 return True
1434 n_tries = n_tries - 1
1435 self.sleep(s_time)
1436 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1437 return False
1438
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001439 def test_gbp_learn_l2(self):
1440 """ GBP L2 Endpoint Learning """
1441
Neale Ranns796c84b2019-03-28 07:56:23 -07001442 self.vapi.cli("clear errors")
1443
Neale Rannsb6a47952018-11-21 05:44:35 -08001444 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001445 learnt = [{'mac': '00:00:11:11:11:01',
1446 'ip': '10.0.0.1',
1447 'ip6': '2001:10::2'},
1448 {'mac': '00:00:11:11:11:02',
1449 'ip': '10.0.0.2',
1450 'ip6': '2001:10::3'}]
1451
1452 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001453 # IP tables
1454 #
1455 gt4 = VppIpTable(self, 1)
1456 gt4.add_vpp_config()
1457 gt6 = VppIpTable(self, 1, is_ip6=True)
1458 gt6.add_vpp_config()
1459
1460 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1461 rd1.add_vpp_config()
1462
1463 #
1464 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1465 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1466 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1467 #
1468 self.pg2.config_ip4()
1469 self.pg2.resolve_arp()
1470 self.pg2.generate_remote_hosts(4)
1471 self.pg2.configure_ipv4_neighbors()
1472 self.pg3.config_ip4()
1473 self.pg3.resolve_arp()
1474 self.pg4.config_ip4()
1475 self.pg4.resolve_arp()
1476
1477 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001478 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1479 #
1480 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1481 "239.1.1.1", 88,
1482 mcast_itf=self.pg4)
1483 tun_bm.add_vpp_config()
1484
1485 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001486 # a GBP bridge domain with a BVI and a UU-flood interface
1487 #
1488 bd1 = VppBridgeDomain(self, 1)
1489 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001490 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001491 gbd1.add_vpp_config()
1492
1493 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1494 self.logger.info(self.vapi.cli("sh gbp bridge"))
1495
1496 # ... and has a /32 applied
1497 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1498 ip_addr.add_vpp_config()
1499
1500 #
1501 # The Endpoint-group in which we are learning endpoints
1502 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001503 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001504 None, self.loop0,
1505 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001506 "2001:10::128",
1507 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001508 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001509 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001510 None, self.loop1,
1511 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001512 "2001:11::128",
1513 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001514 epg_330.add_vpp_config()
1515
1516 #
1517 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001518 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001519 #
1520 vx_tun_l2_1 = VppGbpVxlanTunnel(
1521 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001522 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1523 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001524 vx_tun_l2_1.add_vpp_config()
1525
1526 #
1527 # A static endpoint that the learnt endpoints are trying to
1528 # talk to
1529 #
1530 ep = VppGbpEndpoint(self, self.pg0,
1531 epg_220, None,
1532 "10.0.0.127", "11.0.0.127",
1533 "2001:10::1", "3001::1")
1534 ep.add_vpp_config()
1535
1536 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1537
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001538 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001539 p = (Ether(src=self.pg2.remote_mac,
1540 dst=self.pg2.local_mac) /
1541 IP(src=self.pg2.remote_hosts[0].ip4,
1542 dst=self.pg2.local_ip4) /
1543 UDP(sport=1234, dport=48879) /
1544 VXLAN(vni=99, gpid=88, flags=0x88) /
1545 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1546 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1547 UDP(sport=1234, dport=1234) /
1548 Raw('\xa5' * 100))
1549
1550 self.send_and_assert_no_replies(self.pg2, p)
1551
Neale Ranns796c84b2019-03-28 07:56:23 -07001552 self.logger.info(self.vapi.cli("sh error"))
1553 # self.assert_packet_counter_equal(
1554 # '/err/gbp-policy-port/drop-no-contract', 1)
1555
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001556 #
1557 # we should not have learnt a new tunnel endpoint, since
1558 # the EPG was not learnt.
1559 #
1560 self.assertEqual(INDEX_INVALID,
1561 find_vxlan_gbp_tunnel(self,
1562 self.pg2.local_ip4,
1563 self.pg2.remote_hosts[0].ip4,
1564 99))
1565
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001566 # epg is not learnt, because the EPG is unknwon
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001567 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1568
Neale Ranns8da9fc62019-03-04 14:08:11 -08001569 #
1570 # Learn new EPs from IP packets
1571 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001572 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001573 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001574 # arriving on an unknown TEP
1575 p = (Ether(src=self.pg2.remote_mac,
1576 dst=self.pg2.local_mac) /
1577 IP(src=self.pg2.remote_hosts[1].ip4,
1578 dst=self.pg2.local_ip4) /
1579 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001580 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001581 Ether(src=l['mac'], dst=ep.mac) /
1582 IP(src=l['ip'], dst=ep.ip4.address) /
1583 UDP(sport=1234, dport=1234) /
1584 Raw('\xa5' * 100))
1585
1586 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1587
1588 # the new TEP
1589 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1590 self,
1591 self.pg2.local_ip4,
1592 self.pg2.remote_hosts[1].ip4,
1593 99)
1594 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1595
1596 #
1597 # the EP is learnt via the learnt TEP
1598 # both from its MAC and its IP
1599 #
1600 self.assertTrue(find_gbp_endpoint(self,
1601 vx_tun_l2_1.sw_if_index,
1602 mac=l['mac']))
1603 self.assertTrue(find_gbp_endpoint(self,
1604 vx_tun_l2_1.sw_if_index,
1605 ip=l['ip']))
1606
Neale Ranns796c84b2019-03-28 07:56:23 -07001607 # self.assert_packet_counter_equal(
1608 # '/err/gbp-policy-port/allow-intra-sclass', 2)
1609
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001610 self.logger.info(self.vapi.cli("show gbp endpoint"))
1611 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001612 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001613
1614 #
1615 # If we sleep for the threshold time, the learnt endpoints should
1616 # age out
1617 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001618 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001619 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1620 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001621
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001622 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001623 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1624 #
1625 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001626 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001627 # arriving on an unknown TEP
1628 p = (Ether(src=self.pg2.remote_mac,
1629 dst=self.pg2.local_mac) /
1630 IP(src=self.pg2.remote_hosts[1].ip4,
1631 dst="239.1.1.1") /
1632 UDP(sport=1234, dport=48879) /
1633 VXLAN(vni=88, gpid=112, flags=0x88) /
1634 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1635 ARP(op="who-has",
1636 psrc=l['ip'], pdst=l['ip'],
1637 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1638
1639 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1640
1641 # the new TEP
1642 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1643 self,
1644 self.pg2.local_ip4,
1645 self.pg2.remote_hosts[1].ip4,
1646 99)
1647 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1648
1649 #
1650 # the EP is learnt via the learnt TEP
1651 # both from its MAC and its IP
1652 #
1653 self.assertTrue(find_gbp_endpoint(self,
1654 vx_tun_l2_1.sw_if_index,
1655 mac=l['mac']))
1656 self.assertTrue(find_gbp_endpoint(self,
1657 vx_tun_l2_1.sw_if_index,
1658 ip=l['ip']))
1659
1660 #
1661 # wait for the learnt endpoints to age out
1662 #
1663 for l in learnt:
1664 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1665 mac=l['mac'])
1666
1667 #
1668 # Learn new EPs from L2 packets
1669 #
1670 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001671 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001672 # arriving on an unknown TEP
1673 p = (Ether(src=self.pg2.remote_mac,
1674 dst=self.pg2.local_mac) /
1675 IP(src=self.pg2.remote_hosts[1].ip4,
1676 dst=self.pg2.local_ip4) /
1677 UDP(sport=1234, dport=48879) /
1678 VXLAN(vni=99, gpid=112, flags=0x88) /
1679 Ether(src=l['mac'], dst=ep.mac) /
1680 Raw('\xa5' * 100))
1681
1682 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1683
1684 # the new TEP
1685 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1686 self,
1687 self.pg2.local_ip4,
1688 self.pg2.remote_hosts[1].ip4,
1689 99)
1690 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1691
1692 #
1693 # the EP is learnt via the learnt TEP
1694 # both from its MAC and its IP
1695 #
1696 self.assertTrue(find_gbp_endpoint(self,
1697 vx_tun_l2_1.sw_if_index,
1698 mac=l['mac']))
1699
1700 self.logger.info(self.vapi.cli("show gbp endpoint"))
1701 self.logger.info(self.vapi.cli("show gbp vxlan"))
1702 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1703
1704 #
1705 # wait for the learnt endpoints to age out
1706 #
1707 for l in learnt:
1708 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1709 mac=l['mac'])
1710
1711 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001712 # repeat. the do not learn bit is set so the EPs are not learnt
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, gpflags="D") /
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 for l in learnt:
1730 self.assertFalse(find_gbp_endpoint(self,
1731 vx_tun_l2_1.sw_if_index,
1732 mac=l['mac']))
1733
1734 #
1735 # repeat
1736 #
1737 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001738 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001739 p = (Ether(src=self.pg2.remote_mac,
1740 dst=self.pg2.local_mac) /
1741 IP(src=self.pg2.remote_hosts[1].ip4,
1742 dst=self.pg2.local_ip4) /
1743 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001744 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001745 Ether(src=l['mac'], dst=ep.mac) /
1746 IP(src=l['ip'], dst=ep.ip4.address) /
1747 UDP(sport=1234, dport=1234) /
1748 Raw('\xa5' * 100))
1749
1750 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1751
1752 self.assertTrue(find_gbp_endpoint(self,
1753 vx_tun_l2_1.sw_if_index,
1754 mac=l['mac']))
1755
1756 #
1757 # Static EP replies to dynamics
1758 #
1759 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1760 for l in learnt:
1761 p = (Ether(src=ep.mac, dst=l['mac']) /
1762 IP(dst=l['ip'], src=ep.ip4.address) /
1763 UDP(sport=1234, dport=1234) /
1764 Raw('\xa5' * 100))
1765
1766 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1767
1768 for rx in rxs:
1769 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1770 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1771 self.assertEqual(rx[UDP].dport, 48879)
1772 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001773 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001774 self.assertEqual(rx[VXLAN].vni, 99)
1775 self.assertTrue(rx[VXLAN].flags.G)
1776 self.assertTrue(rx[VXLAN].flags.Instance)
1777 self.assertTrue(rx[VXLAN].gpflags.A)
1778 self.assertFalse(rx[VXLAN].gpflags.D)
1779
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001780 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001781 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1782 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001783
1784 #
1785 # repeat in the other EPG
1786 # there's no contract between 220 and 330, but the A-bit is set
1787 # so the packet is cleared for delivery
1788 #
1789 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001790 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001791 p = (Ether(src=self.pg2.remote_mac,
1792 dst=self.pg2.local_mac) /
1793 IP(src=self.pg2.remote_hosts[1].ip4,
1794 dst=self.pg2.local_ip4) /
1795 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001796 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001797 Ether(src=l['mac'], dst=ep.mac) /
1798 IP(src=l['ip'], dst=ep.ip4.address) /
1799 UDP(sport=1234, dport=1234) /
1800 Raw('\xa5' * 100))
1801
1802 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1803
1804 self.assertTrue(find_gbp_endpoint(self,
1805 vx_tun_l2_1.sw_if_index,
1806 mac=l['mac']))
1807
1808 #
1809 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001810 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001811 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001812 p = (Ether(src=ep.mac, dst=l['mac']) /
1813 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1814 UDP(sport=1234, dport=1234) /
1815 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001816
Neale Ranns13a08cc2018-11-07 09:25:54 -08001817 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001818
1819 #
1820 # refresh the entries after the check for no replies above
1821 #
1822 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001823 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001824 p = (Ether(src=self.pg2.remote_mac,
1825 dst=self.pg2.local_mac) /
1826 IP(src=self.pg2.remote_hosts[1].ip4,
1827 dst=self.pg2.local_ip4) /
1828 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001829 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001830 Ether(src=l['mac'], dst=ep.mac) /
1831 IP(src=l['ip'], dst=ep.ip4.address) /
1832 UDP(sport=1234, dport=1234) /
1833 Raw('\xa5' * 100))
1834
1835 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1836
1837 self.assertTrue(find_gbp_endpoint(self,
1838 vx_tun_l2_1.sw_if_index,
1839 mac=l['mac']))
1840
1841 #
1842 # Add the contract so they can talk
1843 #
1844 acl = VppGbpAcl(self)
1845 rule = acl.create_rule(permit_deny=1, proto=17)
1846 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1847 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001848 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001849 self, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001850 [VppGbpContractRule(
1851 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1852 []),
1853 VppGbpContractRule(
1854 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001855 [])],
1856 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001857 c1.add_vpp_config()
1858
1859 for l in learnt:
1860 p = (Ether(src=ep.mac, dst=l['mac']) /
1861 IP(dst=l['ip'], src=ep.ip4.address) /
1862 UDP(sport=1234, dport=1234) /
1863 Raw('\xa5' * 100))
1864
1865 self.send_and_expect(self.pg0, [p], self.pg2)
1866
1867 #
1868 # send UU packets from the local EP
1869 #
1870 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1871 self.logger.info(self.vapi.cli("sh gbp bridge"))
1872 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1873 IP(dst="10.0.0.133", src=ep.ip4.address) /
1874 UDP(sport=1234, dport=1234) /
1875 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001876 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001877
1878 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1879
1880 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1881 IP(dst="10.0.0.133", src=ep.ip4.address) /
1882 UDP(sport=1234, dport=1234) /
1883 Raw('\xa5' * 100))
1884 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1885
Neale Ranns879d11c2019-01-21 23:34:18 -08001886 for rx in rxs:
1887 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1888 self.assertEqual(rx[IP].dst, "239.1.1.1")
1889 self.assertEqual(rx[UDP].dport, 48879)
1890 # the UDP source port is a random value for hashing
1891 self.assertEqual(rx[VXLAN].gpid, 112)
1892 self.assertEqual(rx[VXLAN].vni, 88)
1893 self.assertTrue(rx[VXLAN].flags.G)
1894 self.assertTrue(rx[VXLAN].flags.Instance)
1895 self.assertFalse(rx[VXLAN].gpflags.A)
1896 self.assertFalse(rx[VXLAN].gpflags.D)
1897
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001898 #
1899 # Check v6 Endpoints
1900 #
1901 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001902 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001903 p = (Ether(src=self.pg2.remote_mac,
1904 dst=self.pg2.local_mac) /
1905 IP(src=self.pg2.remote_hosts[1].ip4,
1906 dst=self.pg2.local_ip4) /
1907 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001908 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001909 Ether(src=l['mac'], dst=ep.mac) /
1910 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1911 UDP(sport=1234, dport=1234) /
1912 Raw('\xa5' * 100))
1913
1914 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1915
1916 self.assertTrue(find_gbp_endpoint(self,
1917 vx_tun_l2_1.sw_if_index,
1918 mac=l['mac']))
1919
1920 #
1921 # L3 Endpoint Learning
1922 # - configured on the bridge's BVI
1923 #
1924
1925 #
1926 # clean up
1927 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001928 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001929 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1930 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001931 self.pg2.unconfig_ip4()
1932 self.pg3.unconfig_ip4()
1933 self.pg4.unconfig_ip4()
1934
1935 self.logger.info(self.vapi.cli("sh int"))
1936 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1937
Mohsin Kazmi7363d472019-04-04 13:22:15 +02001938 def test_gbp_bd_flags(self):
1939 """ GBP BD FLAGS """
1940
1941 #
1942 # IP tables
1943 #
1944 gt4 = VppIpTable(self, 1)
1945 gt4.add_vpp_config()
1946 gt6 = VppIpTable(self, 1, is_ip6=True)
1947 gt6.add_vpp_config()
1948
1949 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1950 rd1.add_vpp_config()
1951
1952 #
1953 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1954 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1955 #
1956 self.pg3.config_ip4()
1957 self.pg3.resolve_arp()
1958 self.pg4.config_ip4()
1959 self.pg4.resolve_arp()
1960
1961 #
1962 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1963 #
1964 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1965 "239.1.1.1", 88,
1966 mcast_itf=self.pg4)
1967 tun_bm.add_vpp_config()
1968
1969 #
1970 # a GBP bridge domain with a BVI and a UU-flood interface
1971 #
1972 bd1 = VppBridgeDomain(self, 1)
1973 bd1.add_vpp_config()
1974
1975 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm,
1976 uu_drop=True, bm_drop=True)
1977 gbd1.add_vpp_config()
1978
1979 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1980 self.logger.info(self.vapi.cli("sh gbp bridge"))
1981
1982 # ... and has a /32 applied
1983 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1984 ip_addr.add_vpp_config()
1985
1986 #
1987 # The Endpoint-group
1988 #
1989 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
1990 None, self.loop0,
1991 "10.0.0.128",
1992 "2001:10::128",
1993 VppGbpEndpointRetention(2))
1994 epg_220.add_vpp_config()
1995
1996 ep = VppGbpEndpoint(self, self.pg0,
1997 epg_220, None,
1998 "10.0.0.127", "11.0.0.127",
1999 "2001:10::1", "3001::1")
2000 ep.add_vpp_config()
2001 #
2002 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2003 # in bd
2004 #
2005 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2006 self.logger.info(self.vapi.cli("sh gbp bridge"))
2007 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
2008 IP(dst="10.0.0.133", src=ep.ip4.address) /
2009 UDP(sport=1234, dport=1234) /
2010 Raw('\xa5' * 100))
2011 self.send_and_assert_no_replies(ep.itf, [p_uu])
2012
2013 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2014 IP(dst="10.0.0.133", src=ep.ip4.address) /
2015 UDP(sport=1234, dport=1234) /
2016 Raw('\xa5' * 100))
2017 self.send_and_assert_no_replies(ep.itf, [p_bm])
2018
2019 self.pg3.unconfig_ip4()
2020 self.pg4.unconfig_ip4()
2021
2022 self.logger.info(self.vapi.cli("sh int"))
2023
Neale Rannsc29c0af2018-11-07 04:21:12 -08002024 def test_gbp_learn_vlan_l2(self):
2025 """ GBP L2 Endpoint w/ VLANs"""
2026
Neale Rannsb6a47952018-11-21 05:44:35 -08002027 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002028 learnt = [{'mac': '00:00:11:11:11:01',
2029 'ip': '10.0.0.1',
2030 'ip6': '2001:10::2'},
2031 {'mac': '00:00:11:11:11:02',
2032 'ip': '10.0.0.2',
2033 'ip6': '2001:10::3'}]
2034
2035 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002036 # IP tables
2037 #
2038 gt4 = VppIpTable(self, 1)
2039 gt4.add_vpp_config()
2040 gt6 = VppIpTable(self, 1, is_ip6=True)
2041 gt6.add_vpp_config()
2042
2043 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
2044 rd1.add_vpp_config()
2045
2046 #
2047 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2048 #
2049 self.pg2.config_ip4()
2050 self.pg2.resolve_arp()
2051 self.pg2.generate_remote_hosts(4)
2052 self.pg2.configure_ipv4_neighbors()
2053 self.pg3.config_ip4()
2054 self.pg3.resolve_arp()
2055
2056 #
2057 # The EP will be on a vlan sub-interface
2058 #
2059 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2060 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002061 self.vapi.l2_interface_vlan_tag_rewrite(
2062 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2063 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002064
2065 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2066 self.pg3.remote_ip4, 116)
2067 bd_uu_fwd.add_vpp_config()
2068
2069 #
2070 # a GBP bridge domain with a BVI and a UU-flood interface
2071 # The BD is marked as do not learn, so no endpoints are ever
2072 # learnt in this BD.
2073 #
2074 bd1 = VppBridgeDomain(self, 1)
2075 bd1.add_vpp_config()
2076 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
2077 learn=False)
2078 gbd1.add_vpp_config()
2079
2080 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2081 self.logger.info(self.vapi.cli("sh gbp bridge"))
2082
2083 # ... and has a /32 applied
2084 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2085 ip_addr.add_vpp_config()
2086
2087 #
2088 # The Endpoint-group in which we are learning endpoints
2089 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002090 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002091 None, self.loop0,
2092 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002093 "2001:10::128",
2094 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002095 epg_220.add_vpp_config()
2096
2097 #
2098 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002099 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002100 #
2101 vx_tun_l2_1 = VppGbpVxlanTunnel(
2102 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002103 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2104 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002105 vx_tun_l2_1.add_vpp_config()
2106
2107 #
2108 # A static endpoint that the learnt endpoints are trying to
2109 # talk to
2110 #
2111 ep = VppGbpEndpoint(self, vlan_11,
2112 epg_220, None,
2113 "10.0.0.127", "11.0.0.127",
2114 "2001:10::1", "3001::1")
2115 ep.add_vpp_config()
2116
2117 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2118
2119 #
2120 # Send to the static EP
2121 #
2122 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002123 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002124 # arriving on an unknown TEP
2125 p = (Ether(src=self.pg2.remote_mac,
2126 dst=self.pg2.local_mac) /
2127 IP(src=self.pg2.remote_hosts[1].ip4,
2128 dst=self.pg2.local_ip4) /
2129 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002130 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002131 Ether(src=l['mac'], dst=ep.mac) /
2132 IP(src=l['ip'], dst=ep.ip4.address) /
2133 UDP(sport=1234, dport=1234) /
2134 Raw('\xa5' * 100))
2135
2136 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2137
2138 #
2139 # packet to EP has the EP's vlan tag
2140 #
2141 for rx in rxs:
2142 self.assertEqual(rx[Dot1Q].vlan, 11)
2143
2144 #
2145 # the EP is not learnt since the BD setting prevents it
2146 # also no TEP too
2147 #
2148 self.assertFalse(find_gbp_endpoint(self,
2149 vx_tun_l2_1.sw_if_index,
2150 mac=l['mac']))
2151 self.assertEqual(INDEX_INVALID,
2152 find_vxlan_gbp_tunnel(
2153 self,
2154 self.pg2.local_ip4,
2155 self.pg2.remote_hosts[1].ip4,
2156 99))
2157
2158 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2159
2160 #
2161 # static to remotes
2162 # we didn't learn the remotes so they are sent to the UU-fwd
2163 #
2164 for l in learnt:
2165 p = (Ether(src=ep.mac, dst=l['mac']) /
2166 Dot1Q(vlan=11) /
2167 IP(dst=l['ip'], src=ep.ip4.address) /
2168 UDP(sport=1234, dport=1234) /
2169 Raw('\xa5' * 100))
2170
2171 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2172
2173 for rx in rxs:
2174 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2175 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2176 self.assertEqual(rx[UDP].dport, 48879)
2177 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002178 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002179 self.assertEqual(rx[VXLAN].vni, 116)
2180 self.assertTrue(rx[VXLAN].flags.G)
2181 self.assertTrue(rx[VXLAN].flags.Instance)
2182 self.assertFalse(rx[VXLAN].gpflags.A)
2183 self.assertFalse(rx[VXLAN].gpflags.D)
2184
2185 self.pg2.unconfig_ip4()
2186 self.pg3.unconfig_ip4()
2187
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002188 def test_gbp_learn_l3(self):
2189 """ GBP L3 Endpoint Learning """
2190
Neale Ranns13a08cc2018-11-07 09:25:54 -08002191 self.vapi.cli("set logging class gbp debug")
2192
Neale Rannsb6a47952018-11-21 05:44:35 -08002193 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002194 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2195 routed_src_mac = "00:22:bd:f8:19:ff"
2196
2197 learnt = [{'mac': '00:00:11:11:11:02',
2198 'ip': '10.0.1.2',
2199 'ip6': '2001:10::2'},
2200 {'mac': '00:00:11:11:11:03',
2201 'ip': '10.0.1.3',
2202 'ip6': '2001:10::3'}]
2203
2204 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002205 # IP tables
2206 #
2207 t4 = VppIpTable(self, 1)
2208 t4.add_vpp_config()
2209 t6 = VppIpTable(self, 1, True)
2210 t6.add_vpp_config()
2211
2212 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2213 self.pg4.remote_ip4, 114)
2214 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2215 self.pg4.remote_ip4, 116)
2216 tun_ip4_uu.add_vpp_config()
2217 tun_ip6_uu.add_vpp_config()
2218
2219 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2220 rd1.add_vpp_config()
2221
Ole Troan8006c6a2018-12-17 12:02:26 +01002222 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002223
2224 #
2225 # Bind the BVI to the RD
2226 #
2227 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2228 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2229
2230 #
2231 # Pg2 hosts the vxlan tunnel
2232 # hosts on pg2 to act as TEPs
2233 # pg3 is BD uu-fwd
2234 # pg4 is RD uu-fwd
2235 #
2236 self.pg2.config_ip4()
2237 self.pg2.resolve_arp()
2238 self.pg2.generate_remote_hosts(4)
2239 self.pg2.configure_ipv4_neighbors()
2240 self.pg3.config_ip4()
2241 self.pg3.resolve_arp()
2242 self.pg4.config_ip4()
2243 self.pg4.resolve_arp()
2244
2245 #
2246 # a GBP bridge domain with a BVI and a UU-flood interface
2247 #
2248 bd1 = VppBridgeDomain(self, 1)
2249 bd1.add_vpp_config()
2250 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2251 gbd1.add_vpp_config()
2252
2253 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2254 self.logger.info(self.vapi.cli("sh gbp bridge"))
2255 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002256
2257 # ... and has a /32 and /128 applied
2258 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2259 ip4_addr.add_vpp_config()
2260 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2261 ip6_addr.add_vpp_config()
2262
2263 #
2264 # The Endpoint-group in which we are learning endpoints
2265 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002266 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002267 None, self.loop0,
2268 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002269 "2001:10::128",
2270 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002271 epg_220.add_vpp_config()
2272
2273 #
2274 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002275 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002276 #
2277 vx_tun_l3 = VppGbpVxlanTunnel(
2278 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002279 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2280 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002281 vx_tun_l3.add_vpp_config()
2282
2283 #
2284 # A static endpoint that the learnt endpoints are trying to
2285 # talk to
2286 #
2287 ep = VppGbpEndpoint(self, self.pg0,
2288 epg_220, None,
2289 "10.0.0.127", "11.0.0.127",
2290 "2001:10::1", "3001::1")
2291 ep.add_vpp_config()
2292
2293 #
2294 # learn some remote IPv4 EPs
2295 #
2296 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002297 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002298 # arriving on an unknown TEP
2299 p = (Ether(src=self.pg2.remote_mac,
2300 dst=self.pg2.local_mac) /
2301 IP(src=self.pg2.remote_hosts[1].ip4,
2302 dst=self.pg2.local_ip4) /
2303 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002304 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002305 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2306 IP(src=l['ip'], dst=ep.ip4.address) /
2307 UDP(sport=1234, dport=1234) /
2308 Raw('\xa5' * 100))
2309
2310 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2311
2312 # the new TEP
2313 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2314 self,
2315 self.pg2.local_ip4,
2316 self.pg2.remote_hosts[1].ip4,
2317 vx_tun_l3.vni)
2318 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2319
2320 # endpoint learnt via the parent GBP-vxlan interface
2321 self.assertTrue(find_gbp_endpoint(self,
2322 vx_tun_l3._sw_if_index,
2323 ip=l['ip']))
2324
2325 #
2326 # Static IPv4 EP replies to learnt
2327 #
2328 for l in learnt:
2329 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2330 IP(dst=l['ip'], src=ep.ip4.address) /
2331 UDP(sport=1234, dport=1234) /
2332 Raw('\xa5' * 100))
2333
2334 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2335
2336 for rx in rxs:
2337 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2338 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2339 self.assertEqual(rx[UDP].dport, 48879)
2340 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002341 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002342 self.assertEqual(rx[VXLAN].vni, 101)
2343 self.assertTrue(rx[VXLAN].flags.G)
2344 self.assertTrue(rx[VXLAN].flags.Instance)
2345 self.assertTrue(rx[VXLAN].gpflags.A)
2346 self.assertFalse(rx[VXLAN].gpflags.D)
2347
2348 inner = rx[VXLAN].payload
2349
2350 self.assertEqual(inner[Ether].src, routed_src_mac)
2351 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2352 self.assertEqual(inner[IP].src, ep.ip4.address)
2353 self.assertEqual(inner[IP].dst, l['ip'])
2354
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002355 for l in learnt:
2356 self.assertFalse(find_gbp_endpoint(self,
2357 tep1_sw_if_index,
2358 ip=l['ip']))
2359
2360 #
2361 # learn some remote IPv6 EPs
2362 #
2363 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002364 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002365 # arriving on an unknown TEP
2366 p = (Ether(src=self.pg2.remote_mac,
2367 dst=self.pg2.local_mac) /
2368 IP(src=self.pg2.remote_hosts[1].ip4,
2369 dst=self.pg2.local_ip4) /
2370 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002371 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002372 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2373 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2374 UDP(sport=1234, dport=1234) /
2375 Raw('\xa5' * 100))
2376
2377 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2378
2379 # the new TEP
2380 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2381 self,
2382 self.pg2.local_ip4,
2383 self.pg2.remote_hosts[1].ip4,
2384 vx_tun_l3.vni)
2385 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2386
2387 self.logger.info(self.vapi.cli("show gbp bridge"))
2388 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2389 self.logger.info(self.vapi.cli("show gbp vxlan"))
2390 self.logger.info(self.vapi.cli("show int addr"))
2391
2392 # endpoint learnt via the TEP
2393 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2394
2395 self.logger.info(self.vapi.cli("show gbp endpoint"))
2396 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2397
2398 #
2399 # Static EP replies to learnt
2400 #
2401 for l in learnt:
2402 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2403 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2404 UDP(sport=1234, dport=1234) /
2405 Raw('\xa5' * 100))
2406
2407 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2408
2409 for rx in rxs:
2410 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2411 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2412 self.assertEqual(rx[UDP].dport, 48879)
2413 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002414 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002415 self.assertEqual(rx[VXLAN].vni, 101)
2416 self.assertTrue(rx[VXLAN].flags.G)
2417 self.assertTrue(rx[VXLAN].flags.Instance)
2418 self.assertTrue(rx[VXLAN].gpflags.A)
2419 self.assertFalse(rx[VXLAN].gpflags.D)
2420
2421 inner = rx[VXLAN].payload
2422
2423 self.assertEqual(inner[Ether].src, routed_src_mac)
2424 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2425 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2426 self.assertEqual(inner[IPv6].dst, l['ip6'])
2427
2428 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002429 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002430 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002431
2432 #
2433 # Static sends to unknown EP with no route
2434 #
2435 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2436 IP(dst="10.0.0.99", src=ep.ip4.address) /
2437 UDP(sport=1234, dport=1234) /
2438 Raw('\xa5' * 100))
2439
2440 self.send_and_assert_no_replies(self.pg0, [p])
2441
2442 #
2443 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002444 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002445 #
2446 se_10_24 = VppGbpSubnet(
2447 self, rd1, "10.0.0.0", 24,
2448 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2449 se_10_24.add_vpp_config()
2450
2451 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2452 IP(dst="10.0.0.99", src=ep.ip4.address) /
2453 UDP(sport=1234, dport=1234) /
2454 Raw('\xa5' * 100))
2455
2456 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2457 for rx in rxs:
2458 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2459 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2460 self.assertEqual(rx[UDP].dport, 48879)
2461 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002462 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002463 self.assertEqual(rx[VXLAN].vni, 114)
2464 self.assertTrue(rx[VXLAN].flags.G)
2465 self.assertTrue(rx[VXLAN].flags.Instance)
2466 # policy is not applied to packets sent to the uu-fwd interfaces
2467 self.assertFalse(rx[VXLAN].gpflags.A)
2468 self.assertFalse(rx[VXLAN].gpflags.D)
2469
2470 #
2471 # learn some remote IPv4 EPs
2472 #
2473 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002474 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002475 # arriving on an unknown TEP
2476 p = (Ether(src=self.pg2.remote_mac,
2477 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002478 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002479 dst=self.pg2.local_ip4) /
2480 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002481 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002482 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2483 IP(src=l['ip'], dst=ep.ip4.address) /
2484 UDP(sport=1234, dport=1234) /
2485 Raw('\xa5' * 100))
2486
2487 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2488
2489 # the new TEP
2490 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2491 self,
2492 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002493 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002494 vx_tun_l3.vni)
2495 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2496
2497 # endpoint learnt via the parent GBP-vxlan interface
2498 self.assertTrue(find_gbp_endpoint(self,
2499 vx_tun_l3._sw_if_index,
2500 ip=l['ip']))
2501
2502 #
2503 # Add a remote endpoint from the API
2504 #
2505 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2506 epg_220, None,
2507 "10.0.0.88", "11.0.0.88",
2508 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002509 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002510 self.pg2.local_ip4,
2511 self.pg2.remote_hosts[1].ip4,
2512 mac=None)
2513 rep_88.add_vpp_config()
2514
2515 #
2516 # Add a remote endpoint from the API that matches an existing one
2517 #
2518 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2519 epg_220, None,
2520 learnt[0]['ip'], "11.0.0.101",
2521 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002522 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002523 self.pg2.local_ip4,
2524 self.pg2.remote_hosts[1].ip4,
2525 mac=None)
2526 rep_2.add_vpp_config()
2527
2528 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002529 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002530 # packets should be send on the v4/v6 uu=fwd interface resp.
2531 #
2532 se_10_1_24 = VppGbpSubnet(
2533 self, rd1, "10.0.1.0", 24,
2534 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2535 se_10_1_24.add_vpp_config()
2536
2537 self.logger.info(self.vapi.cli("show gbp endpoint"))
2538
2539 ips = ["10.0.0.88", learnt[0]['ip']]
2540 for ip in ips:
2541 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2542 IP(dst=ip, src=ep.ip4.address) /
2543 UDP(sport=1234, dport=1234) /
2544 Raw('\xa5' * 100))
2545
2546 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2547
2548 for rx in rxs:
2549 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2550 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2551 self.assertEqual(rx[UDP].dport, 48879)
2552 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002553 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002554 self.assertEqual(rx[VXLAN].vni, 101)
2555 self.assertTrue(rx[VXLAN].flags.G)
2556 self.assertTrue(rx[VXLAN].flags.Instance)
2557 self.assertTrue(rx[VXLAN].gpflags.A)
2558 self.assertFalse(rx[VXLAN].gpflags.D)
2559
2560 inner = rx[VXLAN].payload
2561
2562 self.assertEqual(inner[Ether].src, routed_src_mac)
2563 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2564 self.assertEqual(inner[IP].src, ep.ip4.address)
2565 self.assertEqual(inner[IP].dst, ip)
2566
2567 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002568 # remove the API remote EPs, only API sourced is gone, the DP
2569 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002570 #
2571 rep_88.remove_vpp_config()
2572 rep_2.remove_vpp_config()
2573
Neale Ranns00a469d2018-12-20 06:12:19 -08002574 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2575
2576 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2577 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2578 UDP(sport=1234, dport=1234) /
2579 Raw('\xa5' * 100))
2580 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002581
Neale Ranns13a08cc2018-11-07 09:25:54 -08002582 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002583
Neale Ranns13a08cc2018-11-07 09:25:54 -08002584 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2585 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2586 UDP(sport=1234, dport=1234) /
2587 Raw('\xa5' * 100))
2588 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002589
Neale Ranns13a08cc2018-11-07 09:25:54 -08002590 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002591 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08002592 # present (because it's DP learnt) when the TC ends so wait until
2593 # it is removed
2594 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002595 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2596 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002597
2598 #
2599 # shutdown with learnt endpoint present
2600 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002601 p = (Ether(src=self.pg2.remote_mac,
2602 dst=self.pg2.local_mac) /
2603 IP(src=self.pg2.remote_hosts[1].ip4,
2604 dst=self.pg2.local_ip4) /
2605 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002606 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002607 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2608 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2609 UDP(sport=1234, dport=1234) /
2610 Raw('\xa5' * 100))
2611
2612 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2613
2614 # endpoint learnt via the parent GBP-vxlan interface
2615 self.assertTrue(find_gbp_endpoint(self,
2616 vx_tun_l3._sw_if_index,
2617 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002618
2619 #
2620 # TODO
2621 # remote endpoint becomes local
2622 #
2623 self.pg2.unconfig_ip4()
2624 self.pg3.unconfig_ip4()
2625 self.pg4.unconfig_ip4()
2626
Neale Ranns13a08cc2018-11-07 09:25:54 -08002627 def test_gbp_redirect(self):
2628 """ GBP Endpoint Redirect """
2629
2630 self.vapi.cli("set logging class gbp debug")
2631
Neale Rannsb6a47952018-11-21 05:44:35 -08002632 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002633 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2634 routed_src_mac = "00:22:bd:f8:19:ff"
2635
2636 learnt = [{'mac': '00:00:11:11:11:02',
2637 'ip': '10.0.1.2',
2638 'ip6': '2001:10::2'},
2639 {'mac': '00:00:11:11:11:03',
2640 'ip': '10.0.1.3',
2641 'ip6': '2001:10::3'}]
2642
2643 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002644 # IP tables
2645 #
2646 t4 = VppIpTable(self, 1)
2647 t4.add_vpp_config()
2648 t6 = VppIpTable(self, 1, True)
2649 t6.add_vpp_config()
2650
2651 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2652 rd1.add_vpp_config()
2653
Ole Troan8006c6a2018-12-17 12:02:26 +01002654 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002655
2656 #
2657 # Bind the BVI to the RD
2658 #
2659 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2660 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2661
2662 #
2663 # Pg7 hosts a BD's UU-fwd
2664 #
2665 self.pg7.config_ip4()
2666 self.pg7.resolve_arp()
2667
2668 #
2669 # a GBP bridge domains for the EPs
2670 #
2671 bd1 = VppBridgeDomain(self, 1)
2672 bd1.add_vpp_config()
2673 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2674 gbd1.add_vpp_config()
2675
2676 bd2 = VppBridgeDomain(self, 2)
2677 bd2.add_vpp_config()
2678 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2679 gbd2.add_vpp_config()
2680
2681 # ... and has a /32 and /128 applied
2682 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2683 ip4_addr.add_vpp_config()
2684 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2685 ip6_addr.add_vpp_config()
2686 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2687 ip4_addr.add_vpp_config()
2688 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2689 ip6_addr.add_vpp_config()
2690
2691 #
2692 # The Endpoint-groups in which we are learning endpoints
2693 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002694 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002695 None, gbd1.bvi,
2696 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002697 "2001:10::128",
2698 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002699 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002700 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002701 None, gbd2.bvi,
2702 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002703 "2001:11::128",
2704 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002705 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002706 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002707 None, gbd1.bvi,
2708 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002709 "2001:12::128",
2710 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002711 epg_222.add_vpp_config()
2712
2713 #
2714 # a GBP bridge domains for the SEPs
2715 #
2716 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2717 self.pg7.remote_ip4, 116)
2718 bd_uu1.add_vpp_config()
2719 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2720 self.pg7.remote_ip4, 117)
2721 bd_uu2.add_vpp_config()
2722
2723 bd3 = VppBridgeDomain(self, 3)
2724 bd3.add_vpp_config()
2725 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2726 gbd3.add_vpp_config()
2727 bd4 = VppBridgeDomain(self, 4)
2728 bd4.add_vpp_config()
2729 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2730 gbd4.add_vpp_config()
2731
2732 #
2733 # EPGs in which the service endpoints exist
2734 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002735 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002736 None, gbd1.bvi,
2737 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002738 "4001:10::128",
2739 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002740 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002741 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002742 None, gbd2.bvi,
2743 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002744 "4001:11::128",
2745 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002746 epg_321.add_vpp_config()
2747
2748 #
2749 # three local endpoints
2750 #
2751 ep1 = VppGbpEndpoint(self, self.pg0,
2752 epg_220, None,
2753 "10.0.0.1", "11.0.0.1",
2754 "2001:10::1", "3001:10::1")
2755 ep1.add_vpp_config()
2756 ep2 = VppGbpEndpoint(self, self.pg1,
2757 epg_221, None,
2758 "10.0.1.1", "11.0.1.1",
2759 "2001:11::1", "3001:11::1")
2760 ep2.add_vpp_config()
2761 ep3 = VppGbpEndpoint(self, self.pg2,
2762 epg_222, None,
2763 "10.0.2.2", "11.0.2.2",
2764 "2001:12::1", "3001:12::1")
2765 ep3.add_vpp_config()
2766
2767 #
2768 # service endpoints
2769 #
2770 sep1 = VppGbpEndpoint(self, self.pg3,
2771 epg_320, None,
2772 "12.0.0.1", "13.0.0.1",
2773 "4001:10::1", "5001:10::1")
2774 sep1.add_vpp_config()
2775 sep2 = VppGbpEndpoint(self, self.pg4,
2776 epg_320, None,
2777 "12.0.0.2", "13.0.0.2",
2778 "4001:10::2", "5001:10::2")
2779 sep2.add_vpp_config()
2780 sep3 = VppGbpEndpoint(self, self.pg5,
2781 epg_321, None,
2782 "12.0.1.1", "13.0.1.1",
2783 "4001:11::1", "5001:11::1")
2784 sep3.add_vpp_config()
2785 # this EP is not installed immediately
2786 sep4 = VppGbpEndpoint(self, self.pg6,
2787 epg_321, None,
2788 "12.0.1.2", "13.0.1.2",
2789 "4001:11::2", "5001:11::2")
2790
2791 #
2792 # an L2 switch packet between local EPs in different EPGs
2793 # different dest ports on each so the are LB hashed differently
2794 #
2795 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2796 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2797 UDP(sport=1234, dport=1234) /
2798 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002799 (Ether(src=ep3.mac, dst=ep1.mac) /
2800 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2801 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002802 Raw('\xa5' * 100))]
2803 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2804 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2805 UDP(sport=1234, dport=1234) /
2806 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002807 (Ether(src=ep3.mac, dst=ep1.mac) /
2808 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002809 UDP(sport=1234, dport=1230) /
2810 Raw('\xa5' * 100))]
2811
2812 # should be dropped since no contract yet
2813 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2814 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2815
2816 #
2817 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2818 # one of the next-hops is via an EP that is not known
2819 #
2820 acl = VppGbpAcl(self)
2821 rule4 = acl.create_rule(permit_deny=1, proto=17)
2822 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2823 acl_index = acl.add_vpp_config([rule4, rule6])
2824
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002825 #
2826 # test the src-ip hash mode
2827 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002828 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002829 self, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002830 [VppGbpContractRule(
2831 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002832 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002833 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2834 sep1.ip4, sep1.epg.rd),
2835 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2836 sep2.ip4, sep2.epg.rd)]),
2837 VppGbpContractRule(
2838 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002839 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002840 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2841 sep3.ip6, sep3.epg.rd),
2842 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002843 sep4.ip6, sep4.epg.rd)])],
2844 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002845 c1.add_vpp_config()
2846
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002847 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002848 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002849 [VppGbpContractRule(
2850 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2851 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2852 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2853 sep1.ip4, sep1.epg.rd),
2854 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2855 sep2.ip4, sep2.epg.rd)]),
2856 VppGbpContractRule(
2857 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2858 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2859 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2860 sep3.ip6, sep3.epg.rd),
2861 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002862 sep4.ip6, sep4.epg.rd)])],
2863 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002864 c2.add_vpp_config()
2865
Neale Ranns13a08cc2018-11-07 09:25:54 -08002866 #
2867 # send again with the contract preset, now packets arrive
2868 # at SEP1 or SEP2 depending on the hashing
2869 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002870 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002871
2872 for rx in rxs:
2873 self.assertEqual(rx[Ether].src, routed_src_mac)
2874 self.assertEqual(rx[Ether].dst, sep1.mac)
2875 self.assertEqual(rx[IP].src, ep1.ip4.address)
2876 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2877
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002878 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2879
2880 for rx in rxs:
2881 self.assertEqual(rx[Ether].src, routed_src_mac)
2882 self.assertEqual(rx[Ether].dst, sep2.mac)
2883 self.assertEqual(rx[IP].src, ep3.ip4.address)
2884 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2885
Neale Ranns13a08cc2018-11-07 09:25:54 -08002886 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2887
2888 for rx in rxs:
2889 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2890 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2891 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2892 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2893 self.assertEqual(rx[VXLAN].vni, 117)
2894 self.assertTrue(rx[VXLAN].flags.G)
2895 self.assertTrue(rx[VXLAN].flags.Instance)
2896 # redirect policy has been applied
2897 self.assertTrue(rx[VXLAN].gpflags.A)
2898 self.assertFalse(rx[VXLAN].gpflags.D)
2899
2900 inner = rx[VXLAN].payload
2901
2902 self.assertEqual(inner[Ether].src, routed_src_mac)
2903 self.assertEqual(inner[Ether].dst, sep4.mac)
2904 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2905 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2906
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002907 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002908
2909 for rx in rxs:
2910 self.assertEqual(rx[Ether].src, routed_src_mac)
2911 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002912 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2913 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002914
2915 #
2916 # programme the unknown EP
2917 #
2918 sep4.add_vpp_config()
2919
2920 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2921
2922 for rx in rxs:
2923 self.assertEqual(rx[Ether].src, routed_src_mac)
2924 self.assertEqual(rx[Ether].dst, sep4.mac)
2925 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2926 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2927
2928 #
2929 # and revert back to unprogrammed
2930 #
2931 sep4.remove_vpp_config()
2932
2933 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2934
2935 for rx in rxs:
2936 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2937 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2938 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2939 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2940 self.assertEqual(rx[VXLAN].vni, 117)
2941 self.assertTrue(rx[VXLAN].flags.G)
2942 self.assertTrue(rx[VXLAN].flags.Instance)
2943 # redirect policy has been applied
2944 self.assertTrue(rx[VXLAN].gpflags.A)
2945 self.assertFalse(rx[VXLAN].gpflags.D)
2946
2947 inner = rx[VXLAN].payload
2948
2949 self.assertEqual(inner[Ether].src, routed_src_mac)
2950 self.assertEqual(inner[Ether].dst, sep4.mac)
2951 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2952 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2953
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002954 c1.remove_vpp_config()
2955 c2.remove_vpp_config()
2956
2957 #
2958 # test the symmetric hash mode
2959 #
2960 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002961 self, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002962 [VppGbpContractRule(
2963 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2964 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2965 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2966 sep1.ip4, sep1.epg.rd),
2967 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2968 sep2.ip4, sep2.epg.rd)]),
2969 VppGbpContractRule(
2970 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2971 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2972 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2973 sep3.ip6, sep3.epg.rd),
2974 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002975 sep4.ip6, sep4.epg.rd)])],
2976 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002977 c1.add_vpp_config()
2978
2979 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002980 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002981 [VppGbpContractRule(
2982 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2983 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2984 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2985 sep1.ip4, sep1.epg.rd),
2986 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2987 sep2.ip4, sep2.epg.rd)]),
2988 VppGbpContractRule(
2989 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2990 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2991 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2992 sep3.ip6, sep3.epg.rd),
2993 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002994 sep4.ip6, sep4.epg.rd)])],
2995 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002996 c2.add_vpp_config()
2997
2998 #
2999 # send again with the contract preset, now packets arrive
3000 # at SEP1 for both directions
3001 #
3002 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3003
3004 for rx in rxs:
3005 self.assertEqual(rx[Ether].src, routed_src_mac)
3006 self.assertEqual(rx[Ether].dst, sep1.mac)
3007 self.assertEqual(rx[IP].src, ep1.ip4.address)
3008 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3009
3010 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3011
3012 for rx in rxs:
3013 self.assertEqual(rx[Ether].src, routed_src_mac)
3014 self.assertEqual(rx[Ether].dst, sep1.mac)
3015 self.assertEqual(rx[IP].src, ep3.ip4.address)
3016 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3017
Neale Ranns13a08cc2018-11-07 09:25:54 -08003018 #
3019 # programme the unknown EP for the L3 tests
3020 #
3021 sep4.add_vpp_config()
3022
3023 #
3024 # an L3 switch packet between local EPs in different EPGs
3025 # different dest ports on each so the are LB hashed differently
3026 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003027 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003028 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3029 UDP(sport=1234, dport=1234) /
3030 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003031 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003032 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3033 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003034 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003035 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003036 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3037 UDP(sport=1234, dport=1234) /
3038 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003039 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003040 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3041 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003042 Raw('\xa5' * 100))]
3043
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003044 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003045 self, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003046 [VppGbpContractRule(
3047 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3048 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3049 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3050 sep1.ip4, sep1.epg.rd),
3051 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3052 sep2.ip4, sep2.epg.rd)]),
3053 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08003054 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003055 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003056 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3057 sep3.ip6, sep3.epg.rd),
3058 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3059 sep4.ip6, sep4.epg.rd)])],
3060 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003061 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003062
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003063 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003064
3065 for rx in rxs:
3066 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003067 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003068 self.assertEqual(rx[IP].src, ep1.ip4.address)
3069 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3070
3071 #
3072 # learn a remote EP in EPG 221
3073 #
3074 vx_tun_l3 = VppGbpVxlanTunnel(
3075 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003076 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3077 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003078 vx_tun_l3.add_vpp_config()
3079
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003080 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003081 self, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003082 [VppGbpContractRule(
3083 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3084 []),
3085 VppGbpContractRule(
3086 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003087 [])],
3088 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003089 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003090
3091 p = (Ether(src=self.pg7.remote_mac,
3092 dst=self.pg7.local_mac) /
3093 IP(src=self.pg7.remote_ip4,
3094 dst=self.pg7.local_ip4) /
3095 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003096 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003097 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003098 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3099 UDP(sport=1234, dport=1234) /
3100 Raw('\xa5' * 100))
3101
3102 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3103
3104 # endpoint learnt via the parent GBP-vxlan interface
3105 self.assertTrue(find_gbp_endpoint(self,
3106 vx_tun_l3._sw_if_index,
3107 ip="10.0.0.88"))
3108
3109 p = (Ether(src=self.pg7.remote_mac,
3110 dst=self.pg7.local_mac) /
3111 IP(src=self.pg7.remote_ip4,
3112 dst=self.pg7.local_ip4) /
3113 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003114 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003115 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003116 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3117 UDP(sport=1234, dport=1234) /
3118 Raw('\xa5' * 100))
3119
3120 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3121
3122 # endpoint learnt via the parent GBP-vxlan interface
3123 self.assertTrue(find_gbp_endpoint(self,
3124 vx_tun_l3._sw_if_index,
3125 ip="2001:10::88"))
3126
3127 #
3128 # L3 switch from local to remote EP
3129 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003130 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003131 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3132 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003133 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003134 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003135 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3136 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003137 Raw('\xa5' * 100))]
3138
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003139 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003140
3141 for rx in rxs:
3142 self.assertEqual(rx[Ether].src, routed_src_mac)
3143 self.assertEqual(rx[Ether].dst, sep1.mac)
3144 self.assertEqual(rx[IP].src, ep1.ip4.address)
3145 self.assertEqual(rx[IP].dst, "10.0.0.88")
3146
3147 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3148
3149 for rx in rxs:
3150 self.assertEqual(rx[Ether].src, routed_src_mac)
3151 self.assertEqual(rx[Ether].dst, sep4.mac)
3152 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3153 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3154
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003155 #
3156 # test the dst-ip hash mode
3157 #
3158 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003159 self, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003160 [VppGbpContractRule(
3161 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3162 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3163 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3164 sep1.ip4, sep1.epg.rd),
3165 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3166 sep2.ip4, sep2.epg.rd)]),
3167 VppGbpContractRule(
3168 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3169 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3170 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3171 sep3.ip6, sep3.epg.rd),
3172 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003173 sep4.ip6, sep4.epg.rd)])],
3174 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003175 c5.add_vpp_config()
3176
3177 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3178
3179 for rx in rxs:
3180 self.assertEqual(rx[Ether].src, routed_src_mac)
3181 self.assertEqual(rx[Ether].dst, sep1.mac)
3182 self.assertEqual(rx[IP].src, ep1.ip4.address)
3183 self.assertEqual(rx[IP].dst, "10.0.0.88")
3184
3185 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003186
3187 for rx in rxs:
3188 self.assertEqual(rx[Ether].src, routed_src_mac)
3189 self.assertEqual(rx[Ether].dst, sep3.mac)
3190 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3191 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3192
Neale Rannsb6a47952018-11-21 05:44:35 -08003193 #
3194 # cleanup
3195 #
3196 self.pg7.unconfig_ip4()
3197
3198 def test_gbp_l3_out(self):
3199 """ GBP L3 Out """
3200
3201 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3202 self.vapi.cli("set logging class gbp debug")
3203
3204 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3205 routed_src_mac = "00:22:bd:f8:19:ff"
3206
3207 #
3208 # IP tables
3209 #
3210 t4 = VppIpTable(self, 1)
3211 t4.add_vpp_config()
3212 t6 = VppIpTable(self, 1, True)
3213 t6.add_vpp_config()
3214
3215 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3216 rd1.add_vpp_config()
3217
Ole Troan8006c6a2018-12-17 12:02:26 +01003218 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003219
3220 #
3221 # Bind the BVI to the RD
3222 #
3223 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3224 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3225
3226 #
3227 # Pg7 hosts a BD's BUM
3228 # Pg1 some other l3 interface
3229 #
3230 self.pg7.config_ip4()
3231 self.pg7.resolve_arp()
3232
3233 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003234 # a multicast vxlan-gbp tunnel for broadcast in the BD
3235 #
3236 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3237 "239.1.1.1", 88,
3238 mcast_itf=self.pg7)
3239 tun_bm.add_vpp_config()
3240
3241 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003242 # a GBP external bridge domains for the EPs
3243 #
3244 bd1 = VppBridgeDomain(self, 1)
3245 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003246 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003247 gbd1.add_vpp_config()
3248
3249 #
3250 # The Endpoint-groups in which the external endpoints exist
3251 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003252 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003253 None, gbd1.bvi,
3254 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003255 "2001:10::128",
3256 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003257 epg_220.add_vpp_config()
3258
3259 # the BVIs have the subnets applied ...
3260 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3261 ip4_addr.add_vpp_config()
3262 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3263 ip6_addr.add_vpp_config()
3264
3265 # ... which are L3-out subnets
3266 l3o_1 = VppGbpSubnet(
3267 self, rd1, "10.0.0.0", 24,
3268 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003269 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003270 l3o_1.add_vpp_config()
3271
3272 #
3273 # an external interface attached to the outside world and the
3274 # external BD
3275 #
3276 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3277 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003278 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3279 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3280 vlan_101.admin_up()
3281 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3282
3283 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003284 ext_itf.add_vpp_config()
3285
3286 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003287 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003288 #
3289 vx_tun_l3 = VppGbpVxlanTunnel(
3290 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003291 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3292 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003293 vx_tun_l3.add_vpp_config()
3294
3295 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003296 # External Endpoints
3297 #
3298 eep1 = VppGbpEndpoint(self, vlan_100,
3299 epg_220, None,
3300 "10.0.0.1", "11.0.0.1",
3301 "2001:10::1", "3001::1",
3302 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3303 eep1.add_vpp_config()
3304 eep2 = VppGbpEndpoint(self, vlan_101,
3305 epg_220, None,
3306 "10.0.0.2", "11.0.0.2",
3307 "2001:10::2", "3001::2",
3308 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3309 eep2.add_vpp_config()
3310
3311 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003312 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003313 #
3314 rep = VppGbpEndpoint(self, vx_tun_l3,
3315 epg_220, None,
3316 "10.0.0.101", "11.0.0.101",
3317 "2001:10::101", "3001::101",
3318 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3319 self.pg7.local_ip4,
3320 self.pg7.remote_ip4,
3321 mac=None)
3322 rep.add_vpp_config()
3323
3324 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003325 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003326 #
3327 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3328 Dot1Q(vlan=100) /
3329 ARP(op="who-has",
3330 psrc=eep1.ip4.address, pdst="10.0.0.128",
3331 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3332 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3333
3334 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003335 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003336 # are ARP'd for
3337 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003338 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003339 Dot1Q(vlan=100) /
3340 IP(src="10.0.0.1", dst="10.0.0.88") /
3341 UDP(sport=1234, dport=1234) /
3342 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003343 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003344 Dot1Q(vlan=100) /
3345 IPv6(src="2001:10::1", dst="2001:10::88") /
3346 UDP(sport=1234, dport=1234) /
3347 Raw('\xa5' * 100))
3348
3349 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3350
3351 for rx in rxs:
3352 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3353 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3354 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3355 self.assertEqual(rx[IP].dst, "239.1.1.1")
3356 self.assertEqual(rx[VXLAN].vni, 88)
3357 self.assertTrue(rx[VXLAN].flags.G)
3358 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003359 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003360 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003361 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003362 self.assertFalse(rx[VXLAN].gpflags.D)
3363
3364 inner = rx[VXLAN].payload
3365
3366 self.assertTrue(inner.haslayer(ARP))
3367
3368 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003369 # remote to external
3370 #
3371 p = (Ether(src=self.pg7.remote_mac,
3372 dst=self.pg7.local_mac) /
3373 IP(src=self.pg7.remote_ip4,
3374 dst=self.pg7.local_ip4) /
3375 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003376 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003377 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003378 IP(src="10.0.0.101", dst="10.0.0.1") /
3379 UDP(sport=1234, dport=1234) /
3380 Raw('\xa5' * 100))
3381
3382 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3383
3384 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003385 # local EP pings router
3386 #
3387 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3388 Dot1Q(vlan=100) /
3389 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3390 ICMP(type='echo-request'))
3391
3392 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3393
3394 for rx in rxs:
3395 self.assertEqual(rx[Ether].src, str(self.router_mac))
3396 self.assertEqual(rx[Ether].dst, eep1.mac)
3397 self.assertEqual(rx[Dot1Q].vlan, 100)
3398
3399 #
3400 # local EP pings other local EP
3401 #
3402 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3403 Dot1Q(vlan=100) /
3404 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3405 ICMP(type='echo-request'))
3406
3407 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3408
3409 for rx in rxs:
3410 self.assertEqual(rx[Ether].src, eep1.mac)
3411 self.assertEqual(rx[Ether].dst, eep2.mac)
3412 self.assertEqual(rx[Dot1Q].vlan, 101)
3413
3414 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003415 # A subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08003416 #
3417 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003418 [VppRoutePath(eep1.ip4.address,
3419 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003420 table_id=t4.table_id)
3421 ip_220.add_vpp_config()
3422
3423 l3o_220 = VppGbpSubnet(
3424 self, rd1, "10.220.0.0", 24,
3425 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003426 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003427 l3o_220.add_vpp_config()
3428
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003429 #
3430 # A subnet reachable through the external EP2
3431 #
3432 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3433 [VppRoutePath(eep2.ip4.address,
3434 eep2.epg.bvi.sw_if_index)],
3435 table_id=t4.table_id)
3436 ip_221.add_vpp_config()
3437
3438 l3o_221 = VppGbpSubnet(
3439 self, rd1, "10.221.0.0", 24,
3440 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3441 sclass=4221)
3442 l3o_221.add_vpp_config()
3443
3444 #
3445 # ping between hosts in remote subnets
3446 # dropped without a contract
3447 #
3448 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3449 Dot1Q(vlan=100) /
3450 IP(src="10.220.0.1", dst="10.221.0.1") /
3451 ICMP(type='echo-request'))
3452
3453 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3454
3455 #
3456 # contract for the external nets to communicate
3457 #
3458 acl = VppGbpAcl(self)
3459 rule4 = acl.create_rule(permit_deny=1, proto=17)
3460 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3461 acl_index = acl.add_vpp_config([rule4, rule6])
3462
3463 c1 = VppGbpContract(
3464 self, 4220, 4221, acl_index,
3465 [VppGbpContractRule(
3466 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3467 []),
3468 VppGbpContractRule(
3469 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3470 [])],
3471 [ETH_P_IP, ETH_P_IPV6])
3472 c1.add_vpp_config()
3473
3474 #
3475 # Contracts allowing ext-net 200 to talk with external EPs
3476 #
3477 c2 = VppGbpContract(
3478 self, 4220, 113, acl_index,
3479 [VppGbpContractRule(
3480 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3481 []),
3482 VppGbpContractRule(
3483 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3484 [])],
3485 [ETH_P_IP, ETH_P_IPV6])
3486 c2.add_vpp_config()
3487 c3 = VppGbpContract(
3488 self, 113, 4220, acl_index,
3489 [VppGbpContractRule(
3490 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3491 []),
3492 VppGbpContractRule(
3493 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3494 [])],
3495 [ETH_P_IP, ETH_P_IPV6])
3496 c3.add_vpp_config()
3497
3498 #
3499 # ping between hosts in remote subnets
3500 #
3501 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3502 Dot1Q(vlan=100) /
3503 IP(src="10.220.0.1", dst="10.221.0.1") /
3504 UDP(sport=1234, dport=1234) /
3505 Raw('\xa5' * 100))
3506
3507 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3508
3509 for rx in rxs:
3510 self.assertEqual(rx[Ether].src, str(self.router_mac))
3511 self.assertEqual(rx[Ether].dst, eep2.mac)
3512 self.assertEqual(rx[Dot1Q].vlan, 101)
3513
3514 # we did not learn these external hosts
3515 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
3516 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
3517
3518 #
3519 # from remote external EP to local external EP
3520 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003521 p = (Ether(src=self.pg7.remote_mac,
3522 dst=self.pg7.local_mac) /
3523 IP(src=self.pg7.remote_ip4,
3524 dst=self.pg7.local_ip4) /
3525 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003526 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003527 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003528 IP(src="10.0.0.101", dst="10.220.0.1") /
3529 UDP(sport=1234, dport=1234) /
3530 Raw('\xa5' * 100))
3531
3532 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3533
3534 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003535 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07003536 #
3537 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3538 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003539 IP(src="10.220.0.1", dst=rep.ip4.address) /
3540 UDP(sport=1234, dport=1234) /
3541 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003542
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003543 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07003544
3545 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003546 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3547 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3548 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3549 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3550 self.assertEqual(rx[VXLAN].vni, 444)
3551 self.assertTrue(rx[VXLAN].flags.G)
3552 self.assertTrue(rx[VXLAN].flags.Instance)
3553 # the sclass of the ext-net the packet came from
3554 self.assertEqual(rx[VXLAN].gpid, 4220)
3555 # policy was applied to the original IP packet
3556 self.assertTrue(rx[VXLAN].gpflags.A)
3557 # since it's an external host the reciever should not learn it
3558 self.assertTrue(rx[VXLAN].gpflags.D)
3559 inner = rx[VXLAN].payload
3560 self.assertEqual(inner[IP].src, "10.220.0.1")
3561 self.assertEqual(inner[IP].dst, rep.ip4.address)
3562
3563 #
3564 # An external subnet reachable via the remote external EP
3565 #
3566
3567 #
3568 # first the VXLAN-GBP tunnel over which it is reached
3569 #
3570 vx_tun_r = VppVxlanGbpTunnel(
3571 self, self.pg7.local_ip4,
3572 self.pg7.remote_ip4, 445,
3573 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
3574 VXLAN_GBP_API_TUNNEL_MODE_L3))
3575 vx_tun_r.add_vpp_config()
3576 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
3577
3578 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
3579
3580 #
3581 # then the special adj to resolve through on that tunnel
3582 #
3583 n1 = VppNeighbor(self,
3584 vx_tun_r.sw_if_index,
3585 "00:0c:0c:0c:0c:0c",
3586 self.pg7.remote_ip4)
3587 n1.add_vpp_config()
3588
3589 #
3590 # the route via the adj above
3591 #
3592 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
3593 [VppRoutePath(self.pg7.remote_ip4,
3594 vx_tun_r.sw_if_index)],
3595 table_id=t4.table_id)
3596 ip_222.add_vpp_config()
3597
3598 l3o_222 = VppGbpSubnet(
3599 self, rd1, "10.222.0.0", 24,
3600 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3601 sclass=4222)
3602 l3o_222.add_vpp_config()
3603
3604 #
3605 # ping between hosts in local and remote external subnets
3606 # dropped without a contract
3607 #
3608 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3609 Dot1Q(vlan=100) /
3610 IP(src="10.220.0.1", dst="10.222.0.1") /
3611 UDP(sport=1234, dport=1234) /
3612 Raw('\xa5' * 100))
3613
3614 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3615
3616 #
3617 # Add contracts ext-nets for 220 -> 222
3618 #
3619 c4 = VppGbpContract(
3620 self, 4220, 4222, acl_index,
3621 [VppGbpContractRule(
3622 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3623 []),
3624 VppGbpContractRule(
3625 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3626 [])],
3627 [ETH_P_IP, ETH_P_IPV6])
3628 c4.add_vpp_config()
3629
3630 #
3631 # ping from host in local to remote external subnets
3632 #
3633 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3634 Dot1Q(vlan=100) /
3635 IP(src="10.220.0.1", dst="10.222.0.1") /
3636 UDP(sport=1234, dport=1234) /
3637 Raw('\xa5' * 100))
3638
3639 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
3640
3641 for rx in rxs:
3642 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3643 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3644 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3645 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3646 self.assertEqual(rx[VXLAN].vni, 445)
3647 self.assertTrue(rx[VXLAN].flags.G)
3648 self.assertTrue(rx[VXLAN].flags.Instance)
3649 # the sclass of the ext-net the packet came from
3650 self.assertEqual(rx[VXLAN].gpid, 4220)
3651 # policy was applied to the original IP packet
3652 self.assertTrue(rx[VXLAN].gpflags.A)
3653 # since it's an external host the reciever should not learn it
3654 self.assertTrue(rx[VXLAN].gpflags.D)
3655 inner = rx[VXLAN].payload
3656 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
3657 self.assertEqual(inner[IP].src, "10.220.0.1")
3658 self.assertEqual(inner[IP].dst, "10.222.0.1")
3659
3660 #
3661 # ping from host in remote to local external subnets
3662 # there's no contract for this, but the A bit is set.
3663 #
3664 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3665 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3666 UDP(sport=1234, dport=48879) /
3667 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3668 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3669 IP(src="10.222.0.1", dst="10.220.0.1") /
3670 UDP(sport=1234, dport=1234) /
3671 Raw('\xa5' * 100))
3672
3673 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3674 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07003675
3676 #
Neale Ranns2b600182019-03-29 05:08:27 -07003677 # ping from host in remote to remote external subnets
3678 # this is dropped by reflection check.
3679 #
3680 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3681 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3682 UDP(sport=1234, dport=48879) /
3683 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3684 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3685 IP(src="10.222.0.1", dst="10.222.0.2") /
3686 UDP(sport=1234, dport=1234) /
3687 Raw('\xa5' * 100))
3688
3689 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
3690
3691 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003692 # cleanup
3693 #
3694 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003695 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003696
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003697
3698if __name__ == '__main__':
3699 unittest.main(testRunner=VppTestRunner)