blob: cc38bc9c1ce668112a1d5ad20b551ab0f434f904 [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
Filip Vargadd1e3e72019-04-15 18:52:43 +0200578 @property
579 def config_flags(self):
580 return VppEnum.vl_api_nat_config_flags_t
581
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700582 @classmethod
583 def setUpClass(cls):
584 super(TestGBP, cls).setUpClass()
585
586 @classmethod
587 def tearDownClass(cls):
588 super(TestGBP, cls).tearDownClass()
589
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800590 def setUp(self):
591 super(TestGBP, self).setUp()
592
Neale Ranns25b04942018-04-04 09:34:50 -0700593 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700594 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700595
Ole Troan8006c6a2018-12-17 12:02:26 +0100596 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800597
598 for i in self.pg_interfaces:
599 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700600 for i in self.lo_interfaces:
601 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800602
603 def tearDown(self):
604 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700605 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800606
607 super(TestGBP, self).tearDown()
608
Neale Ranns25b04942018-04-04 09:34:50 -0700609 def send_and_expect_bridged(self, src, tx, dst):
610 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800611
Neale Ranns25b04942018-04-04 09:34:50 -0700612 for r in rx:
613 self.assertEqual(r[Ether].src, tx[0][Ether].src)
614 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
615 self.assertEqual(r[IP].src, tx[0][IP].src)
616 self.assertEqual(r[IP].dst, tx[0][IP].dst)
617 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800618
Neale Ranns25b04942018-04-04 09:34:50 -0700619 def send_and_expect_bridged6(self, src, tx, dst):
620 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800621
Neale Ranns25b04942018-04-04 09:34:50 -0700622 for r in rx:
623 self.assertEqual(r[Ether].src, tx[0][Ether].src)
624 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
625 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
626 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
627 return rx
628
629 def send_and_expect_routed(self, src, tx, dst, src_mac):
630 rx = self.send_and_expect(src, tx, dst)
631
632 for r in rx:
633 self.assertEqual(r[Ether].src, src_mac)
634 self.assertEqual(r[Ether].dst, dst.remote_mac)
635 self.assertEqual(r[IP].src, tx[0][IP].src)
636 self.assertEqual(r[IP].dst, tx[0][IP].dst)
637 return rx
638
639 def send_and_expect_natted(self, src, tx, dst, src_ip):
640 rx = self.send_and_expect(src, tx, dst)
641
642 for r in rx:
643 self.assertEqual(r[Ether].src, tx[0][Ether].src)
644 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
645 self.assertEqual(r[IP].src, src_ip)
646 self.assertEqual(r[IP].dst, tx[0][IP].dst)
647 return rx
648
Neale Ranns4a6d0232018-04-24 07:45:33 -0700649 def send_and_expect_natted6(self, src, tx, dst, src_ip):
650 rx = self.send_and_expect(src, tx, dst)
651
652 for r in rx:
653 self.assertEqual(r[Ether].src, tx[0][Ether].src)
654 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
655 self.assertEqual(r[IPv6].src, src_ip)
656 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
657 return rx
658
Neale Ranns25b04942018-04-04 09:34:50 -0700659 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
660 rx = self.send_and_expect(src, tx, dst)
661
662 for r in rx:
663 self.assertEqual(r[Ether].src, tx[0][Ether].src)
664 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
665 self.assertEqual(r[IP].dst, dst_ip)
666 self.assertEqual(r[IP].src, tx[0][IP].src)
667 return rx
668
Neale Ranns4a6d0232018-04-24 07:45:33 -0700669 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
670 rx = self.send_and_expect(src, tx, dst)
671
672 for r in rx:
673 self.assertEqual(r[Ether].src, tx[0][Ether].src)
674 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
675 self.assertEqual(r[IPv6].dst, dst_ip)
676 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
677 return rx
678
Neale Ranns25b04942018-04-04 09:34:50 -0700679 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
680 rx = self.send_and_expect(src, tx, dst)
681
682 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100683 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700684 self.assertEqual(r[Ether].dst, dst.remote_mac)
685 self.assertEqual(r[IP].dst, dst_ip)
686 self.assertEqual(r[IP].src, src_ip)
687 return rx
688
Neale Ranns4a6d0232018-04-24 07:45:33 -0700689 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
690 rx = self.send_and_expect(src, tx, dst)
691
692 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100693 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700694 self.assertEqual(r[Ether].dst, dst.remote_mac)
695 self.assertEqual(r[IPv6].dst, dst_ip)
696 self.assertEqual(r[IPv6].src, src_ip)
697 return rx
698
Neale Ranns25b04942018-04-04 09:34:50 -0700699 def test_gbp(self):
700 """ Group Based Policy """
701
Neale Rannsb6a47952018-11-21 05:44:35 -0800702 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
703
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800704 #
Neale Ranns25b04942018-04-04 09:34:50 -0700705 # Bridge Domains
706 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700707 bd1 = VppBridgeDomain(self, 1)
708 bd2 = VppBridgeDomain(self, 2)
709 bd20 = VppBridgeDomain(self, 20)
710
711 bd1.add_vpp_config()
712 bd2.add_vpp_config()
713 bd20.add_vpp_config()
714
715 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
716 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
717 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
718
719 gbd1.add_vpp_config()
720 gbd2.add_vpp_config()
721 gbd20.add_vpp_config()
722
723 #
724 # Route Domains
725 #
726 gt4 = VppIpTable(self, 0)
727 gt4.add_vpp_config()
728 gt6 = VppIpTable(self, 0, is_ip6=True)
729 gt6.add_vpp_config()
730 nt4 = VppIpTable(self, 20)
731 nt4.add_vpp_config()
732 nt6 = VppIpTable(self, 20, is_ip6=True)
733 nt6.add_vpp_config()
734
735 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
736 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
737
738 rd0.add_vpp_config()
739 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700740
741 #
742 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700743 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
744 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000745 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
746 self.pg4, self.loop0,
747 "10.0.0.128", "2001:10::128"),
748 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
749 self.pg5, self.loop0,
750 "10.0.1.128", "2001:10:1::128"),
751 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
752 self.pg6, self.loop1,
753 "10.0.2.128", "2001:10:2::128"),
754 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
755 self.pg7, self.loop2,
756 "11.0.0.128", "3001::128"),
757 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
758 self.pg8, self.loop2,
759 "11.0.0.129", "3001::129")]
760 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
761 VppGbpRecirc(self, epgs[1], self.loop4),
762 VppGbpRecirc(self, epgs[2], self.loop5),
763 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
764 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700765
766 epg_nat = epgs[3]
767 recirc_nat = recircs[3]
768
769 #
770 # 4 end-points, 2 in the same subnet, 3 in the same BD
771 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700772 eps = [VppGbpEndpoint(self, self.pg0,
773 epgs[0], recircs[0],
774 "10.0.0.1", "11.0.0.1",
775 "2001:10::1", "3001::1"),
776 VppGbpEndpoint(self, self.pg1,
777 epgs[0], recircs[0],
778 "10.0.0.2", "11.0.0.2",
779 "2001:10::2", "3001::2"),
780 VppGbpEndpoint(self, self.pg2,
781 epgs[1], recircs[1],
782 "10.0.1.1", "11.0.0.3",
783 "2001:10:1::1", "3001::3"),
784 VppGbpEndpoint(self, self.pg3,
785 epgs[2], recircs[2],
786 "10.0.2.1", "11.0.0.4",
787 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700788
789 #
790 # Config related to each of the EPGs
791 #
792 for epg in epgs:
793 # IP config on the BVI interfaces
794 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700795 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
796 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
797 self.vapi.sw_interface_set_mac_address(
798 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100799 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700800
801 # The BVIs are NAT inside interfaces
Filip Vargadd1e3e72019-04-15 18:52:43 +0200802 flags = self.config_flags.NAT_IS_INSIDE
Neale Ranns25b04942018-04-04 09:34:50 -0700803 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
Filip Vargadd1e3e72019-04-15 18:52:43 +0200804 flags=flags)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700805 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
Filip Vargadd1e3e72019-04-15 18:52:43 +0200806 flags=flags)
Neale Ranns25b04942018-04-04 09:34:50 -0700807
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700808 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
809 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
810 if_ip4.add_vpp_config()
811 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700812
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700813 # EPG uplink interfaces in the RD
814 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
815 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700816
817 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700818 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100819 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700820 epg.bvi_ip4)
821 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100822 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700823 epg.bvi_ip6)
824 epg.bd_arp_ip4.add_vpp_config()
825 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700826
827 # EPG in VPP
828 epg.add_vpp_config()
829
830 for recirc in recircs:
831 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700832 VppIpInterfaceBind(self, recirc.recirc,
833 recirc.epg.rd.t4).add_vpp_config()
834 VppIpInterfaceBind(self, recirc.recirc,
835 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700836
Neale Ranns4a6d0232018-04-24 07:45:33 -0700837 self.vapi.nat44_interface_add_del_feature(
Filip Vargadd1e3e72019-04-15 18:52:43 +0200838 recirc.recirc.sw_if_index)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700839 self.vapi.nat66_add_del_interface(
Filip Vargadd1e3e72019-04-15 18:52:43 +0200840 recirc.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700841
842 recirc.add_vpp_config()
843
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700844 for recirc in recircs:
845 self.assertTrue(find_bridge_domain_port(self,
846 recirc.epg.bd.bd.bd_id,
847 recirc.recirc.sw_if_index))
848
Neale Ranns25b04942018-04-04 09:34:50 -0700849 for ep in eps:
850 self.pg_enable_capture(self.pg_interfaces)
851 self.pg_start()
852 #
853 # routes to the endpoints. We need these since there are no
854 # adj-fibs due to the fact the the BVI address has /32 and
855 # the subnet is not attached.
856 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700857 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700858 # Add static mappings for each EP from the 10/8 to 11/8 network
859 if ip.af == AF_INET:
Filip Vargadd1e3e72019-04-15 18:52:43 +0200860 flags = self.config_flags.NAT_IS_ADDR_ONLY
Neale Rannsc0a93142018-09-05 15:42:26 -0700861 self.vapi.nat44_add_del_static_mapping(ip.bytes,
862 fip.bytes,
863 vrf_id=0,
Filip Vargadd1e3e72019-04-15 18:52:43 +0200864 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -0700865 else:
866 self.vapi.nat66_add_del_static_mapping(ip.bytes,
867 fip.bytes,
868 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700869
Neale Ranns25b04942018-04-04 09:34:50 -0700870 # VPP EP create ...
871 ep.add_vpp_config()
872
Neale Rannsc0a93142018-09-05 15:42:26 -0700873 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700874
Neale Rannsc0a93142018-09-05 15:42:26 -0700875 # ... results in a Gratuitous ARP/ND on the EPG's uplink
876 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
877
878 for ii, ip in enumerate(ep.ips):
879 p = rx[ii]
880
881 if ip.is_ip6:
882 self.assertTrue(p.haslayer(ICMPv6ND_NA))
883 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
884 else:
885 self.assertTrue(p.haslayer(ARP))
886 self.assertEqual(p[ARP].psrc, ip.address)
887 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700888
889 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700890 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700891 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
892 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700893
Neale Rannsc0a93142018-09-05 15:42:26 -0700894 # floating IPs route via EPG recirc
895 r = VppIpRoute(self, fip.address, fip.length,
896 [VppRoutePath(fip.address,
897 ep.recirc.recirc.sw_if_index,
898 is_dvr=1,
899 proto=fip.dpo_proto)],
900 table_id=20,
901 is_ip6=fip.is_ip6)
902 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700903
904 # L2 FIB entries in the NAT EPG BD to bridge the packets from
905 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700906 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
907 ep.recirc.recirc, bvi_mac=0)
908 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700909
910 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700911 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700912 #
913 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
914 src=self.pg0.remote_mac) /
915 ARP(op="who-has",
916 hwdst="ff:ff:ff:ff:ff:ff",
917 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700918 pdst="10.0.0.88",
919 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700920
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700921 self.vapi.cli("clear trace")
922 self.pg0.add_stream(pkt_arp)
923
924 self.pg_enable_capture(self.pg_interfaces)
925 self.pg_start()
926
927 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700928
929 #
930 # ARP/ND packets get a response
931 #
932 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
933 src=self.pg0.remote_mac) /
934 ARP(op="who-has",
935 hwdst="ff:ff:ff:ff:ff:ff",
936 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700937 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700938 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700939
940 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
941
Neale Rannsc0a93142018-09-05 15:42:26 -0700942 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700943 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700944 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
945 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700946 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700947 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700948 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
949 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
950
951 #
952 # broadcast packets are flooded
953 #
954 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
955 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700956 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700957 UDP(sport=1234, dport=1234) /
958 Raw('\xa5' * 100))
959
960 self.vapi.cli("clear trace")
961 self.pg0.add_stream(pkt_bcast)
962
963 self.pg_enable_capture(self.pg_interfaces)
964 self.pg_start()
965
966 rxd = eps[1].itf.get_capture(1)
967 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
968 rxd = epgs[0].uplink.get_capture(1)
969 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
970
971 #
972 # packets to non-local L3 destinations dropped
973 #
974 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100975 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700976 IP(src=eps[0].ip4.address,
977 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700978 UDP(sport=1234, dport=1234) /
979 Raw('\xa5' * 100))
980 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100981 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700982 IP(src=eps[0].ip4.address,
983 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700984 UDP(sport=1234, dport=1234) /
985 Raw('\xa5' * 100))
986
987 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
988
989 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100990 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700991 IPv6(src=eps[0].ip6.address,
992 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700993 UDP(sport=1234, dport=1234) /
994 Raw('\xa5' * 100))
995 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
996
997 #
998 # Add the subnet routes
999 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001000 s41 = VppGbpSubnet(
1001 self, rd0, "10.0.0.0", 24,
1002 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1003 s42 = VppGbpSubnet(
1004 self, rd0, "10.0.1.0", 24,
1005 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1006 s43 = VppGbpSubnet(
1007 self, rd0, "10.0.2.0", 24,
1008 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1009 s61 = VppGbpSubnet(
1010 self, rd0, "2001:10::1", 64,
1011 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1012 s62 = VppGbpSubnet(
1013 self, rd0, "2001:10:1::1", 64,
1014 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1015 s63 = VppGbpSubnet(
1016 self, rd0, "2001:10:2::1", 64,
1017 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001018 s41.add_vpp_config()
1019 s42.add_vpp_config()
1020 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001021 s61.add_vpp_config()
1022 s62.add_vpp_config()
1023 s63.add_vpp_config()
1024
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001025 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001026 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001027 eps[0].epg.uplink)
1028 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001029 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001030 eps[0].epg.uplink)
1031 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001032 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001033 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001034
1035 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1036 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1037 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1038 self.logger.info(self.vapi.cli("sh gbp recirc"))
1039 self.logger.info(self.vapi.cli("sh int"))
1040 self.logger.info(self.vapi.cli("sh int addr"))
1041 self.logger.info(self.vapi.cli("sh int feat loop6"))
1042 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1043 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001044 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001045
1046 #
1047 # Packet destined to unknown unicast is sent on the epg uplink ...
1048 #
1049 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1050 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001051 IP(src=eps[0].ip4.address,
1052 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001053 UDP(sport=1234, dport=1234) /
1054 Raw('\xa5' * 100))
1055
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001056 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001057 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001058 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001059 # ... and nowhere else
1060 self.pg1.get_capture(0, timeout=0.1)
1061 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1062
1063 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1064 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001065 IP(src=eps[0].ip4.address,
1066 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001067 UDP(sport=1234, dport=1234) /
1068 Raw('\xa5' * 100))
1069
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001070 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001071 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001072 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001073
1074 #
1075 # Packets from the uplink are forwarded in the absence of a contract
1076 #
1077 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1078 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001079 IP(src=eps[0].ip4.address,
1080 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001081 UDP(sport=1234, dport=1234) /
1082 Raw('\xa5' * 100))
1083
1084 self.send_and_expect_bridged(self.pg4,
1085 pkt_intra_epg_220_from_uplink * 65,
1086 self.pg0)
1087
1088 #
1089 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001090 # can communicate
1091 #
1092 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001093 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001094 IP(src=eps[0].ip4.address,
1095 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001096 UDP(sport=1234, dport=1234) /
1097 Raw('\xa5' * 100))
1098
Neale Ranns25b04942018-04-04 09:34:50 -07001099 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001100
1101 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001102 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001103 # cannot communicate
1104 #
1105 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001106 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001107 IP(src=eps[0].ip4.address,
1108 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001109 UDP(sport=1234, dport=1234) /
1110 Raw('\xa5' * 100))
1111 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001112 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001113 IP(src=eps[2].ip4.address,
1114 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001115 UDP(sport=1234, dport=1234) /
1116 Raw('\xa5' * 100))
1117 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001118 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001119 IP(src=eps[0].ip4.address,
1120 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001121 UDP(sport=1234, dport=1234) /
1122 Raw('\xa5' * 100))
1123
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001124 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001125 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001126 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001127 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001128
1129 #
1130 # A uni-directional contract from EPG 220 -> 221
1131 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001132 acl = VppGbpAcl(self)
1133 rule = acl.create_rule(permit_deny=1, proto=17)
1134 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1135 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001136 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001137 self, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001138 [VppGbpContractRule(
1139 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1140 []),
1141 VppGbpContractRule(
1142 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001143 [])],
1144 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001145 c1.add_vpp_config()
1146
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001147 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001148 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001149 eps[2].itf)
1150 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001151 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001152
1153 #
1154 # contract for the return direction
1155 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001156 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001157 self, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001158 [VppGbpContractRule(
1159 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1160 []),
1161 VppGbpContractRule(
1162 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001163 [])],
1164 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001165 c2.add_vpp_config()
1166
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001167 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001168 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001169 eps[2].itf)
1170 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001171 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001172 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001173
Neale Ranns796c84b2019-03-28 07:56:23 -07001174 ds = c2.get_drop_stats()
1175 self.assertEqual(ds['packets'], 0)
1176 ps = c2.get_permit_stats()
1177 self.assertEqual(ps['packets'], 65)
1178
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001179 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001180 # the contract does not allow non-IP
1181 #
1182 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1183 dst=self.pg2.remote_mac) /
1184 ARP())
1185 self.send_and_assert_no_replies(eps[0].itf,
1186 pkt_non_ip_inter_epg_220_to_221 * 17)
1187
1188 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001189 # check that inter group is still disabled for the groups
1190 # not in the contract.
1191 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001192 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001193 pkt_inter_epg_220_to_222 * 65)
1194
Neale Ranns25b04942018-04-04 09:34:50 -07001195 #
1196 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1197 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001198 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001199 self, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001200 [VppGbpContractRule(
1201 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1202 []),
1203 VppGbpContractRule(
1204 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001205 [])],
1206 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001207 c3.add_vpp_config()
1208
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001209 self.logger.info(self.vapi.cli("sh gbp contract"))
1210
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001211 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001212 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001213 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001214 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001215
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001216 #
1217 # remove both contracts, traffic stops in both directions
1218 #
1219 c2.remove_vpp_config()
1220 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001221 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001222 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001223
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001224 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001225 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001226 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001227 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001228 self.send_and_expect_bridged(eps[0].itf,
1229 pkt_intra_epg * 65,
1230 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001231
1232 #
Neale Ranns25b04942018-04-04 09:34:50 -07001233 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001234 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001235
Neale Ranns25b04942018-04-04 09:34:50 -07001236 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001237 se1 = VppGbpSubnet(
1238 self, rd0, "0.0.0.0", 0,
1239 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1240 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001241 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001242 se2 = VppGbpSubnet(
1243 self, rd0, "11.0.0.0", 8,
1244 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1245 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001246 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001247 se16 = VppGbpSubnet(
1248 self, rd0, "::", 0,
1249 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1250 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001251 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001252 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001253 se3 = VppGbpSubnet(
1254 self, rd20, "0.0.0.0", 0,
1255 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1256 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001257 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001258 se36 = VppGbpSubnet(
1259 self, rd20, "::", 0,
1260 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1261 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001262 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001263 se4 = VppGbpSubnet(
1264 self, rd20, "11.0.0.0", 8,
1265 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1266 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001267 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001268 se1.add_vpp_config()
1269 se2.add_vpp_config()
1270 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001271 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001272 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001273 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001274
Neale Ranns25b04942018-04-04 09:34:50 -07001275 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1276 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001277 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1278 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001279 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001280
Neale Ranns4a6d0232018-04-24 07:45:33 -07001281 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001282 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001283 #
Neale Ranns25b04942018-04-04 09:34:50 -07001284 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001285 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001286 IP(src=eps[0].ip4.address,
1287 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001288 UDP(sport=1234, dport=1234) /
1289 Raw('\xa5' * 100))
1290
1291 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001292 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001293 pkt_inter_epg_220_to_global * 65)
1294
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001295 acl2 = VppGbpAcl(self)
1296 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1297 sport_to=1234, dport_from=1234, dport_to=1234)
1298 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1299 sport_from=1234, sport_to=1234,
1300 dport_from=1234, dport_to=1234)
1301
1302 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001303 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001304 self, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001305 [VppGbpContractRule(
1306 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1307 []),
1308 VppGbpContractRule(
1309 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001310 [])],
1311 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001312 c4.add_vpp_config()
1313
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001314 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001315 pkt_inter_epg_220_to_global * 65,
1316 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001317 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001318
Neale Ranns4a6d0232018-04-24 07:45:33 -07001319 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001320 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001321 IPv6(src=eps[0].ip6.address,
1322 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001323 UDP(sport=1234, dport=1234) /
1324 Raw('\xa5' * 100))
1325
1326 self.send_and_expect_natted6(self.pg0,
1327 pkt_inter_epg_220_to_global * 65,
1328 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001329 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001330
1331 #
1332 # From a global address to an EP: OUT2IN
1333 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001334 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001335 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001336 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001337 src="1.1.1.1") /
1338 UDP(sport=1234, dport=1234) /
1339 Raw('\xa5' * 100))
1340
1341 self.send_and_assert_no_replies(self.pg7,
1342 pkt_inter_epg_220_from_global * 65)
1343
Neale Ranns13a08cc2018-11-07 09:25:54 -08001344 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001345 self, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001346 [VppGbpContractRule(
1347 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1348 []),
1349 VppGbpContractRule(
1350 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001351 [])],
1352 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001353 c5.add_vpp_config()
1354
1355 self.send_and_expect_unnatted(self.pg7,
1356 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001357 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001358 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001359
Ole Troan8006c6a2018-12-17 12:02:26 +01001360 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001361 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001362 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001363 src="6001::1") /
1364 UDP(sport=1234, dport=1234) /
1365 Raw('\xa5' * 100))
1366
1367 self.send_and_expect_unnatted6(self.pg7,
1368 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001369 eps[0].itf,
1370 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001371
1372 #
1373 # From a local VM to another local VM using resp. public addresses:
1374 # IN2OUT2IN
1375 #
Neale Ranns25b04942018-04-04 09:34:50 -07001376 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001377 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001378 IP(src=eps[0].ip4.address,
1379 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001380 UDP(sport=1234, dport=1234) /
1381 Raw('\xa5' * 100))
1382
Neale Ranns4a6d0232018-04-24 07:45:33 -07001383 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001384 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001385 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001386 eps[0].fip4.address,
1387 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001388
Neale Rannsc0a93142018-09-05 15:42:26 -07001389 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001390 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001391 IPv6(src=eps[0].ip6.address,
1392 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001393 UDP(sport=1234, dport=1234) /
1394 Raw('\xa5' * 100))
1395
Neale Rannsc0a93142018-09-05 15:42:26 -07001396 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001397 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001398 eps[1].itf,
1399 eps[0].fip6.address,
1400 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001401
1402 #
Neale Ranns25b04942018-04-04 09:34:50 -07001403 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001404 #
Neale Ranns25b04942018-04-04 09:34:50 -07001405 for ep in eps:
1406 # del static mappings for each EP from the 10/8 to 11/8 network
Filip Vargadd1e3e72019-04-15 18:52:43 +02001407 flags = self.config_flags.NAT_IS_ADDR_ONLY
Neale Rannsc0a93142018-09-05 15:42:26 -07001408 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1409 ep.fip4.bytes,
1410 vrf_id=0,
Filip Vargadd1e3e72019-04-15 18:52:43 +02001411 is_add=0,
1412 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -07001413 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1414 ep.fip6.bytes,
1415 vrf_id=0,
1416 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001417
Neale Ranns25b04942018-04-04 09:34:50 -07001418 for epg in epgs:
1419 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001420 if epg != epgs[0] and epg != epgs[3]:
Filip Vargadd1e3e72019-04-15 18:52:43 +02001421 flags = self.config_flags.NAT_IS_INSIDE
Neale Ranns25b04942018-04-04 09:34:50 -07001422 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
Filip Vargadd1e3e72019-04-15 18:52:43 +02001423 flags=flags,
Neale Ranns25b04942018-04-04 09:34:50 -07001424 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001425 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
Filip Vargadd1e3e72019-04-15 18:52:43 +02001426 flags=flags,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001427 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001428
Neale Ranns25b04942018-04-04 09:34:50 -07001429 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001430 self.vapi.nat44_interface_add_del_feature(
1431 recirc.recirc.sw_if_index,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001432 is_add=0)
1433 self.vapi.nat66_add_del_interface(
1434 recirc.recirc.sw_if_index,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001435 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001436
Neale Ranns774356a2018-11-29 12:02:16 +00001437 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1438 n_tries=100, s_time=1):
1439 while (n_tries):
1440 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1441 return True
1442 n_tries = n_tries - 1
1443 self.sleep(s_time)
1444 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1445 return False
1446
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001447 def test_gbp_learn_l2(self):
1448 """ GBP L2 Endpoint Learning """
1449
Neale Ranns796c84b2019-03-28 07:56:23 -07001450 self.vapi.cli("clear errors")
1451
Neale Rannsb6a47952018-11-21 05:44:35 -08001452 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001453 learnt = [{'mac': '00:00:11:11:11:01',
1454 'ip': '10.0.0.1',
1455 'ip6': '2001:10::2'},
1456 {'mac': '00:00:11:11:11:02',
1457 'ip': '10.0.0.2',
1458 'ip6': '2001:10::3'}]
1459
1460 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001461 # IP tables
1462 #
1463 gt4 = VppIpTable(self, 1)
1464 gt4.add_vpp_config()
1465 gt6 = VppIpTable(self, 1, is_ip6=True)
1466 gt6.add_vpp_config()
1467
1468 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1469 rd1.add_vpp_config()
1470
1471 #
1472 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1473 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1474 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1475 #
1476 self.pg2.config_ip4()
1477 self.pg2.resolve_arp()
1478 self.pg2.generate_remote_hosts(4)
1479 self.pg2.configure_ipv4_neighbors()
1480 self.pg3.config_ip4()
1481 self.pg3.resolve_arp()
1482 self.pg4.config_ip4()
1483 self.pg4.resolve_arp()
1484
1485 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001486 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1487 #
1488 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1489 "239.1.1.1", 88,
1490 mcast_itf=self.pg4)
1491 tun_bm.add_vpp_config()
1492
1493 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001494 # a GBP bridge domain with a BVI and a UU-flood interface
1495 #
1496 bd1 = VppBridgeDomain(self, 1)
1497 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001498 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001499 gbd1.add_vpp_config()
1500
1501 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1502 self.logger.info(self.vapi.cli("sh gbp bridge"))
1503
1504 # ... and has a /32 applied
1505 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1506 ip_addr.add_vpp_config()
1507
1508 #
1509 # The Endpoint-group in which we are learning endpoints
1510 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001511 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001512 None, self.loop0,
1513 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001514 "2001:10::128",
1515 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001516 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001517 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001518 None, self.loop1,
1519 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001520 "2001:11::128",
1521 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001522 epg_330.add_vpp_config()
1523
1524 #
1525 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001526 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001527 #
1528 vx_tun_l2_1 = VppGbpVxlanTunnel(
1529 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001530 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1531 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001532 vx_tun_l2_1.add_vpp_config()
1533
1534 #
1535 # A static endpoint that the learnt endpoints are trying to
1536 # talk to
1537 #
1538 ep = VppGbpEndpoint(self, self.pg0,
1539 epg_220, None,
1540 "10.0.0.127", "11.0.0.127",
1541 "2001:10::1", "3001::1")
1542 ep.add_vpp_config()
1543
1544 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1545
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001546 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001547 p = (Ether(src=self.pg2.remote_mac,
1548 dst=self.pg2.local_mac) /
1549 IP(src=self.pg2.remote_hosts[0].ip4,
1550 dst=self.pg2.local_ip4) /
1551 UDP(sport=1234, dport=48879) /
1552 VXLAN(vni=99, gpid=88, flags=0x88) /
1553 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1554 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1555 UDP(sport=1234, dport=1234) /
1556 Raw('\xa5' * 100))
1557
1558 self.send_and_assert_no_replies(self.pg2, p)
1559
Neale Ranns796c84b2019-03-28 07:56:23 -07001560 self.logger.info(self.vapi.cli("sh error"))
1561 # self.assert_packet_counter_equal(
1562 # '/err/gbp-policy-port/drop-no-contract', 1)
1563
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001564 #
1565 # we should not have learnt a new tunnel endpoint, since
1566 # the EPG was not learnt.
1567 #
1568 self.assertEqual(INDEX_INVALID,
1569 find_vxlan_gbp_tunnel(self,
1570 self.pg2.local_ip4,
1571 self.pg2.remote_hosts[0].ip4,
1572 99))
1573
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001574 # epg is not learnt, because the EPG is unknown
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001575 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1576
Neale Ranns8da9fc62019-03-04 14:08:11 -08001577 #
1578 # Learn new EPs from IP packets
1579 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001580 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001581 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001582 # arriving on an unknown TEP
1583 p = (Ether(src=self.pg2.remote_mac,
1584 dst=self.pg2.local_mac) /
1585 IP(src=self.pg2.remote_hosts[1].ip4,
1586 dst=self.pg2.local_ip4) /
1587 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001588 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001589 Ether(src=l['mac'], dst=ep.mac) /
1590 IP(src=l['ip'], dst=ep.ip4.address) /
1591 UDP(sport=1234, dport=1234) /
1592 Raw('\xa5' * 100))
1593
1594 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1595
1596 # the new TEP
1597 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1598 self,
1599 self.pg2.local_ip4,
1600 self.pg2.remote_hosts[1].ip4,
1601 99)
1602 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1603
1604 #
1605 # the EP is learnt via the learnt TEP
1606 # both from its MAC and its IP
1607 #
1608 self.assertTrue(find_gbp_endpoint(self,
1609 vx_tun_l2_1.sw_if_index,
1610 mac=l['mac']))
1611 self.assertTrue(find_gbp_endpoint(self,
1612 vx_tun_l2_1.sw_if_index,
1613 ip=l['ip']))
1614
Neale Ranns796c84b2019-03-28 07:56:23 -07001615 # self.assert_packet_counter_equal(
1616 # '/err/gbp-policy-port/allow-intra-sclass', 2)
1617
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001618 self.logger.info(self.vapi.cli("show gbp endpoint"))
1619 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001620 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001621
1622 #
1623 # If we sleep for the threshold time, the learnt endpoints should
1624 # age out
1625 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001626 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001627 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1628 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001629
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001630 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001631 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1632 #
1633 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001634 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001635 # arriving on an unknown TEP
1636 p = (Ether(src=self.pg2.remote_mac,
1637 dst=self.pg2.local_mac) /
1638 IP(src=self.pg2.remote_hosts[1].ip4,
1639 dst="239.1.1.1") /
1640 UDP(sport=1234, dport=48879) /
1641 VXLAN(vni=88, gpid=112, flags=0x88) /
1642 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1643 ARP(op="who-has",
1644 psrc=l['ip'], pdst=l['ip'],
1645 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1646
1647 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1648
1649 # the new TEP
1650 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1651 self,
1652 self.pg2.local_ip4,
1653 self.pg2.remote_hosts[1].ip4,
1654 99)
1655 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1656
1657 #
1658 # the EP is learnt via the learnt TEP
1659 # both from its MAC and its IP
1660 #
1661 self.assertTrue(find_gbp_endpoint(self,
1662 vx_tun_l2_1.sw_if_index,
1663 mac=l['mac']))
1664 self.assertTrue(find_gbp_endpoint(self,
1665 vx_tun_l2_1.sw_if_index,
1666 ip=l['ip']))
1667
1668 #
1669 # wait for the learnt endpoints to age out
1670 #
1671 for l in learnt:
1672 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1673 mac=l['mac'])
1674
1675 #
1676 # Learn new EPs from L2 packets
1677 #
1678 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001679 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001680 # arriving on an unknown TEP
1681 p = (Ether(src=self.pg2.remote_mac,
1682 dst=self.pg2.local_mac) /
1683 IP(src=self.pg2.remote_hosts[1].ip4,
1684 dst=self.pg2.local_ip4) /
1685 UDP(sport=1234, dport=48879) /
1686 VXLAN(vni=99, gpid=112, flags=0x88) /
1687 Ether(src=l['mac'], dst=ep.mac) /
1688 Raw('\xa5' * 100))
1689
1690 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1691
1692 # the new TEP
1693 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1694 self,
1695 self.pg2.local_ip4,
1696 self.pg2.remote_hosts[1].ip4,
1697 99)
1698 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1699
1700 #
1701 # the EP is learnt via the learnt TEP
1702 # both from its MAC and its IP
1703 #
1704 self.assertTrue(find_gbp_endpoint(self,
1705 vx_tun_l2_1.sw_if_index,
1706 mac=l['mac']))
1707
1708 self.logger.info(self.vapi.cli("show gbp endpoint"))
1709 self.logger.info(self.vapi.cli("show gbp vxlan"))
1710 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1711
1712 #
1713 # wait for the learnt endpoints to age out
1714 #
1715 for l in learnt:
1716 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1717 mac=l['mac'])
1718
1719 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001720 # repeat. the do not learn bit is set so the EPs are not learnt
1721 #
1722 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001723 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001724 p = (Ether(src=self.pg2.remote_mac,
1725 dst=self.pg2.local_mac) /
1726 IP(src=self.pg2.remote_hosts[1].ip4,
1727 dst=self.pg2.local_ip4) /
1728 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001729 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001730 Ether(src=l['mac'], dst=ep.mac) /
1731 IP(src=l['ip'], dst=ep.ip4.address) /
1732 UDP(sport=1234, dport=1234) /
1733 Raw('\xa5' * 100))
1734
1735 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1736
1737 for l in learnt:
1738 self.assertFalse(find_gbp_endpoint(self,
1739 vx_tun_l2_1.sw_if_index,
1740 mac=l['mac']))
1741
1742 #
1743 # repeat
1744 #
1745 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001746 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001747 p = (Ether(src=self.pg2.remote_mac,
1748 dst=self.pg2.local_mac) /
1749 IP(src=self.pg2.remote_hosts[1].ip4,
1750 dst=self.pg2.local_ip4) /
1751 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001752 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001753 Ether(src=l['mac'], dst=ep.mac) /
1754 IP(src=l['ip'], dst=ep.ip4.address) /
1755 UDP(sport=1234, dport=1234) /
1756 Raw('\xa5' * 100))
1757
1758 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1759
1760 self.assertTrue(find_gbp_endpoint(self,
1761 vx_tun_l2_1.sw_if_index,
1762 mac=l['mac']))
1763
1764 #
1765 # Static EP replies to dynamics
1766 #
1767 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1768 for l in learnt:
1769 p = (Ether(src=ep.mac, dst=l['mac']) /
1770 IP(dst=l['ip'], src=ep.ip4.address) /
1771 UDP(sport=1234, dport=1234) /
1772 Raw('\xa5' * 100))
1773
1774 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1775
1776 for rx in rxs:
1777 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1778 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1779 self.assertEqual(rx[UDP].dport, 48879)
1780 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001781 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001782 self.assertEqual(rx[VXLAN].vni, 99)
1783 self.assertTrue(rx[VXLAN].flags.G)
1784 self.assertTrue(rx[VXLAN].flags.Instance)
1785 self.assertTrue(rx[VXLAN].gpflags.A)
1786 self.assertFalse(rx[VXLAN].gpflags.D)
1787
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001788 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001789 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1790 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001791
1792 #
1793 # repeat in the other EPG
1794 # there's no contract between 220 and 330, but the A-bit is set
1795 # so the packet is cleared for delivery
1796 #
1797 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001798 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001799 p = (Ether(src=self.pg2.remote_mac,
1800 dst=self.pg2.local_mac) /
1801 IP(src=self.pg2.remote_hosts[1].ip4,
1802 dst=self.pg2.local_ip4) /
1803 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001804 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001805 Ether(src=l['mac'], dst=ep.mac) /
1806 IP(src=l['ip'], dst=ep.ip4.address) /
1807 UDP(sport=1234, dport=1234) /
1808 Raw('\xa5' * 100))
1809
1810 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1811
1812 self.assertTrue(find_gbp_endpoint(self,
1813 vx_tun_l2_1.sw_if_index,
1814 mac=l['mac']))
1815
1816 #
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02001817 # repeat in the other EPG
1818 # there's no contract between 220 and 330, but the sclass is set to 1
1819 # so the packet is cleared for delivery
1820 #
1821 for l in learnt:
1822 # a packet with an sclass from a known EPG
1823 p = (Ether(src=self.pg2.remote_mac,
1824 dst=self.pg2.local_mac) /
1825 IP(src=self.pg2.remote_hosts[1].ip4,
1826 dst=self.pg2.local_ip4) /
1827 UDP(sport=1234, dport=48879) /
1828 VXLAN(vni=99, gpid=1, flags=0x88) /
1829 Ether(src=l['mac'], dst=ep.mac) /
1830 IP(src=l['ip'], dst=ep.ip4.address) /
1831 UDP(sport=1234, dport=1234) /
1832 Raw('\xa5' * 100))
1833
1834 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1835
1836 self.assertTrue(find_gbp_endpoint(self,
1837 vx_tun_l2_1.sw_if_index,
1838 mac=l['mac']))
1839
1840 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001841 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001842 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001843 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001844 p = (Ether(src=ep.mac, dst=l['mac']) /
1845 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1846 UDP(sport=1234, dport=1234) /
1847 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001848
Neale Ranns13a08cc2018-11-07 09:25:54 -08001849 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001850
1851 #
1852 # refresh the entries after the check for no replies above
1853 #
1854 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001855 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001856 p = (Ether(src=self.pg2.remote_mac,
1857 dst=self.pg2.local_mac) /
1858 IP(src=self.pg2.remote_hosts[1].ip4,
1859 dst=self.pg2.local_ip4) /
1860 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001861 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001862 Ether(src=l['mac'], dst=ep.mac) /
1863 IP(src=l['ip'], dst=ep.ip4.address) /
1864 UDP(sport=1234, dport=1234) /
1865 Raw('\xa5' * 100))
1866
1867 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1868
1869 self.assertTrue(find_gbp_endpoint(self,
1870 vx_tun_l2_1.sw_if_index,
1871 mac=l['mac']))
1872
1873 #
1874 # Add the contract so they can talk
1875 #
1876 acl = VppGbpAcl(self)
1877 rule = acl.create_rule(permit_deny=1, proto=17)
1878 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1879 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001880 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001881 self, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001882 [VppGbpContractRule(
1883 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1884 []),
1885 VppGbpContractRule(
1886 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001887 [])],
1888 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001889 c1.add_vpp_config()
1890
1891 for l in learnt:
1892 p = (Ether(src=ep.mac, dst=l['mac']) /
1893 IP(dst=l['ip'], src=ep.ip4.address) /
1894 UDP(sport=1234, dport=1234) /
1895 Raw('\xa5' * 100))
1896
1897 self.send_and_expect(self.pg0, [p], self.pg2)
1898
1899 #
1900 # send UU packets from the local EP
1901 #
1902 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1903 self.logger.info(self.vapi.cli("sh gbp bridge"))
1904 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1905 IP(dst="10.0.0.133", src=ep.ip4.address) /
1906 UDP(sport=1234, dport=1234) /
1907 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001908 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001909
1910 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1911
1912 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1913 IP(dst="10.0.0.133", src=ep.ip4.address) /
1914 UDP(sport=1234, dport=1234) /
1915 Raw('\xa5' * 100))
1916 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1917
Neale Ranns879d11c2019-01-21 23:34:18 -08001918 for rx in rxs:
1919 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1920 self.assertEqual(rx[IP].dst, "239.1.1.1")
1921 self.assertEqual(rx[UDP].dport, 48879)
1922 # the UDP source port is a random value for hashing
1923 self.assertEqual(rx[VXLAN].gpid, 112)
1924 self.assertEqual(rx[VXLAN].vni, 88)
1925 self.assertTrue(rx[VXLAN].flags.G)
1926 self.assertTrue(rx[VXLAN].flags.Instance)
1927 self.assertFalse(rx[VXLAN].gpflags.A)
1928 self.assertFalse(rx[VXLAN].gpflags.D)
1929
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001930 #
1931 # Check v6 Endpoints
1932 #
1933 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001934 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001935 p = (Ether(src=self.pg2.remote_mac,
1936 dst=self.pg2.local_mac) /
1937 IP(src=self.pg2.remote_hosts[1].ip4,
1938 dst=self.pg2.local_ip4) /
1939 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001940 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001941 Ether(src=l['mac'], dst=ep.mac) /
1942 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1943 UDP(sport=1234, dport=1234) /
1944 Raw('\xa5' * 100))
1945
1946 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1947
1948 self.assertTrue(find_gbp_endpoint(self,
1949 vx_tun_l2_1.sw_if_index,
1950 mac=l['mac']))
1951
1952 #
1953 # L3 Endpoint Learning
1954 # - configured on the bridge's BVI
1955 #
1956
1957 #
1958 # clean up
1959 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001960 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001961 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1962 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001963 self.pg2.unconfig_ip4()
1964 self.pg3.unconfig_ip4()
1965 self.pg4.unconfig_ip4()
1966
1967 self.logger.info(self.vapi.cli("sh int"))
1968 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1969
Mohsin Kazmi7363d472019-04-04 13:22:15 +02001970 def test_gbp_bd_flags(self):
1971 """ GBP BD FLAGS """
1972
1973 #
1974 # IP tables
1975 #
1976 gt4 = VppIpTable(self, 1)
1977 gt4.add_vpp_config()
1978 gt6 = VppIpTable(self, 1, is_ip6=True)
1979 gt6.add_vpp_config()
1980
1981 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1982 rd1.add_vpp_config()
1983
1984 #
1985 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1986 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1987 #
1988 self.pg3.config_ip4()
1989 self.pg3.resolve_arp()
1990 self.pg4.config_ip4()
1991 self.pg4.resolve_arp()
1992
1993 #
1994 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1995 #
1996 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1997 "239.1.1.1", 88,
1998 mcast_itf=self.pg4)
1999 tun_bm.add_vpp_config()
2000
2001 #
2002 # a GBP bridge domain with a BVI and a UU-flood interface
2003 #
2004 bd1 = VppBridgeDomain(self, 1)
2005 bd1.add_vpp_config()
2006
2007 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm,
2008 uu_drop=True, bm_drop=True)
2009 gbd1.add_vpp_config()
2010
2011 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2012 self.logger.info(self.vapi.cli("sh gbp bridge"))
2013
2014 # ... and has a /32 applied
2015 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2016 ip_addr.add_vpp_config()
2017
2018 #
2019 # The Endpoint-group
2020 #
2021 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2022 None, self.loop0,
2023 "10.0.0.128",
2024 "2001:10::128",
2025 VppGbpEndpointRetention(2))
2026 epg_220.add_vpp_config()
2027
2028 ep = VppGbpEndpoint(self, self.pg0,
2029 epg_220, None,
2030 "10.0.0.127", "11.0.0.127",
2031 "2001:10::1", "3001::1")
2032 ep.add_vpp_config()
2033 #
2034 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2035 # in bd
2036 #
2037 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2038 self.logger.info(self.vapi.cli("sh gbp bridge"))
2039 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
2040 IP(dst="10.0.0.133", src=ep.ip4.address) /
2041 UDP(sport=1234, dport=1234) /
2042 Raw('\xa5' * 100))
2043 self.send_and_assert_no_replies(ep.itf, [p_uu])
2044
2045 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2046 IP(dst="10.0.0.133", src=ep.ip4.address) /
2047 UDP(sport=1234, dport=1234) /
2048 Raw('\xa5' * 100))
2049 self.send_and_assert_no_replies(ep.itf, [p_bm])
2050
2051 self.pg3.unconfig_ip4()
2052 self.pg4.unconfig_ip4()
2053
2054 self.logger.info(self.vapi.cli("sh int"))
2055
Neale Rannsc29c0af2018-11-07 04:21:12 -08002056 def test_gbp_learn_vlan_l2(self):
2057 """ GBP L2 Endpoint w/ VLANs"""
2058
Neale Rannsb6a47952018-11-21 05:44:35 -08002059 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002060 learnt = [{'mac': '00:00:11:11:11:01',
2061 'ip': '10.0.0.1',
2062 'ip6': '2001:10::2'},
2063 {'mac': '00:00:11:11:11:02',
2064 'ip': '10.0.0.2',
2065 'ip6': '2001:10::3'}]
2066
2067 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002068 # IP tables
2069 #
2070 gt4 = VppIpTable(self, 1)
2071 gt4.add_vpp_config()
2072 gt6 = VppIpTable(self, 1, is_ip6=True)
2073 gt6.add_vpp_config()
2074
2075 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
2076 rd1.add_vpp_config()
2077
2078 #
2079 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2080 #
2081 self.pg2.config_ip4()
2082 self.pg2.resolve_arp()
2083 self.pg2.generate_remote_hosts(4)
2084 self.pg2.configure_ipv4_neighbors()
2085 self.pg3.config_ip4()
2086 self.pg3.resolve_arp()
2087
2088 #
2089 # The EP will be on a vlan sub-interface
2090 #
2091 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2092 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002093 self.vapi.l2_interface_vlan_tag_rewrite(
2094 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2095 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002096
2097 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2098 self.pg3.remote_ip4, 116)
2099 bd_uu_fwd.add_vpp_config()
2100
2101 #
2102 # a GBP bridge domain with a BVI and a UU-flood interface
2103 # The BD is marked as do not learn, so no endpoints are ever
2104 # learnt in this BD.
2105 #
2106 bd1 = VppBridgeDomain(self, 1)
2107 bd1.add_vpp_config()
2108 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
2109 learn=False)
2110 gbd1.add_vpp_config()
2111
2112 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2113 self.logger.info(self.vapi.cli("sh gbp bridge"))
2114
2115 # ... and has a /32 applied
2116 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2117 ip_addr.add_vpp_config()
2118
2119 #
2120 # The Endpoint-group in which we are learning endpoints
2121 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002122 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002123 None, self.loop0,
2124 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002125 "2001:10::128",
2126 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002127 epg_220.add_vpp_config()
2128
2129 #
2130 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002131 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002132 #
2133 vx_tun_l2_1 = VppGbpVxlanTunnel(
2134 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002135 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2136 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002137 vx_tun_l2_1.add_vpp_config()
2138
2139 #
2140 # A static endpoint that the learnt endpoints are trying to
2141 # talk to
2142 #
2143 ep = VppGbpEndpoint(self, vlan_11,
2144 epg_220, None,
2145 "10.0.0.127", "11.0.0.127",
2146 "2001:10::1", "3001::1")
2147 ep.add_vpp_config()
2148
2149 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2150
2151 #
2152 # Send to the static EP
2153 #
2154 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002155 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002156 # arriving on an unknown TEP
2157 p = (Ether(src=self.pg2.remote_mac,
2158 dst=self.pg2.local_mac) /
2159 IP(src=self.pg2.remote_hosts[1].ip4,
2160 dst=self.pg2.local_ip4) /
2161 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002162 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002163 Ether(src=l['mac'], dst=ep.mac) /
2164 IP(src=l['ip'], dst=ep.ip4.address) /
2165 UDP(sport=1234, dport=1234) /
2166 Raw('\xa5' * 100))
2167
2168 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2169
2170 #
2171 # packet to EP has the EP's vlan tag
2172 #
2173 for rx in rxs:
2174 self.assertEqual(rx[Dot1Q].vlan, 11)
2175
2176 #
2177 # the EP is not learnt since the BD setting prevents it
2178 # also no TEP too
2179 #
2180 self.assertFalse(find_gbp_endpoint(self,
2181 vx_tun_l2_1.sw_if_index,
2182 mac=l['mac']))
2183 self.assertEqual(INDEX_INVALID,
2184 find_vxlan_gbp_tunnel(
2185 self,
2186 self.pg2.local_ip4,
2187 self.pg2.remote_hosts[1].ip4,
2188 99))
2189
2190 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2191
2192 #
2193 # static to remotes
2194 # we didn't learn the remotes so they are sent to the UU-fwd
2195 #
2196 for l in learnt:
2197 p = (Ether(src=ep.mac, dst=l['mac']) /
2198 Dot1Q(vlan=11) /
2199 IP(dst=l['ip'], src=ep.ip4.address) /
2200 UDP(sport=1234, dport=1234) /
2201 Raw('\xa5' * 100))
2202
2203 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2204
2205 for rx in rxs:
2206 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2207 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2208 self.assertEqual(rx[UDP].dport, 48879)
2209 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002210 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002211 self.assertEqual(rx[VXLAN].vni, 116)
2212 self.assertTrue(rx[VXLAN].flags.G)
2213 self.assertTrue(rx[VXLAN].flags.Instance)
2214 self.assertFalse(rx[VXLAN].gpflags.A)
2215 self.assertFalse(rx[VXLAN].gpflags.D)
2216
2217 self.pg2.unconfig_ip4()
2218 self.pg3.unconfig_ip4()
2219
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002220 def test_gbp_learn_l3(self):
2221 """ GBP L3 Endpoint Learning """
2222
Neale Ranns13a08cc2018-11-07 09:25:54 -08002223 self.vapi.cli("set logging class gbp debug")
2224
Neale Rannsb6a47952018-11-21 05:44:35 -08002225 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002226 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2227 routed_src_mac = "00:22:bd:f8:19:ff"
2228
2229 learnt = [{'mac': '00:00:11:11:11:02',
2230 'ip': '10.0.1.2',
2231 'ip6': '2001:10::2'},
2232 {'mac': '00:00:11:11:11:03',
2233 'ip': '10.0.1.3',
2234 'ip6': '2001:10::3'}]
2235
2236 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002237 # IP tables
2238 #
2239 t4 = VppIpTable(self, 1)
2240 t4.add_vpp_config()
2241 t6 = VppIpTable(self, 1, True)
2242 t6.add_vpp_config()
2243
2244 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2245 self.pg4.remote_ip4, 114)
2246 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2247 self.pg4.remote_ip4, 116)
2248 tun_ip4_uu.add_vpp_config()
2249 tun_ip6_uu.add_vpp_config()
2250
2251 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2252 rd1.add_vpp_config()
2253
Ole Troan8006c6a2018-12-17 12:02:26 +01002254 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002255
2256 #
2257 # Bind the BVI to the RD
2258 #
2259 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2260 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2261
2262 #
2263 # Pg2 hosts the vxlan tunnel
2264 # hosts on pg2 to act as TEPs
2265 # pg3 is BD uu-fwd
2266 # pg4 is RD uu-fwd
2267 #
2268 self.pg2.config_ip4()
2269 self.pg2.resolve_arp()
2270 self.pg2.generate_remote_hosts(4)
2271 self.pg2.configure_ipv4_neighbors()
2272 self.pg3.config_ip4()
2273 self.pg3.resolve_arp()
2274 self.pg4.config_ip4()
2275 self.pg4.resolve_arp()
2276
2277 #
2278 # a GBP bridge domain with a BVI and a UU-flood interface
2279 #
2280 bd1 = VppBridgeDomain(self, 1)
2281 bd1.add_vpp_config()
2282 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2283 gbd1.add_vpp_config()
2284
2285 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2286 self.logger.info(self.vapi.cli("sh gbp bridge"))
2287 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002288
2289 # ... and has a /32 and /128 applied
2290 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2291 ip4_addr.add_vpp_config()
2292 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2293 ip6_addr.add_vpp_config()
2294
2295 #
2296 # The Endpoint-group in which we are learning endpoints
2297 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002298 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002299 None, self.loop0,
2300 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002301 "2001:10::128",
2302 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002303 epg_220.add_vpp_config()
2304
2305 #
2306 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002307 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002308 #
2309 vx_tun_l3 = VppGbpVxlanTunnel(
2310 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002311 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2312 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002313 vx_tun_l3.add_vpp_config()
2314
2315 #
2316 # A static endpoint that the learnt endpoints are trying to
2317 # talk to
2318 #
2319 ep = VppGbpEndpoint(self, self.pg0,
2320 epg_220, None,
2321 "10.0.0.127", "11.0.0.127",
2322 "2001:10::1", "3001::1")
2323 ep.add_vpp_config()
2324
2325 #
2326 # learn some remote IPv4 EPs
2327 #
2328 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002329 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002330 # arriving on an unknown TEP
2331 p = (Ether(src=self.pg2.remote_mac,
2332 dst=self.pg2.local_mac) /
2333 IP(src=self.pg2.remote_hosts[1].ip4,
2334 dst=self.pg2.local_ip4) /
2335 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002336 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002337 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2338 IP(src=l['ip'], dst=ep.ip4.address) /
2339 UDP(sport=1234, dport=1234) /
2340 Raw('\xa5' * 100))
2341
2342 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2343
2344 # the new TEP
2345 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2346 self,
2347 self.pg2.local_ip4,
2348 self.pg2.remote_hosts[1].ip4,
2349 vx_tun_l3.vni)
2350 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2351
2352 # endpoint learnt via the parent GBP-vxlan interface
2353 self.assertTrue(find_gbp_endpoint(self,
2354 vx_tun_l3._sw_if_index,
2355 ip=l['ip']))
2356
2357 #
2358 # Static IPv4 EP replies to learnt
2359 #
2360 for l in learnt:
2361 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2362 IP(dst=l['ip'], src=ep.ip4.address) /
2363 UDP(sport=1234, dport=1234) /
2364 Raw('\xa5' * 100))
2365
2366 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2367
2368 for rx in rxs:
2369 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2370 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2371 self.assertEqual(rx[UDP].dport, 48879)
2372 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002373 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002374 self.assertEqual(rx[VXLAN].vni, 101)
2375 self.assertTrue(rx[VXLAN].flags.G)
2376 self.assertTrue(rx[VXLAN].flags.Instance)
2377 self.assertTrue(rx[VXLAN].gpflags.A)
2378 self.assertFalse(rx[VXLAN].gpflags.D)
2379
2380 inner = rx[VXLAN].payload
2381
2382 self.assertEqual(inner[Ether].src, routed_src_mac)
2383 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2384 self.assertEqual(inner[IP].src, ep.ip4.address)
2385 self.assertEqual(inner[IP].dst, l['ip'])
2386
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002387 for l in learnt:
2388 self.assertFalse(find_gbp_endpoint(self,
2389 tep1_sw_if_index,
2390 ip=l['ip']))
2391
2392 #
2393 # learn some remote IPv6 EPs
2394 #
2395 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002396 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002397 # arriving on an unknown TEP
2398 p = (Ether(src=self.pg2.remote_mac,
2399 dst=self.pg2.local_mac) /
2400 IP(src=self.pg2.remote_hosts[1].ip4,
2401 dst=self.pg2.local_ip4) /
2402 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002403 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002404 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2405 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2406 UDP(sport=1234, dport=1234) /
2407 Raw('\xa5' * 100))
2408
2409 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2410
2411 # the new TEP
2412 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2413 self,
2414 self.pg2.local_ip4,
2415 self.pg2.remote_hosts[1].ip4,
2416 vx_tun_l3.vni)
2417 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2418
2419 self.logger.info(self.vapi.cli("show gbp bridge"))
2420 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2421 self.logger.info(self.vapi.cli("show gbp vxlan"))
2422 self.logger.info(self.vapi.cli("show int addr"))
2423
2424 # endpoint learnt via the TEP
2425 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2426
2427 self.logger.info(self.vapi.cli("show gbp endpoint"))
2428 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2429
2430 #
2431 # Static EP replies to learnt
2432 #
2433 for l in learnt:
2434 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2435 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2436 UDP(sport=1234, dport=1234) /
2437 Raw('\xa5' * 100))
2438
2439 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2440
2441 for rx in rxs:
2442 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2443 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2444 self.assertEqual(rx[UDP].dport, 48879)
2445 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002446 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002447 self.assertEqual(rx[VXLAN].vni, 101)
2448 self.assertTrue(rx[VXLAN].flags.G)
2449 self.assertTrue(rx[VXLAN].flags.Instance)
2450 self.assertTrue(rx[VXLAN].gpflags.A)
2451 self.assertFalse(rx[VXLAN].gpflags.D)
2452
2453 inner = rx[VXLAN].payload
2454
2455 self.assertEqual(inner[Ether].src, routed_src_mac)
2456 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2457 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2458 self.assertEqual(inner[IPv6].dst, l['ip6'])
2459
2460 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002461 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002462 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002463
2464 #
2465 # Static sends to unknown EP with no route
2466 #
2467 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2468 IP(dst="10.0.0.99", src=ep.ip4.address) /
2469 UDP(sport=1234, dport=1234) /
2470 Raw('\xa5' * 100))
2471
2472 self.send_and_assert_no_replies(self.pg0, [p])
2473
2474 #
2475 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002476 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002477 #
2478 se_10_24 = VppGbpSubnet(
2479 self, rd1, "10.0.0.0", 24,
2480 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2481 se_10_24.add_vpp_config()
2482
2483 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2484 IP(dst="10.0.0.99", src=ep.ip4.address) /
2485 UDP(sport=1234, dport=1234) /
2486 Raw('\xa5' * 100))
2487
2488 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2489 for rx in rxs:
2490 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2491 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2492 self.assertEqual(rx[UDP].dport, 48879)
2493 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002494 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002495 self.assertEqual(rx[VXLAN].vni, 114)
2496 self.assertTrue(rx[VXLAN].flags.G)
2497 self.assertTrue(rx[VXLAN].flags.Instance)
2498 # policy is not applied to packets sent to the uu-fwd interfaces
2499 self.assertFalse(rx[VXLAN].gpflags.A)
2500 self.assertFalse(rx[VXLAN].gpflags.D)
2501
2502 #
2503 # learn some remote IPv4 EPs
2504 #
2505 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002506 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002507 # arriving on an unknown TEP
2508 p = (Ether(src=self.pg2.remote_mac,
2509 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002510 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002511 dst=self.pg2.local_ip4) /
2512 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002513 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002514 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2515 IP(src=l['ip'], dst=ep.ip4.address) /
2516 UDP(sport=1234, dport=1234) /
2517 Raw('\xa5' * 100))
2518
2519 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2520
2521 # the new TEP
2522 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2523 self,
2524 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002525 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002526 vx_tun_l3.vni)
2527 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2528
2529 # endpoint learnt via the parent GBP-vxlan interface
2530 self.assertTrue(find_gbp_endpoint(self,
2531 vx_tun_l3._sw_if_index,
2532 ip=l['ip']))
2533
2534 #
2535 # Add a remote endpoint from the API
2536 #
2537 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2538 epg_220, None,
2539 "10.0.0.88", "11.0.0.88",
2540 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002541 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002542 self.pg2.local_ip4,
2543 self.pg2.remote_hosts[1].ip4,
2544 mac=None)
2545 rep_88.add_vpp_config()
2546
2547 #
2548 # Add a remote endpoint from the API that matches an existing one
2549 #
2550 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2551 epg_220, None,
2552 learnt[0]['ip'], "11.0.0.101",
2553 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002554 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002555 self.pg2.local_ip4,
2556 self.pg2.remote_hosts[1].ip4,
2557 mac=None)
2558 rep_2.add_vpp_config()
2559
2560 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002561 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002562 # packets should be send on the v4/v6 uu=fwd interface resp.
2563 #
2564 se_10_1_24 = VppGbpSubnet(
2565 self, rd1, "10.0.1.0", 24,
2566 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2567 se_10_1_24.add_vpp_config()
2568
2569 self.logger.info(self.vapi.cli("show gbp endpoint"))
2570
2571 ips = ["10.0.0.88", learnt[0]['ip']]
2572 for ip in ips:
2573 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2574 IP(dst=ip, src=ep.ip4.address) /
2575 UDP(sport=1234, dport=1234) /
2576 Raw('\xa5' * 100))
2577
2578 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2579
2580 for rx in rxs:
2581 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2582 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2583 self.assertEqual(rx[UDP].dport, 48879)
2584 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002585 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002586 self.assertEqual(rx[VXLAN].vni, 101)
2587 self.assertTrue(rx[VXLAN].flags.G)
2588 self.assertTrue(rx[VXLAN].flags.Instance)
2589 self.assertTrue(rx[VXLAN].gpflags.A)
2590 self.assertFalse(rx[VXLAN].gpflags.D)
2591
2592 inner = rx[VXLAN].payload
2593
2594 self.assertEqual(inner[Ether].src, routed_src_mac)
2595 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2596 self.assertEqual(inner[IP].src, ep.ip4.address)
2597 self.assertEqual(inner[IP].dst, ip)
2598
2599 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002600 # remove the API remote EPs, only API sourced is gone, the DP
2601 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002602 #
2603 rep_88.remove_vpp_config()
2604 rep_2.remove_vpp_config()
2605
Neale Ranns00a469d2018-12-20 06:12:19 -08002606 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2607
2608 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2609 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2610 UDP(sport=1234, dport=1234) /
2611 Raw('\xa5' * 100))
2612 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002613
Neale Ranns13a08cc2018-11-07 09:25:54 -08002614 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002615
Neale Ranns13a08cc2018-11-07 09:25:54 -08002616 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2617 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2618 UDP(sport=1234, dport=1234) /
2619 Raw('\xa5' * 100))
2620 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002621
Neale Ranns13a08cc2018-11-07 09:25:54 -08002622 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002623 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08002624 # present (because it's DP learnt) when the TC ends so wait until
2625 # it is removed
2626 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002627 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2628 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002629
2630 #
2631 # shutdown with learnt endpoint present
2632 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002633 p = (Ether(src=self.pg2.remote_mac,
2634 dst=self.pg2.local_mac) /
2635 IP(src=self.pg2.remote_hosts[1].ip4,
2636 dst=self.pg2.local_ip4) /
2637 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002638 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002639 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2640 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2641 UDP(sport=1234, dport=1234) /
2642 Raw('\xa5' * 100))
2643
2644 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2645
2646 # endpoint learnt via the parent GBP-vxlan interface
2647 self.assertTrue(find_gbp_endpoint(self,
2648 vx_tun_l3._sw_if_index,
2649 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002650
2651 #
2652 # TODO
2653 # remote endpoint becomes local
2654 #
2655 self.pg2.unconfig_ip4()
2656 self.pg3.unconfig_ip4()
2657 self.pg4.unconfig_ip4()
2658
Neale Ranns13a08cc2018-11-07 09:25:54 -08002659 def test_gbp_redirect(self):
2660 """ GBP Endpoint Redirect """
2661
2662 self.vapi.cli("set logging class gbp debug")
2663
Neale Rannsb6a47952018-11-21 05:44:35 -08002664 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002665 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2666 routed_src_mac = "00:22:bd:f8:19:ff"
2667
2668 learnt = [{'mac': '00:00:11:11:11:02',
2669 'ip': '10.0.1.2',
2670 'ip6': '2001:10::2'},
2671 {'mac': '00:00:11:11:11:03',
2672 'ip': '10.0.1.3',
2673 'ip6': '2001:10::3'}]
2674
2675 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002676 # IP tables
2677 #
2678 t4 = VppIpTable(self, 1)
2679 t4.add_vpp_config()
2680 t6 = VppIpTable(self, 1, True)
2681 t6.add_vpp_config()
2682
2683 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2684 rd1.add_vpp_config()
2685
Ole Troan8006c6a2018-12-17 12:02:26 +01002686 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002687
2688 #
2689 # Bind the BVI to the RD
2690 #
2691 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2692 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2693
2694 #
2695 # Pg7 hosts a BD's UU-fwd
2696 #
2697 self.pg7.config_ip4()
2698 self.pg7.resolve_arp()
2699
2700 #
2701 # a GBP bridge domains for the EPs
2702 #
2703 bd1 = VppBridgeDomain(self, 1)
2704 bd1.add_vpp_config()
2705 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2706 gbd1.add_vpp_config()
2707
2708 bd2 = VppBridgeDomain(self, 2)
2709 bd2.add_vpp_config()
2710 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2711 gbd2.add_vpp_config()
2712
2713 # ... and has a /32 and /128 applied
2714 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2715 ip4_addr.add_vpp_config()
2716 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2717 ip6_addr.add_vpp_config()
2718 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2719 ip4_addr.add_vpp_config()
2720 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2721 ip6_addr.add_vpp_config()
2722
2723 #
2724 # The Endpoint-groups in which we are learning endpoints
2725 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002726 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002727 None, gbd1.bvi,
2728 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002729 "2001:10::128",
2730 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002731 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002732 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002733 None, gbd2.bvi,
2734 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002735 "2001:11::128",
2736 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002737 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002738 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002739 None, gbd1.bvi,
2740 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002741 "2001:12::128",
2742 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002743 epg_222.add_vpp_config()
2744
2745 #
2746 # a GBP bridge domains for the SEPs
2747 #
2748 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2749 self.pg7.remote_ip4, 116)
2750 bd_uu1.add_vpp_config()
2751 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2752 self.pg7.remote_ip4, 117)
2753 bd_uu2.add_vpp_config()
2754
2755 bd3 = VppBridgeDomain(self, 3)
2756 bd3.add_vpp_config()
2757 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2758 gbd3.add_vpp_config()
2759 bd4 = VppBridgeDomain(self, 4)
2760 bd4.add_vpp_config()
2761 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2762 gbd4.add_vpp_config()
2763
2764 #
2765 # EPGs in which the service endpoints exist
2766 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002767 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002768 None, gbd1.bvi,
2769 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002770 "4001:10::128",
2771 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002772 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002773 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002774 None, gbd2.bvi,
2775 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002776 "4001:11::128",
2777 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002778 epg_321.add_vpp_config()
2779
2780 #
2781 # three local endpoints
2782 #
2783 ep1 = VppGbpEndpoint(self, self.pg0,
2784 epg_220, None,
2785 "10.0.0.1", "11.0.0.1",
2786 "2001:10::1", "3001:10::1")
2787 ep1.add_vpp_config()
2788 ep2 = VppGbpEndpoint(self, self.pg1,
2789 epg_221, None,
2790 "10.0.1.1", "11.0.1.1",
2791 "2001:11::1", "3001:11::1")
2792 ep2.add_vpp_config()
2793 ep3 = VppGbpEndpoint(self, self.pg2,
2794 epg_222, None,
2795 "10.0.2.2", "11.0.2.2",
2796 "2001:12::1", "3001:12::1")
2797 ep3.add_vpp_config()
2798
2799 #
2800 # service endpoints
2801 #
2802 sep1 = VppGbpEndpoint(self, self.pg3,
2803 epg_320, None,
2804 "12.0.0.1", "13.0.0.1",
2805 "4001:10::1", "5001:10::1")
2806 sep1.add_vpp_config()
2807 sep2 = VppGbpEndpoint(self, self.pg4,
2808 epg_320, None,
2809 "12.0.0.2", "13.0.0.2",
2810 "4001:10::2", "5001:10::2")
2811 sep2.add_vpp_config()
2812 sep3 = VppGbpEndpoint(self, self.pg5,
2813 epg_321, None,
2814 "12.0.1.1", "13.0.1.1",
2815 "4001:11::1", "5001:11::1")
2816 sep3.add_vpp_config()
2817 # this EP is not installed immediately
2818 sep4 = VppGbpEndpoint(self, self.pg6,
2819 epg_321, None,
2820 "12.0.1.2", "13.0.1.2",
2821 "4001:11::2", "5001:11::2")
2822
2823 #
2824 # an L2 switch packet between local EPs in different EPGs
2825 # different dest ports on each so the are LB hashed differently
2826 #
2827 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2828 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2829 UDP(sport=1234, dport=1234) /
2830 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002831 (Ether(src=ep3.mac, dst=ep1.mac) /
2832 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2833 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002834 Raw('\xa5' * 100))]
2835 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2836 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2837 UDP(sport=1234, dport=1234) /
2838 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002839 (Ether(src=ep3.mac, dst=ep1.mac) /
2840 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002841 UDP(sport=1234, dport=1230) /
2842 Raw('\xa5' * 100))]
2843
2844 # should be dropped since no contract yet
2845 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2846 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2847
2848 #
2849 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2850 # one of the next-hops is via an EP that is not known
2851 #
2852 acl = VppGbpAcl(self)
2853 rule4 = acl.create_rule(permit_deny=1, proto=17)
2854 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2855 acl_index = acl.add_vpp_config([rule4, rule6])
2856
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002857 #
2858 # test the src-ip hash mode
2859 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002860 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002861 self, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002862 [VppGbpContractRule(
2863 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002864 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002865 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2866 sep1.ip4, sep1.epg.rd),
2867 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2868 sep2.ip4, sep2.epg.rd)]),
2869 VppGbpContractRule(
2870 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002871 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002872 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2873 sep3.ip6, sep3.epg.rd),
2874 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002875 sep4.ip6, sep4.epg.rd)])],
2876 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002877 c1.add_vpp_config()
2878
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002879 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002880 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002881 [VppGbpContractRule(
2882 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2883 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2884 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2885 sep1.ip4, sep1.epg.rd),
2886 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2887 sep2.ip4, sep2.epg.rd)]),
2888 VppGbpContractRule(
2889 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2890 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2891 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2892 sep3.ip6, sep3.epg.rd),
2893 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002894 sep4.ip6, sep4.epg.rd)])],
2895 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002896 c2.add_vpp_config()
2897
Neale Ranns13a08cc2018-11-07 09:25:54 -08002898 #
2899 # send again with the contract preset, now packets arrive
2900 # at SEP1 or SEP2 depending on the hashing
2901 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002902 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002903
2904 for rx in rxs:
2905 self.assertEqual(rx[Ether].src, routed_src_mac)
2906 self.assertEqual(rx[Ether].dst, sep1.mac)
2907 self.assertEqual(rx[IP].src, ep1.ip4.address)
2908 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2909
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002910 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2911
2912 for rx in rxs:
2913 self.assertEqual(rx[Ether].src, routed_src_mac)
2914 self.assertEqual(rx[Ether].dst, sep2.mac)
2915 self.assertEqual(rx[IP].src, ep3.ip4.address)
2916 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2917
Neale Ranns13a08cc2018-11-07 09:25:54 -08002918 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2919
2920 for rx in rxs:
2921 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2922 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2923 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2924 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2925 self.assertEqual(rx[VXLAN].vni, 117)
2926 self.assertTrue(rx[VXLAN].flags.G)
2927 self.assertTrue(rx[VXLAN].flags.Instance)
2928 # redirect policy has been applied
2929 self.assertTrue(rx[VXLAN].gpflags.A)
2930 self.assertFalse(rx[VXLAN].gpflags.D)
2931
2932 inner = rx[VXLAN].payload
2933
2934 self.assertEqual(inner[Ether].src, routed_src_mac)
2935 self.assertEqual(inner[Ether].dst, sep4.mac)
2936 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2937 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2938
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002939 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002940
2941 for rx in rxs:
2942 self.assertEqual(rx[Ether].src, routed_src_mac)
2943 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002944 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2945 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002946
2947 #
2948 # programme the unknown EP
2949 #
2950 sep4.add_vpp_config()
2951
2952 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2953
2954 for rx in rxs:
2955 self.assertEqual(rx[Ether].src, routed_src_mac)
2956 self.assertEqual(rx[Ether].dst, sep4.mac)
2957 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2958 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2959
2960 #
2961 # and revert back to unprogrammed
2962 #
2963 sep4.remove_vpp_config()
2964
2965 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2966
2967 for rx in rxs:
2968 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2969 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2970 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2971 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2972 self.assertEqual(rx[VXLAN].vni, 117)
2973 self.assertTrue(rx[VXLAN].flags.G)
2974 self.assertTrue(rx[VXLAN].flags.Instance)
2975 # redirect policy has been applied
2976 self.assertTrue(rx[VXLAN].gpflags.A)
2977 self.assertFalse(rx[VXLAN].gpflags.D)
2978
2979 inner = rx[VXLAN].payload
2980
2981 self.assertEqual(inner[Ether].src, routed_src_mac)
2982 self.assertEqual(inner[Ether].dst, sep4.mac)
2983 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2984 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2985
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002986 c1.remove_vpp_config()
2987 c2.remove_vpp_config()
2988
2989 #
2990 # test the symmetric hash mode
2991 #
2992 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002993 self, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002994 [VppGbpContractRule(
2995 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2996 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2997 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2998 sep1.ip4, sep1.epg.rd),
2999 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3000 sep2.ip4, sep2.epg.rd)]),
3001 VppGbpContractRule(
3002 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3003 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3004 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3005 sep3.ip6, sep3.epg.rd),
3006 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003007 sep4.ip6, sep4.epg.rd)])],
3008 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003009 c1.add_vpp_config()
3010
3011 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003012 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003013 [VppGbpContractRule(
3014 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3015 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3016 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3017 sep1.ip4, sep1.epg.rd),
3018 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3019 sep2.ip4, sep2.epg.rd)]),
3020 VppGbpContractRule(
3021 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3022 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3023 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3024 sep3.ip6, sep3.epg.rd),
3025 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003026 sep4.ip6, sep4.epg.rd)])],
3027 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003028 c2.add_vpp_config()
3029
3030 #
3031 # send again with the contract preset, now packets arrive
3032 # at SEP1 for both directions
3033 #
3034 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3035
3036 for rx in rxs:
3037 self.assertEqual(rx[Ether].src, routed_src_mac)
3038 self.assertEqual(rx[Ether].dst, sep1.mac)
3039 self.assertEqual(rx[IP].src, ep1.ip4.address)
3040 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3041
3042 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3043
3044 for rx in rxs:
3045 self.assertEqual(rx[Ether].src, routed_src_mac)
3046 self.assertEqual(rx[Ether].dst, sep1.mac)
3047 self.assertEqual(rx[IP].src, ep3.ip4.address)
3048 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3049
Neale Ranns13a08cc2018-11-07 09:25:54 -08003050 #
3051 # programme the unknown EP for the L3 tests
3052 #
3053 sep4.add_vpp_config()
3054
3055 #
3056 # an L3 switch packet between local EPs in different EPGs
3057 # different dest ports on each so the are LB hashed differently
3058 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003059 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003060 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3061 UDP(sport=1234, dport=1234) /
3062 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003063 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003064 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3065 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003066 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003067 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003068 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3069 UDP(sport=1234, dport=1234) /
3070 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003071 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003072 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3073 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003074 Raw('\xa5' * 100))]
3075
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003076 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003077 self, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003078 [VppGbpContractRule(
3079 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3080 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3081 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3082 sep1.ip4, sep1.epg.rd),
3083 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3084 sep2.ip4, sep2.epg.rd)]),
3085 VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08003086 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003087 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003088 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3089 sep3.ip6, sep3.epg.rd),
3090 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3091 sep4.ip6, sep4.epg.rd)])],
3092 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003093 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003094
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003095 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003096
3097 for rx in rxs:
3098 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003099 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003100 self.assertEqual(rx[IP].src, ep1.ip4.address)
3101 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3102
3103 #
3104 # learn a remote EP in EPG 221
3105 #
3106 vx_tun_l3 = VppGbpVxlanTunnel(
3107 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003108 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3109 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003110 vx_tun_l3.add_vpp_config()
3111
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003112 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003113 self, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003114 [VppGbpContractRule(
3115 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3116 []),
3117 VppGbpContractRule(
3118 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003119 [])],
3120 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003121 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003122
3123 p = (Ether(src=self.pg7.remote_mac,
3124 dst=self.pg7.local_mac) /
3125 IP(src=self.pg7.remote_ip4,
3126 dst=self.pg7.local_ip4) /
3127 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003128 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003129 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003130 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3131 UDP(sport=1234, dport=1234) /
3132 Raw('\xa5' * 100))
3133
3134 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3135
3136 # endpoint learnt via the parent GBP-vxlan interface
3137 self.assertTrue(find_gbp_endpoint(self,
3138 vx_tun_l3._sw_if_index,
3139 ip="10.0.0.88"))
3140
3141 p = (Ether(src=self.pg7.remote_mac,
3142 dst=self.pg7.local_mac) /
3143 IP(src=self.pg7.remote_ip4,
3144 dst=self.pg7.local_ip4) /
3145 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003146 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003147 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003148 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3149 UDP(sport=1234, dport=1234) /
3150 Raw('\xa5' * 100))
3151
3152 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3153
3154 # endpoint learnt via the parent GBP-vxlan interface
3155 self.assertTrue(find_gbp_endpoint(self,
3156 vx_tun_l3._sw_if_index,
3157 ip="2001:10::88"))
3158
3159 #
3160 # L3 switch from local to remote EP
3161 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003162 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003163 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3164 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003165 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003166 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003167 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3168 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003169 Raw('\xa5' * 100))]
3170
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003171 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003172
3173 for rx in rxs:
3174 self.assertEqual(rx[Ether].src, routed_src_mac)
3175 self.assertEqual(rx[Ether].dst, sep1.mac)
3176 self.assertEqual(rx[IP].src, ep1.ip4.address)
3177 self.assertEqual(rx[IP].dst, "10.0.0.88")
3178
3179 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3180
3181 for rx in rxs:
3182 self.assertEqual(rx[Ether].src, routed_src_mac)
3183 self.assertEqual(rx[Ether].dst, sep4.mac)
3184 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3185 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3186
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003187 #
3188 # test the dst-ip hash mode
3189 #
3190 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003191 self, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003192 [VppGbpContractRule(
3193 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3194 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3195 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3196 sep1.ip4, sep1.epg.rd),
3197 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3198 sep2.ip4, sep2.epg.rd)]),
3199 VppGbpContractRule(
3200 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3201 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3202 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3203 sep3.ip6, sep3.epg.rd),
3204 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003205 sep4.ip6, sep4.epg.rd)])],
3206 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003207 c5.add_vpp_config()
3208
3209 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3210
3211 for rx in rxs:
3212 self.assertEqual(rx[Ether].src, routed_src_mac)
3213 self.assertEqual(rx[Ether].dst, sep1.mac)
3214 self.assertEqual(rx[IP].src, ep1.ip4.address)
3215 self.assertEqual(rx[IP].dst, "10.0.0.88")
3216
3217 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003218
3219 for rx in rxs:
3220 self.assertEqual(rx[Ether].src, routed_src_mac)
3221 self.assertEqual(rx[Ether].dst, sep3.mac)
3222 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3223 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3224
Neale Rannsb6a47952018-11-21 05:44:35 -08003225 #
3226 # cleanup
3227 #
3228 self.pg7.unconfig_ip4()
3229
3230 def test_gbp_l3_out(self):
3231 """ GBP L3 Out """
3232
3233 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3234 self.vapi.cli("set logging class gbp debug")
3235
3236 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3237 routed_src_mac = "00:22:bd:f8:19:ff"
3238
3239 #
3240 # IP tables
3241 #
3242 t4 = VppIpTable(self, 1)
3243 t4.add_vpp_config()
3244 t6 = VppIpTable(self, 1, True)
3245 t6.add_vpp_config()
3246
3247 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3248 rd1.add_vpp_config()
3249
Ole Troan8006c6a2018-12-17 12:02:26 +01003250 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003251
3252 #
3253 # Bind the BVI to the RD
3254 #
3255 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3256 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3257
3258 #
3259 # Pg7 hosts a BD's BUM
3260 # Pg1 some other l3 interface
3261 #
3262 self.pg7.config_ip4()
3263 self.pg7.resolve_arp()
3264
3265 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003266 # a multicast vxlan-gbp tunnel for broadcast in the BD
3267 #
3268 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3269 "239.1.1.1", 88,
3270 mcast_itf=self.pg7)
3271 tun_bm.add_vpp_config()
3272
3273 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003274 # a GBP external bridge domains for the EPs
3275 #
3276 bd1 = VppBridgeDomain(self, 1)
3277 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003278 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003279 gbd1.add_vpp_config()
3280
3281 #
3282 # The Endpoint-groups in which the external endpoints exist
3283 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003284 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003285 None, gbd1.bvi,
3286 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003287 "2001:10::128",
3288 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003289 epg_220.add_vpp_config()
3290
3291 # the BVIs have the subnets applied ...
3292 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3293 ip4_addr.add_vpp_config()
3294 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3295 ip6_addr.add_vpp_config()
3296
3297 # ... which are L3-out subnets
3298 l3o_1 = VppGbpSubnet(
3299 self, rd1, "10.0.0.0", 24,
3300 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003301 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003302 l3o_1.add_vpp_config()
3303
3304 #
3305 # an external interface attached to the outside world and the
3306 # external BD
3307 #
3308 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3309 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003310 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3311 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3312 vlan_101.admin_up()
3313 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3314
3315 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003316 ext_itf.add_vpp_config()
3317
3318 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003319 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003320 #
3321 vx_tun_l3 = VppGbpVxlanTunnel(
3322 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003323 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3324 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003325 vx_tun_l3.add_vpp_config()
3326
3327 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003328 # External Endpoints
3329 #
3330 eep1 = VppGbpEndpoint(self, vlan_100,
3331 epg_220, None,
3332 "10.0.0.1", "11.0.0.1",
3333 "2001:10::1", "3001::1",
3334 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3335 eep1.add_vpp_config()
3336 eep2 = VppGbpEndpoint(self, vlan_101,
3337 epg_220, None,
3338 "10.0.0.2", "11.0.0.2",
3339 "2001:10::2", "3001::2",
3340 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3341 eep2.add_vpp_config()
3342
3343 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003344 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003345 #
3346 rep = VppGbpEndpoint(self, vx_tun_l3,
3347 epg_220, None,
3348 "10.0.0.101", "11.0.0.101",
3349 "2001:10::101", "3001::101",
3350 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3351 self.pg7.local_ip4,
3352 self.pg7.remote_ip4,
3353 mac=None)
3354 rep.add_vpp_config()
3355
3356 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003357 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003358 #
3359 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3360 Dot1Q(vlan=100) /
3361 ARP(op="who-has",
3362 psrc=eep1.ip4.address, pdst="10.0.0.128",
3363 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3364 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3365
3366 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003367 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003368 # are ARP'd for
3369 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003370 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003371 Dot1Q(vlan=100) /
3372 IP(src="10.0.0.1", dst="10.0.0.88") /
3373 UDP(sport=1234, dport=1234) /
3374 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003375 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003376 Dot1Q(vlan=100) /
3377 IPv6(src="2001:10::1", dst="2001:10::88") /
3378 UDP(sport=1234, dport=1234) /
3379 Raw('\xa5' * 100))
3380
3381 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3382
3383 for rx in rxs:
3384 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3385 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3386 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3387 self.assertEqual(rx[IP].dst, "239.1.1.1")
3388 self.assertEqual(rx[VXLAN].vni, 88)
3389 self.assertTrue(rx[VXLAN].flags.G)
3390 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003391 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003392 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003393 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003394 self.assertFalse(rx[VXLAN].gpflags.D)
3395
3396 inner = rx[VXLAN].payload
3397
3398 self.assertTrue(inner.haslayer(ARP))
3399
3400 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003401 # remote to external
3402 #
3403 p = (Ether(src=self.pg7.remote_mac,
3404 dst=self.pg7.local_mac) /
3405 IP(src=self.pg7.remote_ip4,
3406 dst=self.pg7.local_ip4) /
3407 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003408 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003409 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003410 IP(src="10.0.0.101", dst="10.0.0.1") /
3411 UDP(sport=1234, dport=1234) /
3412 Raw('\xa5' * 100))
3413
3414 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3415
3416 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003417 # local EP pings router
3418 #
3419 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3420 Dot1Q(vlan=100) /
3421 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3422 ICMP(type='echo-request'))
3423
3424 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3425
3426 for rx in rxs:
3427 self.assertEqual(rx[Ether].src, str(self.router_mac))
3428 self.assertEqual(rx[Ether].dst, eep1.mac)
3429 self.assertEqual(rx[Dot1Q].vlan, 100)
3430
3431 #
3432 # local EP pings other local EP
3433 #
3434 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3435 Dot1Q(vlan=100) /
3436 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3437 ICMP(type='echo-request'))
3438
3439 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3440
3441 for rx in rxs:
3442 self.assertEqual(rx[Ether].src, eep1.mac)
3443 self.assertEqual(rx[Ether].dst, eep2.mac)
3444 self.assertEqual(rx[Dot1Q].vlan, 101)
3445
3446 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003447 # A subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08003448 #
3449 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003450 [VppRoutePath(eep1.ip4.address,
3451 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003452 table_id=t4.table_id)
3453 ip_220.add_vpp_config()
3454
3455 l3o_220 = VppGbpSubnet(
3456 self, rd1, "10.220.0.0", 24,
3457 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003458 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003459 l3o_220.add_vpp_config()
3460
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003461 #
3462 # A subnet reachable through the external EP2
3463 #
3464 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3465 [VppRoutePath(eep2.ip4.address,
3466 eep2.epg.bvi.sw_if_index)],
3467 table_id=t4.table_id)
3468 ip_221.add_vpp_config()
3469
3470 l3o_221 = VppGbpSubnet(
3471 self, rd1, "10.221.0.0", 24,
3472 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3473 sclass=4221)
3474 l3o_221.add_vpp_config()
3475
3476 #
3477 # ping between hosts in remote subnets
3478 # dropped without a contract
3479 #
3480 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3481 Dot1Q(vlan=100) /
3482 IP(src="10.220.0.1", dst="10.221.0.1") /
3483 ICMP(type='echo-request'))
3484
3485 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3486
3487 #
3488 # contract for the external nets to communicate
3489 #
3490 acl = VppGbpAcl(self)
3491 rule4 = acl.create_rule(permit_deny=1, proto=17)
3492 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3493 acl_index = acl.add_vpp_config([rule4, rule6])
3494
3495 c1 = VppGbpContract(
3496 self, 4220, 4221, acl_index,
3497 [VppGbpContractRule(
3498 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3499 []),
3500 VppGbpContractRule(
3501 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3502 [])],
3503 [ETH_P_IP, ETH_P_IPV6])
3504 c1.add_vpp_config()
3505
3506 #
3507 # Contracts allowing ext-net 200 to talk with external EPs
3508 #
3509 c2 = VppGbpContract(
3510 self, 4220, 113, acl_index,
3511 [VppGbpContractRule(
3512 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3513 []),
3514 VppGbpContractRule(
3515 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3516 [])],
3517 [ETH_P_IP, ETH_P_IPV6])
3518 c2.add_vpp_config()
3519 c3 = VppGbpContract(
3520 self, 113, 4220, acl_index,
3521 [VppGbpContractRule(
3522 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3523 []),
3524 VppGbpContractRule(
3525 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3526 [])],
3527 [ETH_P_IP, ETH_P_IPV6])
3528 c3.add_vpp_config()
3529
3530 #
3531 # ping between hosts in remote subnets
3532 #
3533 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3534 Dot1Q(vlan=100) /
3535 IP(src="10.220.0.1", dst="10.221.0.1") /
3536 UDP(sport=1234, dport=1234) /
3537 Raw('\xa5' * 100))
3538
3539 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3540
3541 for rx in rxs:
3542 self.assertEqual(rx[Ether].src, str(self.router_mac))
3543 self.assertEqual(rx[Ether].dst, eep2.mac)
3544 self.assertEqual(rx[Dot1Q].vlan, 101)
3545
3546 # we did not learn these external hosts
3547 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
3548 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
3549
3550 #
3551 # from remote external EP to local external EP
3552 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003553 p = (Ether(src=self.pg7.remote_mac,
3554 dst=self.pg7.local_mac) /
3555 IP(src=self.pg7.remote_ip4,
3556 dst=self.pg7.local_ip4) /
3557 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003558 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003559 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003560 IP(src="10.0.0.101", dst="10.220.0.1") /
3561 UDP(sport=1234, dport=1234) /
3562 Raw('\xa5' * 100))
3563
3564 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3565
3566 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003567 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07003568 #
3569 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3570 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003571 IP(src="10.220.0.1", dst=rep.ip4.address) /
3572 UDP(sport=1234, dport=1234) /
3573 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003574
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003575 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07003576
3577 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003578 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3579 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3580 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3581 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3582 self.assertEqual(rx[VXLAN].vni, 444)
3583 self.assertTrue(rx[VXLAN].flags.G)
3584 self.assertTrue(rx[VXLAN].flags.Instance)
3585 # the sclass of the ext-net the packet came from
3586 self.assertEqual(rx[VXLAN].gpid, 4220)
3587 # policy was applied to the original IP packet
3588 self.assertTrue(rx[VXLAN].gpflags.A)
3589 # since it's an external host the reciever should not learn it
3590 self.assertTrue(rx[VXLAN].gpflags.D)
3591 inner = rx[VXLAN].payload
3592 self.assertEqual(inner[IP].src, "10.220.0.1")
3593 self.assertEqual(inner[IP].dst, rep.ip4.address)
3594
3595 #
3596 # An external subnet reachable via the remote external EP
3597 #
3598
3599 #
3600 # first the VXLAN-GBP tunnel over which it is reached
3601 #
3602 vx_tun_r = VppVxlanGbpTunnel(
3603 self, self.pg7.local_ip4,
3604 self.pg7.remote_ip4, 445,
3605 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
3606 VXLAN_GBP_API_TUNNEL_MODE_L3))
3607 vx_tun_r.add_vpp_config()
3608 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
3609
3610 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
3611
3612 #
3613 # then the special adj to resolve through on that tunnel
3614 #
3615 n1 = VppNeighbor(self,
3616 vx_tun_r.sw_if_index,
3617 "00:0c:0c:0c:0c:0c",
3618 self.pg7.remote_ip4)
3619 n1.add_vpp_config()
3620
3621 #
3622 # the route via the adj above
3623 #
3624 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
3625 [VppRoutePath(self.pg7.remote_ip4,
3626 vx_tun_r.sw_if_index)],
3627 table_id=t4.table_id)
3628 ip_222.add_vpp_config()
3629
3630 l3o_222 = VppGbpSubnet(
3631 self, rd1, "10.222.0.0", 24,
3632 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3633 sclass=4222)
3634 l3o_222.add_vpp_config()
3635
3636 #
3637 # ping between hosts in local and remote external subnets
3638 # dropped without a contract
3639 #
3640 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3641 Dot1Q(vlan=100) /
3642 IP(src="10.220.0.1", dst="10.222.0.1") /
3643 UDP(sport=1234, dport=1234) /
3644 Raw('\xa5' * 100))
3645
3646 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3647
3648 #
3649 # Add contracts ext-nets for 220 -> 222
3650 #
3651 c4 = VppGbpContract(
3652 self, 4220, 4222, acl_index,
3653 [VppGbpContractRule(
3654 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3655 []),
3656 VppGbpContractRule(
3657 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3658 [])],
3659 [ETH_P_IP, ETH_P_IPV6])
3660 c4.add_vpp_config()
3661
3662 #
3663 # ping from host in local to remote external subnets
3664 #
3665 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3666 Dot1Q(vlan=100) /
3667 IP(src="10.220.0.1", dst="10.222.0.1") /
3668 UDP(sport=1234, dport=1234) /
3669 Raw('\xa5' * 100))
3670
3671 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
3672
3673 for rx in rxs:
3674 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3675 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3676 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3677 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3678 self.assertEqual(rx[VXLAN].vni, 445)
3679 self.assertTrue(rx[VXLAN].flags.G)
3680 self.assertTrue(rx[VXLAN].flags.Instance)
3681 # the sclass of the ext-net the packet came from
3682 self.assertEqual(rx[VXLAN].gpid, 4220)
3683 # policy was applied to the original IP packet
3684 self.assertTrue(rx[VXLAN].gpflags.A)
3685 # since it's an external host the reciever should not learn it
3686 self.assertTrue(rx[VXLAN].gpflags.D)
3687 inner = rx[VXLAN].payload
3688 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
3689 self.assertEqual(inner[IP].src, "10.220.0.1")
3690 self.assertEqual(inner[IP].dst, "10.222.0.1")
3691
3692 #
3693 # ping from host in remote to local external subnets
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02003694 # there's no contract for this, but sclass is 1.
3695 #
3696 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3697 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3698 UDP(sport=1234, dport=48879) /
3699 VXLAN(vni=445, gpid=1, flags=0x88) /
3700 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3701 IP(src="10.222.0.1", dst="10.220.0.1") /
3702 UDP(sport=1234, dport=1234) /
3703 Raw('\xa5' * 100))
3704
3705 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3706 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
3707
3708 #
3709 # ping from host in remote to local external subnets
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003710 # there's no contract for this, but the A bit is set.
3711 #
3712 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3713 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3714 UDP(sport=1234, dport=48879) /
3715 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3716 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3717 IP(src="10.222.0.1", dst="10.220.0.1") /
3718 UDP(sport=1234, dport=1234) /
3719 Raw('\xa5' * 100))
3720
3721 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3722 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07003723
3724 #
Neale Ranns2b600182019-03-29 05:08:27 -07003725 # ping from host in remote to remote external subnets
3726 # this is dropped by reflection check.
3727 #
3728 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3729 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3730 UDP(sport=1234, dport=48879) /
3731 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3732 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3733 IP(src="10.222.0.1", dst="10.222.0.2") /
3734 UDP(sport=1234, dport=1234) /
3735 Raw('\xa5' * 100))
3736
3737 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
3738
3739 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003740 # cleanup
3741 #
3742 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003743 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003744
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003745
3746if __name__ == '__main__':
3747 unittest.main(testRunner=VppTestRunner)