blob: 2e6dca5b2b1f5cf8ec8d2fe16781ca3c2b4eaeb7 [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
Filip Vargaf4749ca2019-04-25 14:55:32 +02009from 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 """
Filip Vargaf4749ca2019-04-25 14:55:32 +0200223
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700224 def __init__(self, test, rd, address, address_len,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700225 type, sw_if_index=None, sclass=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700226 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700227 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200228 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700229 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700230 self.sw_if_index = sw_if_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700231 self.sclass = sclass
Neale Ranns25b04942018-04-04 09:34:50 -0700232
233 def add_vpp_config(self):
234 self._test.vapi.gbp_subnet_add_del(
235 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700236 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200237 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700238 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700239 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700240 sclass=self.sclass if self.sclass else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700241 self._test.registry.register(self, self._test.logger)
242
243 def remove_vpp_config(self):
244 self._test.vapi.gbp_subnet_add_del(
245 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700246 self.rd_id,
247 self.prefix.encode(),
248 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700249
Neale Ranns25b04942018-04-04 09:34:50 -0700250 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700251 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700252
253 def query_vpp_config(self):
254 ss = self._test.vapi.gbp_subnet_dump()
255 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700256 if s.subnet.rd_id == self.rd_id and \
Filip Vargaf4749ca2019-04-25 14:55:32 +0200257 s.subnet.type == self.type and \
258 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700259 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700260 return False
261
262
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800263class VppGbpEndpointRetention(object):
264 def __init__(self, remote_ep_timeout=0xffffffff):
265 self.remote_ep_timeout = remote_ep_timeout
266
267 def encode(self):
268 return {'remote_ep_timeout': self.remote_ep_timeout}
269
270
Neale Ranns25b04942018-04-04 09:34:50 -0700271class VppGbpEndpointGroup(VppObject):
272 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200273 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700274 """
275
Neale Ranns4ba67722019-02-28 11:11:39 +0000276 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800277 bvi, bvi_ip4, bvi_ip6=None,
278 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700279 self._test = test
280 self.uplink = uplink
281 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700282 self.bvi_ip4 = VppIpAddress(bvi_ip4)
283 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000284 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700285 self.bd = bd
286 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800287 self.sclass = sclass
288 if 0 == self.sclass:
289 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800290 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700291
292 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700293 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000294 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800295 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700296 self.bd.bd.bd_id,
297 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800298 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
299 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700300 self._test.registry.register(self, self._test.logger)
301
302 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000303 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700304
Neale Ranns25b04942018-04-04 09:34:50 -0700305 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000306 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700307
308 def query_vpp_config(self):
309 epgs = self._test.vapi.gbp_endpoint_group_dump()
310 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000311 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800312 return True
313 return False
314
315
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700316class VppGbpBridgeDomain(VppObject):
317 """
318 GBP Bridge Domain
319 """
320
Neale Ranns879d11c2019-01-21 23:34:18 -0800321 def __init__(self, test, bd, bvi, uu_fwd=None,
Mohsin Kazmi8ea109e2019-03-22 15:13:31 +0100322 bm_flood=None, learn=True, uu_drop=False, bm_drop=False):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700323 self._test = test
324 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800325 self.uu_fwd = uu_fwd
326 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700327 self.bd = bd
328
Neale Rannsc29c0af2018-11-07 04:21:12 -0800329 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
330 if (learn):
331 self.learn = e.GBP_BD_API_FLAG_NONE
332 else:
333 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
Mohsin Kazmi8ea109e2019-03-22 15:13:31 +0100334 if (uu_drop):
335 self.learn |= e.GBP_BD_API_FLAG_UU_FWD_DROP
336 if (bm_drop):
337 self.learn |= e.GBP_BD_API_FLAG_MCAST_DROP
Neale Rannsc29c0af2018-11-07 04:21:12 -0800338
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700339 def add_vpp_config(self):
340 self._test.vapi.gbp_bridge_domain_add(
341 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800342 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700343 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800344 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
345 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700346 self._test.registry.register(self, self._test.logger)
347
348 def remove_vpp_config(self):
349 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
350
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700351 def object_id(self):
352 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
353
354 def query_vpp_config(self):
355 bds = self._test.vapi.gbp_bridge_domain_dump()
356 for bd in bds:
357 if bd.bd.bd_id == self.bd.bd_id:
358 return True
359 return False
360
361
362class VppGbpRouteDomain(VppObject):
363 """
364 GBP Route Domain
365 """
366
367 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
368 self._test = test
369 self.rd_id = rd_id
370 self.t4 = t4
371 self.t6 = t6
372 self.ip4_uu = ip4_uu
373 self.ip6_uu = ip6_uu
374
375 def add_vpp_config(self):
376 self._test.vapi.gbp_route_domain_add(
377 self.rd_id,
378 self.t4.table_id,
379 self.t6.table_id,
380 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
381 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
382 self._test.registry.register(self, self._test.logger)
383
384 def remove_vpp_config(self):
385 self._test.vapi.gbp_route_domain_del(self.rd_id)
386
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700387 def object_id(self):
388 return "gbp-route-domain:[%d]" % (self.rd_id)
389
390 def query_vpp_config(self):
391 rds = self._test.vapi.gbp_route_domain_dump()
392 for rd in rds:
393 if rd.rd.rd_id == self.rd_id:
394 return True
395 return False
396
397
Neale Ranns13a08cc2018-11-07 09:25:54 -0800398class VppGbpContractNextHop():
399 def __init__(self, mac, bd, ip, rd):
400 self.mac = mac
401 self.ip = ip
402 self.bd = bd
403 self.rd = rd
404
405 def encode(self):
406 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100407 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800408 'bd_id': self.bd.bd.bd_id,
409 'rd_id': self.rd.rd_id}
410
411
412class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100413 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800414 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100415 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800416 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800417
418 def encode(self):
419 nhs = []
420 for nh in self.nhs:
421 nhs.append(nh.encode())
422 while len(nhs) < 8:
423 nhs.append({})
424 return {'action': self.action,
425 'nh_set': {
426 'hash_mode': self.hash_mode,
427 'n_nhs': len(self.nhs),
428 'nhs': nhs}}
429
430
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800431class VppGbpContract(VppObject):
432 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200433 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800434 """
435
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700436 def __init__(self, test, sclass, dclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800437 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800438 self._test = test
439 self.acl_index = acl_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700440 self.sclass = sclass
441 self.dclass = dclass
Neale Ranns13a08cc2018-11-07 09:25:54 -0800442 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800443 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700444 while (len(self.allowed_ethertypes) < 16):
445 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800446
447 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800448 rules = []
449 for r in self.rules:
450 rules.append(r.encode())
Neale Ranns796c84b2019-03-28 07:56:23 -0700451 r = self._test.vapi.gbp_contract_add_del(
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800452 1,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700453 self.sclass,
454 self.dclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800455 self.acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800456 rules,
457 self.allowed_ethertypes)
Neale Ranns796c84b2019-03-28 07:56:23 -0700458 self.stats_index = r.stats_index
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800459 self._test.registry.register(self, self._test.logger)
460
461 def remove_vpp_config(self):
462 self._test.vapi.gbp_contract_add_del(
463 0,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700464 self.sclass,
465 self.dclass,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800466 self.acl_index,
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700467 [],
468 self.allowed_ethertypes)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800469
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800470 def object_id(self):
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700471 return "gbp-contract:[%d:%s:%d]" % (self.sclass,
472 self.dclass,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800473 self.acl_index)
474
475 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700476 cs = self._test.vapi.gbp_contract_dump()
477 for c in cs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700478 if c.contract.sclass == self.sclass \
Filip Vargaf4749ca2019-04-25 14:55:32 +0200479 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800480 return True
481 return False
482
Neale Ranns796c84b2019-03-28 07:56:23 -0700483 def get_drop_stats(self):
484 c = self._test.statistics.get_counter("/net/gbp/contract/drop")
485 return c[0][self.stats_index]
486
487 def get_permit_stats(self):
488 c = self._test.statistics.get_counter("/net/gbp/contract/permit")
489 return c[0][self.stats_index]
490
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800491
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700492class VppGbpVxlanTunnel(VppInterface):
493 """
494 GBP VXLAN tunnel
495 """
496
Neale Ranns8da9fc62019-03-04 14:08:11 -0800497 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700498 super(VppGbpVxlanTunnel, self).__init__(test)
499 self._test = test
500 self.vni = vni
501 self.bd_rd_id = bd_rd_id
502 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800503 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700504
505 def add_vpp_config(self):
506 r = self._test.vapi.gbp_vxlan_tunnel_add(
507 self.vni,
508 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800509 self.mode,
510 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700511 self.set_sw_if_index(r.sw_if_index)
512 self._test.registry.register(self, self._test.logger)
513
514 def remove_vpp_config(self):
515 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
516
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700517 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800518 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700519
520 def query_vpp_config(self):
521 return find_gbp_vxlan(self._test, self.vni)
522
523
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200524class VppGbpAcl(VppObject):
525 """
526 GBP Acl
527 """
528
529 def __init__(self, test):
530 self._test = test
531 self.acl_index = 4294967295
532
533 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800534 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
535 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200536 dport_from=0, dport_to=65535):
537 if proto == -1 or proto == 0:
538 sport_to = 0
539 dport_to = sport_to
540 elif proto == 1 or proto == 58:
541 sport_to = 255
542 dport_to = sport_to
543 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
544 'srcport_or_icmptype_first': sport_from,
545 'srcport_or_icmptype_last': sport_to,
546 'src_ip_prefix_len': s_prefix,
547 'src_ip_addr': s_ip,
548 'dstport_or_icmpcode_first': dport_from,
549 'dstport_or_icmpcode_last': dport_to,
550 'dst_ip_prefix_len': d_prefix,
551 'dst_ip_addr': d_ip})
552 return rule
553
554 def add_vpp_config(self, rules):
555
556 reply = self._test.vapi.acl_add_replace(self.acl_index,
557 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800558 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200559 self.acl_index = reply.acl_index
560 return self.acl_index
561
562 def remove_vpp_config(self):
563 self._test.vapi.acl_del(self.acl_index)
564
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200565 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700566 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200567
568 def query_vpp_config(self):
569 cs = self._test.vapi.acl_dump()
570 for c in cs:
571 if c.acl_index == self.acl_index:
572 return True
573 return False
574
575
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800576class TestGBP(VppTestCase):
577 """ GBP Test Case """
578
Filip Vargadd1e3e72019-04-15 18:52:43 +0200579 @property
580 def config_flags(self):
581 return VppEnum.vl_api_nat_config_flags_t
582
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700583 @classmethod
584 def setUpClass(cls):
585 super(TestGBP, cls).setUpClass()
586
587 @classmethod
588 def tearDownClass(cls):
589 super(TestGBP, cls).tearDownClass()
590
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800591 def setUp(self):
592 super(TestGBP, self).setUp()
593
Neale Ranns25b04942018-04-04 09:34:50 -0700594 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700595 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700596
Ole Troan8006c6a2018-12-17 12:02:26 +0100597 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800598
599 for i in self.pg_interfaces:
600 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700601 for i in self.lo_interfaces:
602 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800603
604 def tearDown(self):
605 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700606 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800607
608 super(TestGBP, self).tearDown()
609
Neale Ranns25b04942018-04-04 09:34:50 -0700610 def send_and_expect_bridged(self, src, tx, dst):
611 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800612
Neale Ranns25b04942018-04-04 09:34:50 -0700613 for r in rx:
614 self.assertEqual(r[Ether].src, tx[0][Ether].src)
615 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
616 self.assertEqual(r[IP].src, tx[0][IP].src)
617 self.assertEqual(r[IP].dst, tx[0][IP].dst)
618 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800619
Neale Ranns25b04942018-04-04 09:34:50 -0700620 def send_and_expect_bridged6(self, src, tx, dst):
621 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800622
Neale Ranns25b04942018-04-04 09:34:50 -0700623 for r in rx:
624 self.assertEqual(r[Ether].src, tx[0][Ether].src)
625 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
626 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
627 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
628 return rx
629
630 def send_and_expect_routed(self, src, tx, dst, src_mac):
631 rx = self.send_and_expect(src, tx, dst)
632
633 for r in rx:
634 self.assertEqual(r[Ether].src, src_mac)
635 self.assertEqual(r[Ether].dst, dst.remote_mac)
636 self.assertEqual(r[IP].src, tx[0][IP].src)
637 self.assertEqual(r[IP].dst, tx[0][IP].dst)
638 return rx
639
640 def send_and_expect_natted(self, src, tx, dst, src_ip):
641 rx = self.send_and_expect(src, tx, dst)
642
643 for r in rx:
644 self.assertEqual(r[Ether].src, tx[0][Ether].src)
645 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
646 self.assertEqual(r[IP].src, src_ip)
647 self.assertEqual(r[IP].dst, tx[0][IP].dst)
648 return rx
649
Neale Ranns4a6d0232018-04-24 07:45:33 -0700650 def send_and_expect_natted6(self, src, tx, dst, src_ip):
651 rx = self.send_and_expect(src, tx, dst)
652
653 for r in rx:
654 self.assertEqual(r[Ether].src, tx[0][Ether].src)
655 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
656 self.assertEqual(r[IPv6].src, src_ip)
657 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
658 return rx
659
Neale Ranns25b04942018-04-04 09:34:50 -0700660 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
661 rx = self.send_and_expect(src, tx, dst)
662
663 for r in rx:
664 self.assertEqual(r[Ether].src, tx[0][Ether].src)
665 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
666 self.assertEqual(r[IP].dst, dst_ip)
667 self.assertEqual(r[IP].src, tx[0][IP].src)
668 return rx
669
Neale Ranns4a6d0232018-04-24 07:45:33 -0700670 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
671 rx = self.send_and_expect(src, tx, dst)
672
673 for r in rx:
674 self.assertEqual(r[Ether].src, tx[0][Ether].src)
675 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
676 self.assertEqual(r[IPv6].dst, dst_ip)
677 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
678 return rx
679
Neale Ranns25b04942018-04-04 09:34:50 -0700680 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
681 rx = self.send_and_expect(src, tx, dst)
682
683 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100684 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700685 self.assertEqual(r[Ether].dst, dst.remote_mac)
686 self.assertEqual(r[IP].dst, dst_ip)
687 self.assertEqual(r[IP].src, src_ip)
688 return rx
689
Neale Ranns4a6d0232018-04-24 07:45:33 -0700690 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
691 rx = self.send_and_expect(src, tx, dst)
692
693 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100694 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700695 self.assertEqual(r[Ether].dst, dst.remote_mac)
696 self.assertEqual(r[IPv6].dst, dst_ip)
697 self.assertEqual(r[IPv6].src, src_ip)
698 return rx
699
Neale Ranns25b04942018-04-04 09:34:50 -0700700 def test_gbp(self):
701 """ Group Based Policy """
702
Neale Rannsb6a47952018-11-21 05:44:35 -0800703 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
704
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800705 #
Neale Ranns25b04942018-04-04 09:34:50 -0700706 # Bridge Domains
707 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700708 bd1 = VppBridgeDomain(self, 1)
709 bd2 = VppBridgeDomain(self, 2)
710 bd20 = VppBridgeDomain(self, 20)
711
712 bd1.add_vpp_config()
713 bd2.add_vpp_config()
714 bd20.add_vpp_config()
715
716 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
717 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
718 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
719
720 gbd1.add_vpp_config()
721 gbd2.add_vpp_config()
722 gbd20.add_vpp_config()
723
724 #
725 # Route Domains
726 #
727 gt4 = VppIpTable(self, 0)
728 gt4.add_vpp_config()
729 gt6 = VppIpTable(self, 0, is_ip6=True)
730 gt6.add_vpp_config()
731 nt4 = VppIpTable(self, 20)
732 nt4.add_vpp_config()
733 nt6 = VppIpTable(self, 20, is_ip6=True)
734 nt6.add_vpp_config()
735
736 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
737 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
738
739 rd0.add_vpp_config()
740 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700741
742 #
743 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700744 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
745 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000746 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
747 self.pg4, self.loop0,
748 "10.0.0.128", "2001:10::128"),
749 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
750 self.pg5, self.loop0,
751 "10.0.1.128", "2001:10:1::128"),
752 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
753 self.pg6, self.loop1,
754 "10.0.2.128", "2001:10:2::128"),
755 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
756 self.pg7, self.loop2,
757 "11.0.0.128", "3001::128"),
758 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
759 self.pg8, self.loop2,
760 "11.0.0.129", "3001::129")]
761 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
762 VppGbpRecirc(self, epgs[1], self.loop4),
763 VppGbpRecirc(self, epgs[2], self.loop5),
764 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
765 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700766
767 epg_nat = epgs[3]
768 recirc_nat = recircs[3]
769
770 #
771 # 4 end-points, 2 in the same subnet, 3 in the same BD
772 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700773 eps = [VppGbpEndpoint(self, self.pg0,
774 epgs[0], recircs[0],
775 "10.0.0.1", "11.0.0.1",
776 "2001:10::1", "3001::1"),
777 VppGbpEndpoint(self, self.pg1,
778 epgs[0], recircs[0],
779 "10.0.0.2", "11.0.0.2",
780 "2001:10::2", "3001::2"),
781 VppGbpEndpoint(self, self.pg2,
782 epgs[1], recircs[1],
783 "10.0.1.1", "11.0.0.3",
784 "2001:10:1::1", "3001::3"),
785 VppGbpEndpoint(self, self.pg3,
786 epgs[2], recircs[2],
787 "10.0.2.1", "11.0.0.4",
788 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700789
790 #
791 # Config related to each of the EPGs
792 #
793 for epg in epgs:
794 # IP config on the BVI interfaces
795 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700796 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
797 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
798 self.vapi.sw_interface_set_mac_address(
799 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100800 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700801
802 # The BVIs are NAT inside interfaces
Filip Vargadd1e3e72019-04-15 18:52:43 +0200803 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +0200804 self.vapi.nat44_interface_add_del_feature(
805 sw_if_index=epg.bvi.sw_if_index,
806 flags=flags, is_add=1)
807 self.vapi.nat66_add_del_interface(
808 is_add=1, flags=flags,
809 sw_if_index=epg.bvi.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700810
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700811 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
812 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
813 if_ip4.add_vpp_config()
814 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700815
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700816 # EPG uplink interfaces in the RD
817 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
818 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700819
820 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700821 epg.bd_arp_ip4 = 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_ip4)
824 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100825 str(self.router_mac),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700826 epg.bvi_ip6)
827 epg.bd_arp_ip4.add_vpp_config()
828 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700829
830 # EPG in VPP
831 epg.add_vpp_config()
832
833 for recirc in recircs:
834 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700835 VppIpInterfaceBind(self, recirc.recirc,
836 recirc.epg.rd.t4).add_vpp_config()
837 VppIpInterfaceBind(self, recirc.recirc,
838 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700839
Neale Ranns4a6d0232018-04-24 07:45:33 -0700840 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200841 sw_if_index=recirc.recirc.sw_if_index, is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700842 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200843 is_add=1,
844 sw_if_index=recirc.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700845
846 recirc.add_vpp_config()
847
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700848 for recirc in recircs:
849 self.assertTrue(find_bridge_domain_port(self,
850 recirc.epg.bd.bd.bd_id,
851 recirc.recirc.sw_if_index))
852
Neale Ranns25b04942018-04-04 09:34:50 -0700853 for ep in eps:
854 self.pg_enable_capture(self.pg_interfaces)
855 self.pg_start()
856 #
857 # routes to the endpoints. We need these since there are no
858 # adj-fibs due to the fact the the BVI address has /32 and
859 # the subnet is not attached.
860 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700861 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700862 # Add static mappings for each EP from the 10/8 to 11/8 network
863 if ip.af == AF_INET:
Filip Vargadd1e3e72019-04-15 18:52:43 +0200864 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +0200865 self.vapi.nat44_add_del_static_mapping(
866 is_add=1,
867 local_ip_address=ip.bytes,
868 external_ip_address=fip.bytes,
869 external_sw_if_index=0xFFFFFFFF,
870 vrf_id=0,
871 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -0700872 else:
Filip Vargaf4749ca2019-04-25 14:55:32 +0200873 self.vapi.nat66_add_del_static_mapping(
874 local_ip_address=ip.bytes,
875 external_ip_address=fip.bytes,
876 vrf_id=0, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700877
Neale Ranns25b04942018-04-04 09:34:50 -0700878 # VPP EP create ...
879 ep.add_vpp_config()
880
Neale Rannsc0a93142018-09-05 15:42:26 -0700881 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700882
Neale Rannsc0a93142018-09-05 15:42:26 -0700883 # ... results in a Gratuitous ARP/ND on the EPG's uplink
884 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
885
886 for ii, ip in enumerate(ep.ips):
887 p = rx[ii]
888
889 if ip.is_ip6:
890 self.assertTrue(p.haslayer(ICMPv6ND_NA))
891 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
892 else:
893 self.assertTrue(p.haslayer(ARP))
894 self.assertEqual(p[ARP].psrc, ip.address)
895 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700896
897 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700898 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700899 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
900 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700901
Neale Rannsc0a93142018-09-05 15:42:26 -0700902 # floating IPs route via EPG recirc
903 r = VppIpRoute(self, fip.address, fip.length,
904 [VppRoutePath(fip.address,
905 ep.recirc.recirc.sw_if_index,
906 is_dvr=1,
907 proto=fip.dpo_proto)],
908 table_id=20,
909 is_ip6=fip.is_ip6)
910 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700911
912 # L2 FIB entries in the NAT EPG BD to bridge the packets from
913 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700914 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
915 ep.recirc.recirc, bvi_mac=0)
916 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700917
918 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700919 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700920 #
921 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
922 src=self.pg0.remote_mac) /
923 ARP(op="who-has",
924 hwdst="ff:ff:ff:ff:ff:ff",
925 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700926 pdst="10.0.0.88",
927 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700928
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700929 self.vapi.cli("clear trace")
930 self.pg0.add_stream(pkt_arp)
931
932 self.pg_enable_capture(self.pg_interfaces)
933 self.pg_start()
934
935 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700936
937 #
938 # ARP/ND packets get a response
939 #
940 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
941 src=self.pg0.remote_mac) /
942 ARP(op="who-has",
943 hwdst="ff:ff:ff:ff:ff:ff",
944 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700945 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700946 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700947
948 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
949
Neale Rannsc0a93142018-09-05 15:42:26 -0700950 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700951 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700952 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
953 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700954 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700955 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700956 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
957 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
958
959 #
960 # broadcast packets are flooded
961 #
962 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
963 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700964 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700965 UDP(sport=1234, dport=1234) /
966 Raw('\xa5' * 100))
967
968 self.vapi.cli("clear trace")
969 self.pg0.add_stream(pkt_bcast)
970
971 self.pg_enable_capture(self.pg_interfaces)
972 self.pg_start()
973
974 rxd = eps[1].itf.get_capture(1)
975 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
976 rxd = epgs[0].uplink.get_capture(1)
977 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
978
979 #
980 # packets to non-local L3 destinations dropped
981 #
982 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100983 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700984 IP(src=eps[0].ip4.address,
985 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700986 UDP(sport=1234, dport=1234) /
987 Raw('\xa5' * 100))
988 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100989 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700990 IP(src=eps[0].ip4.address,
991 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700992 UDP(sport=1234, dport=1234) /
993 Raw('\xa5' * 100))
994
995 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
996
997 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +0100998 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700999 IPv6(src=eps[0].ip6.address,
1000 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001001 UDP(sport=1234, dport=1234) /
1002 Raw('\xa5' * 100))
1003 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
1004
1005 #
1006 # Add the subnet routes
1007 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001008 s41 = VppGbpSubnet(
1009 self, rd0, "10.0.0.0", 24,
1010 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1011 s42 = VppGbpSubnet(
1012 self, rd0, "10.0.1.0", 24,
1013 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1014 s43 = VppGbpSubnet(
1015 self, rd0, "10.0.2.0", 24,
1016 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1017 s61 = VppGbpSubnet(
1018 self, rd0, "2001:10::1", 64,
1019 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1020 s62 = VppGbpSubnet(
1021 self, rd0, "2001:10:1::1", 64,
1022 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1023 s63 = VppGbpSubnet(
1024 self, rd0, "2001:10:2::1", 64,
1025 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001026 s41.add_vpp_config()
1027 s42.add_vpp_config()
1028 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001029 s61.add_vpp_config()
1030 s62.add_vpp_config()
1031 s63.add_vpp_config()
1032
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001033 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001034 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001035 eps[0].epg.uplink)
1036 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001037 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001038 eps[0].epg.uplink)
1039 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001040 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001041 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001042
1043 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1044 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1045 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1046 self.logger.info(self.vapi.cli("sh gbp recirc"))
1047 self.logger.info(self.vapi.cli("sh int"))
1048 self.logger.info(self.vapi.cli("sh int addr"))
1049 self.logger.info(self.vapi.cli("sh int feat loop6"))
1050 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1051 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001052 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001053
1054 #
1055 # Packet destined to unknown unicast is sent on the epg uplink ...
1056 #
1057 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1058 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001059 IP(src=eps[0].ip4.address,
1060 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001061 UDP(sport=1234, dport=1234) /
1062 Raw('\xa5' * 100))
1063
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001064 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001065 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001066 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001067 # ... and nowhere else
1068 self.pg1.get_capture(0, timeout=0.1)
1069 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1070
1071 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1072 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001073 IP(src=eps[0].ip4.address,
1074 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001075 UDP(sport=1234, dport=1234) /
1076 Raw('\xa5' * 100))
1077
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001078 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001079 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001080 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001081
1082 #
1083 # Packets from the uplink are forwarded in the absence of a contract
1084 #
1085 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1086 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001087 IP(src=eps[0].ip4.address,
1088 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001089 UDP(sport=1234, dport=1234) /
1090 Raw('\xa5' * 100))
1091
1092 self.send_and_expect_bridged(self.pg4,
1093 pkt_intra_epg_220_from_uplink * 65,
1094 self.pg0)
1095
1096 #
1097 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001098 # can communicate
1099 #
1100 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001101 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001102 IP(src=eps[0].ip4.address,
1103 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001104 UDP(sport=1234, dport=1234) /
1105 Raw('\xa5' * 100))
1106
Neale Ranns25b04942018-04-04 09:34:50 -07001107 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001108
1109 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001110 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001111 # cannot communicate
1112 #
1113 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001114 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001115 IP(src=eps[0].ip4.address,
1116 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001117 UDP(sport=1234, dport=1234) /
1118 Raw('\xa5' * 100))
1119 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001120 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001121 IP(src=eps[2].ip4.address,
1122 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001123 UDP(sport=1234, dport=1234) /
1124 Raw('\xa5' * 100))
1125 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001126 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001127 IP(src=eps[0].ip4.address,
1128 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001129 UDP(sport=1234, dport=1234) /
1130 Raw('\xa5' * 100))
1131
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001132 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001133 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001134 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001135 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001136
1137 #
1138 # A uni-directional contract from EPG 220 -> 221
1139 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001140 acl = VppGbpAcl(self)
1141 rule = acl.create_rule(permit_deny=1, proto=17)
1142 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1143 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001144 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001145 self, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001146 [VppGbpContractRule(
1147 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1148 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001149 VppGbpContractRule(
1150 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1151 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001152 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001153 c1.add_vpp_config()
1154
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001155 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001156 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001157 eps[2].itf)
1158 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001159 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001160
1161 #
1162 # contract for the return direction
1163 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001164 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001165 self, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001166 [VppGbpContractRule(
1167 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1168 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001169 VppGbpContractRule(
1170 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1171 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001172 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001173 c2.add_vpp_config()
1174
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001175 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001176 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001177 eps[2].itf)
1178 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001179 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001180 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001181
Neale Ranns796c84b2019-03-28 07:56:23 -07001182 ds = c2.get_drop_stats()
1183 self.assertEqual(ds['packets'], 0)
1184 ps = c2.get_permit_stats()
1185 self.assertEqual(ps['packets'], 65)
1186
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001187 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001188 # the contract does not allow non-IP
1189 #
1190 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1191 dst=self.pg2.remote_mac) /
1192 ARP())
1193 self.send_and_assert_no_replies(eps[0].itf,
1194 pkt_non_ip_inter_epg_220_to_221 * 17)
1195
1196 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001197 # check that inter group is still disabled for the groups
1198 # not in the contract.
1199 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001200 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001201 pkt_inter_epg_220_to_222 * 65)
1202
Neale Ranns25b04942018-04-04 09:34:50 -07001203 #
1204 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1205 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001206 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001207 self, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001208 [VppGbpContractRule(
1209 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1210 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001211 VppGbpContractRule(
1212 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1213 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001214 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001215 c3.add_vpp_config()
1216
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001217 self.logger.info(self.vapi.cli("sh gbp contract"))
1218
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001219 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001220 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001221 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001222 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001223
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001224 #
1225 # remove both contracts, traffic stops in both directions
1226 #
1227 c2.remove_vpp_config()
1228 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001229 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001230 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001231
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001232 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001233 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001234 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001235 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001236 self.send_and_expect_bridged(eps[0].itf,
1237 pkt_intra_epg * 65,
1238 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001239
1240 #
Neale Ranns25b04942018-04-04 09:34:50 -07001241 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001242 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001243
Neale Ranns25b04942018-04-04 09:34:50 -07001244 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001245 se1 = VppGbpSubnet(
1246 self, rd0, "0.0.0.0", 0,
1247 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1248 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001249 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001250 se2 = VppGbpSubnet(
1251 self, rd0, "11.0.0.0", 8,
1252 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1253 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001254 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001255 se16 = VppGbpSubnet(
1256 self, rd0, "::", 0,
1257 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1258 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001259 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001260 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001261 se3 = VppGbpSubnet(
1262 self, rd20, "0.0.0.0", 0,
1263 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1264 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001265 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001266 se36 = VppGbpSubnet(
1267 self, rd20, "::", 0,
1268 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1269 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001270 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001271 se4 = VppGbpSubnet(
1272 self, rd20, "11.0.0.0", 8,
1273 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1274 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001275 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001276 se1.add_vpp_config()
1277 se2.add_vpp_config()
1278 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001279 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001280 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001281 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001282
Neale Ranns25b04942018-04-04 09:34:50 -07001283 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1284 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001285 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1286 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001287 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001288
Neale Ranns4a6d0232018-04-24 07:45:33 -07001289 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001290 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001291 #
Neale Ranns25b04942018-04-04 09:34:50 -07001292 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001293 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001294 IP(src=eps[0].ip4.address,
1295 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001296 UDP(sport=1234, dport=1234) /
1297 Raw('\xa5' * 100))
1298
1299 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001300 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001301 pkt_inter_epg_220_to_global * 65)
1302
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001303 acl2 = VppGbpAcl(self)
1304 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1305 sport_to=1234, dport_from=1234, dport_to=1234)
1306 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1307 sport_from=1234, sport_to=1234,
1308 dport_from=1234, dport_to=1234)
1309
1310 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001311 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001312 self, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001313 [VppGbpContractRule(
1314 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1315 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001316 VppGbpContractRule(
1317 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1318 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001319 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001320 c4.add_vpp_config()
1321
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001322 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001323 pkt_inter_epg_220_to_global * 65,
1324 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001325 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001326
Neale Ranns4a6d0232018-04-24 07:45:33 -07001327 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001328 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001329 IPv6(src=eps[0].ip6.address,
1330 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001331 UDP(sport=1234, dport=1234) /
1332 Raw('\xa5' * 100))
1333
1334 self.send_and_expect_natted6(self.pg0,
1335 pkt_inter_epg_220_to_global * 65,
1336 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001337 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001338
1339 #
1340 # From a global address to an EP: OUT2IN
1341 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001342 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001343 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001344 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001345 src="1.1.1.1") /
1346 UDP(sport=1234, dport=1234) /
1347 Raw('\xa5' * 100))
1348
1349 self.send_and_assert_no_replies(self.pg7,
1350 pkt_inter_epg_220_from_global * 65)
1351
Neale Ranns13a08cc2018-11-07 09:25:54 -08001352 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001353 self, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001354 [VppGbpContractRule(
1355 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1356 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001357 VppGbpContractRule(
1358 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1359 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001360 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001361 c5.add_vpp_config()
1362
1363 self.send_and_expect_unnatted(self.pg7,
1364 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001365 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001366 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001367
Ole Troan8006c6a2018-12-17 12:02:26 +01001368 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001369 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001370 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001371 src="6001::1") /
1372 UDP(sport=1234, dport=1234) /
1373 Raw('\xa5' * 100))
1374
1375 self.send_and_expect_unnatted6(self.pg7,
1376 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001377 eps[0].itf,
1378 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001379
1380 #
1381 # From a local VM to another local VM using resp. public addresses:
1382 # IN2OUT2IN
1383 #
Neale Ranns25b04942018-04-04 09:34:50 -07001384 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001385 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001386 IP(src=eps[0].ip4.address,
1387 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001388 UDP(sport=1234, dport=1234) /
1389 Raw('\xa5' * 100))
1390
Neale Ranns4a6d0232018-04-24 07:45:33 -07001391 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001392 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001393 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001394 eps[0].fip4.address,
1395 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001396
Neale Rannsc0a93142018-09-05 15:42:26 -07001397 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001398 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001399 IPv6(src=eps[0].ip6.address,
1400 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001401 UDP(sport=1234, dport=1234) /
1402 Raw('\xa5' * 100))
1403
Neale Rannsc0a93142018-09-05 15:42:26 -07001404 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001405 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001406 eps[1].itf,
1407 eps[0].fip6.address,
1408 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001409
1410 #
Neale Ranns25b04942018-04-04 09:34:50 -07001411 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001412 #
Neale Ranns25b04942018-04-04 09:34:50 -07001413 for ep in eps:
1414 # del static mappings for each EP from the 10/8 to 11/8 network
Filip Vargadd1e3e72019-04-15 18:52:43 +02001415 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +02001416 self.vapi.nat44_add_del_static_mapping(
1417 is_add=0,
1418 local_ip_address=ep.ip4.bytes,
1419 external_ip_address=ep.fip4.bytes,
1420 external_sw_if_index=0xFFFFFFFF,
1421 vrf_id=0,
1422 flags=flags)
1423 self.vapi.nat66_add_del_static_mapping(
1424 local_ip_address=ep.ip6.bytes,
1425 external_ip_address=ep.fip6.bytes,
1426 vrf_id=0, is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001427
Neale Ranns25b04942018-04-04 09:34:50 -07001428 for epg in epgs:
1429 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001430 if epg != epgs[0] and epg != epgs[3]:
Filip Vargadd1e3e72019-04-15 18:52:43 +02001431 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +02001432 self.vapi.nat44_interface_add_del_feature(
1433 sw_if_index=epg.bvi.sw_if_index,
1434 flags=flags,
1435 is_add=0)
1436 self.vapi.nat66_add_del_interface(
1437 is_add=0, flags=flags,
1438 sw_if_index=epg.bvi.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001439
Neale Ranns25b04942018-04-04 09:34:50 -07001440 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001441 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001442 sw_if_index=recirc.recirc.sw_if_index,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001443 is_add=0)
1444 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001445 is_add=0,
1446 sw_if_index=recirc.recirc.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001447
Neale Ranns774356a2018-11-29 12:02:16 +00001448 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1449 n_tries=100, s_time=1):
1450 while (n_tries):
1451 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1452 return True
1453 n_tries = n_tries - 1
1454 self.sleep(s_time)
1455 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1456 return False
1457
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001458 def test_gbp_learn_l2(self):
1459 """ GBP L2 Endpoint Learning """
1460
Neale Ranns796c84b2019-03-28 07:56:23 -07001461 self.vapi.cli("clear errors")
1462
Neale Rannsb6a47952018-11-21 05:44:35 -08001463 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001464 learnt = [{'mac': '00:00:11:11:11:01',
1465 'ip': '10.0.0.1',
1466 'ip6': '2001:10::2'},
1467 {'mac': '00:00:11:11:11:02',
1468 'ip': '10.0.0.2',
1469 'ip6': '2001:10::3'}]
1470
1471 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001472 # IP tables
1473 #
1474 gt4 = VppIpTable(self, 1)
1475 gt4.add_vpp_config()
1476 gt6 = VppIpTable(self, 1, is_ip6=True)
1477 gt6.add_vpp_config()
1478
1479 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1480 rd1.add_vpp_config()
1481
1482 #
1483 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1484 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1485 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1486 #
1487 self.pg2.config_ip4()
1488 self.pg2.resolve_arp()
1489 self.pg2.generate_remote_hosts(4)
1490 self.pg2.configure_ipv4_neighbors()
1491 self.pg3.config_ip4()
1492 self.pg3.resolve_arp()
1493 self.pg4.config_ip4()
1494 self.pg4.resolve_arp()
1495
1496 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001497 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1498 #
1499 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1500 "239.1.1.1", 88,
1501 mcast_itf=self.pg4)
1502 tun_bm.add_vpp_config()
1503
1504 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001505 # a GBP bridge domain with a BVI and a UU-flood interface
1506 #
1507 bd1 = VppBridgeDomain(self, 1)
1508 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001509 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001510 gbd1.add_vpp_config()
1511
1512 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1513 self.logger.info(self.vapi.cli("sh gbp bridge"))
1514
1515 # ... and has a /32 applied
1516 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1517 ip_addr.add_vpp_config()
1518
1519 #
1520 # The Endpoint-group in which we are learning endpoints
1521 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001522 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001523 None, self.loop0,
1524 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001525 "2001:10::128",
1526 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001527 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001528 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001529 None, self.loop1,
1530 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001531 "2001:11::128",
1532 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001533 epg_330.add_vpp_config()
1534
1535 #
1536 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001537 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001538 #
1539 vx_tun_l2_1 = VppGbpVxlanTunnel(
1540 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001541 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1542 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001543 vx_tun_l2_1.add_vpp_config()
1544
1545 #
1546 # A static endpoint that the learnt endpoints are trying to
1547 # talk to
1548 #
1549 ep = VppGbpEndpoint(self, self.pg0,
1550 epg_220, None,
1551 "10.0.0.127", "11.0.0.127",
1552 "2001:10::1", "3001::1")
1553 ep.add_vpp_config()
1554
1555 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1556
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001557 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001558 p = (Ether(src=self.pg2.remote_mac,
1559 dst=self.pg2.local_mac) /
1560 IP(src=self.pg2.remote_hosts[0].ip4,
1561 dst=self.pg2.local_ip4) /
1562 UDP(sport=1234, dport=48879) /
1563 VXLAN(vni=99, gpid=88, flags=0x88) /
1564 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1565 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1566 UDP(sport=1234, dport=1234) /
1567 Raw('\xa5' * 100))
1568
1569 self.send_and_assert_no_replies(self.pg2, p)
1570
Neale Ranns796c84b2019-03-28 07:56:23 -07001571 self.logger.info(self.vapi.cli("sh error"))
1572 # self.assert_packet_counter_equal(
1573 # '/err/gbp-policy-port/drop-no-contract', 1)
1574
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001575 #
1576 # we should not have learnt a new tunnel endpoint, since
1577 # the EPG was not learnt.
1578 #
1579 self.assertEqual(INDEX_INVALID,
1580 find_vxlan_gbp_tunnel(self,
1581 self.pg2.local_ip4,
1582 self.pg2.remote_hosts[0].ip4,
1583 99))
1584
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001585 # epg is not learnt, because the EPG is unknown
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001586 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1587
Neale Ranns8da9fc62019-03-04 14:08:11 -08001588 #
1589 # Learn new EPs from IP packets
1590 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001591 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001592 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001593 # arriving on an unknown TEP
1594 p = (Ether(src=self.pg2.remote_mac,
1595 dst=self.pg2.local_mac) /
1596 IP(src=self.pg2.remote_hosts[1].ip4,
1597 dst=self.pg2.local_ip4) /
1598 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001599 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001600 Ether(src=l['mac'], dst=ep.mac) /
1601 IP(src=l['ip'], dst=ep.ip4.address) /
1602 UDP(sport=1234, dport=1234) /
1603 Raw('\xa5' * 100))
1604
1605 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1606
1607 # the new TEP
1608 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1609 self,
1610 self.pg2.local_ip4,
1611 self.pg2.remote_hosts[1].ip4,
1612 99)
1613 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1614
1615 #
1616 # the EP is learnt via the learnt TEP
1617 # both from its MAC and its IP
1618 #
1619 self.assertTrue(find_gbp_endpoint(self,
1620 vx_tun_l2_1.sw_if_index,
1621 mac=l['mac']))
1622 self.assertTrue(find_gbp_endpoint(self,
1623 vx_tun_l2_1.sw_if_index,
1624 ip=l['ip']))
1625
Neale Ranns796c84b2019-03-28 07:56:23 -07001626 # self.assert_packet_counter_equal(
1627 # '/err/gbp-policy-port/allow-intra-sclass', 2)
1628
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001629 self.logger.info(self.vapi.cli("show gbp endpoint"))
1630 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001631 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001632
1633 #
1634 # If we sleep for the threshold time, the learnt endpoints should
1635 # age out
1636 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001637 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001638 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1639 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001640
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001641 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001642 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1643 #
1644 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001645 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001646 # arriving on an unknown TEP
1647 p = (Ether(src=self.pg2.remote_mac,
1648 dst=self.pg2.local_mac) /
1649 IP(src=self.pg2.remote_hosts[1].ip4,
1650 dst="239.1.1.1") /
1651 UDP(sport=1234, dport=48879) /
1652 VXLAN(vni=88, gpid=112, flags=0x88) /
1653 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1654 ARP(op="who-has",
1655 psrc=l['ip'], pdst=l['ip'],
1656 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1657
1658 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1659
1660 # the new TEP
1661 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1662 self,
1663 self.pg2.local_ip4,
1664 self.pg2.remote_hosts[1].ip4,
1665 99)
1666 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1667
1668 #
1669 # the EP is learnt via the learnt TEP
1670 # both from its MAC and its IP
1671 #
1672 self.assertTrue(find_gbp_endpoint(self,
1673 vx_tun_l2_1.sw_if_index,
1674 mac=l['mac']))
1675 self.assertTrue(find_gbp_endpoint(self,
1676 vx_tun_l2_1.sw_if_index,
1677 ip=l['ip']))
1678
1679 #
1680 # wait for the learnt endpoints to age out
1681 #
1682 for l in learnt:
1683 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1684 mac=l['mac'])
1685
1686 #
1687 # Learn new EPs from L2 packets
1688 #
1689 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001690 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001691 # arriving on an unknown TEP
1692 p = (Ether(src=self.pg2.remote_mac,
1693 dst=self.pg2.local_mac) /
1694 IP(src=self.pg2.remote_hosts[1].ip4,
1695 dst=self.pg2.local_ip4) /
1696 UDP(sport=1234, dport=48879) /
1697 VXLAN(vni=99, gpid=112, flags=0x88) /
1698 Ether(src=l['mac'], dst=ep.mac) /
1699 Raw('\xa5' * 100))
1700
1701 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1702
1703 # the new TEP
1704 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1705 self,
1706 self.pg2.local_ip4,
1707 self.pg2.remote_hosts[1].ip4,
1708 99)
1709 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1710
1711 #
1712 # the EP is learnt via the learnt TEP
1713 # both from its MAC and its IP
1714 #
1715 self.assertTrue(find_gbp_endpoint(self,
1716 vx_tun_l2_1.sw_if_index,
1717 mac=l['mac']))
1718
1719 self.logger.info(self.vapi.cli("show gbp endpoint"))
1720 self.logger.info(self.vapi.cli("show gbp vxlan"))
1721 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1722
1723 #
1724 # wait for the learnt endpoints to age out
1725 #
1726 for l in learnt:
1727 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1728 mac=l['mac'])
1729
1730 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001731 # repeat. the do not learn bit is set so the EPs are not learnt
1732 #
1733 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001734 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001735 p = (Ether(src=self.pg2.remote_mac,
1736 dst=self.pg2.local_mac) /
1737 IP(src=self.pg2.remote_hosts[1].ip4,
1738 dst=self.pg2.local_ip4) /
1739 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001740 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001741 Ether(src=l['mac'], dst=ep.mac) /
1742 IP(src=l['ip'], dst=ep.ip4.address) /
1743 UDP(sport=1234, dport=1234) /
1744 Raw('\xa5' * 100))
1745
Filip Vargaf4749ca2019-04-25 14:55:32 +02001746 rx = self.send_and_expect(self.pg2, p * 65, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001747
1748 for l in learnt:
1749 self.assertFalse(find_gbp_endpoint(self,
1750 vx_tun_l2_1.sw_if_index,
1751 mac=l['mac']))
1752
1753 #
1754 # repeat
1755 #
1756 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001757 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001758 p = (Ether(src=self.pg2.remote_mac,
1759 dst=self.pg2.local_mac) /
1760 IP(src=self.pg2.remote_hosts[1].ip4,
1761 dst=self.pg2.local_ip4) /
1762 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001763 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001764 Ether(src=l['mac'], dst=ep.mac) /
1765 IP(src=l['ip'], dst=ep.ip4.address) /
1766 UDP(sport=1234, dport=1234) /
1767 Raw('\xa5' * 100))
1768
Filip Vargaf4749ca2019-04-25 14:55:32 +02001769 rx = self.send_and_expect(self.pg2, p * 65, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001770
1771 self.assertTrue(find_gbp_endpoint(self,
1772 vx_tun_l2_1.sw_if_index,
1773 mac=l['mac']))
1774
1775 #
1776 # Static EP replies to dynamics
1777 #
1778 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1779 for l in learnt:
1780 p = (Ether(src=ep.mac, dst=l['mac']) /
1781 IP(dst=l['ip'], src=ep.ip4.address) /
1782 UDP(sport=1234, dport=1234) /
1783 Raw('\xa5' * 100))
1784
1785 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1786
1787 for rx in rxs:
1788 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1789 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1790 self.assertEqual(rx[UDP].dport, 48879)
1791 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001792 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001793 self.assertEqual(rx[VXLAN].vni, 99)
1794 self.assertTrue(rx[VXLAN].flags.G)
1795 self.assertTrue(rx[VXLAN].flags.Instance)
1796 self.assertTrue(rx[VXLAN].gpflags.A)
1797 self.assertFalse(rx[VXLAN].gpflags.D)
1798
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001799 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001800 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1801 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001802
1803 #
1804 # repeat in the other EPG
1805 # there's no contract between 220 and 330, but the A-bit is set
1806 # so the packet is cleared for delivery
1807 #
1808 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001809 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001810 p = (Ether(src=self.pg2.remote_mac,
1811 dst=self.pg2.local_mac) /
1812 IP(src=self.pg2.remote_hosts[1].ip4,
1813 dst=self.pg2.local_ip4) /
1814 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001815 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001816 Ether(src=l['mac'], dst=ep.mac) /
1817 IP(src=l['ip'], dst=ep.ip4.address) /
1818 UDP(sport=1234, dport=1234) /
1819 Raw('\xa5' * 100))
1820
Filip Vargaf4749ca2019-04-25 14:55:32 +02001821 rx = self.send_and_expect(self.pg2, p * 65, self.pg0)
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02001822
1823 self.assertTrue(find_gbp_endpoint(self,
1824 vx_tun_l2_1.sw_if_index,
1825 mac=l['mac']))
1826
1827 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001828 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001829 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001830 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001831 p = (Ether(src=ep.mac, dst=l['mac']) /
1832 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1833 UDP(sport=1234, dport=1234) /
1834 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001835
Neale Ranns13a08cc2018-11-07 09:25:54 -08001836 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001837
1838 #
1839 # refresh the entries after the check for no replies above
1840 #
1841 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001842 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001843 p = (Ether(src=self.pg2.remote_mac,
1844 dst=self.pg2.local_mac) /
1845 IP(src=self.pg2.remote_hosts[1].ip4,
1846 dst=self.pg2.local_ip4) /
1847 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001848 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001849 Ether(src=l['mac'], dst=ep.mac) /
1850 IP(src=l['ip'], dst=ep.ip4.address) /
1851 UDP(sport=1234, dport=1234) /
1852 Raw('\xa5' * 100))
1853
Filip Vargaf4749ca2019-04-25 14:55:32 +02001854 rx = self.send_and_expect(self.pg2, p * 65, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001855
1856 self.assertTrue(find_gbp_endpoint(self,
1857 vx_tun_l2_1.sw_if_index,
1858 mac=l['mac']))
1859
1860 #
1861 # Add the contract so they can talk
1862 #
1863 acl = VppGbpAcl(self)
1864 rule = acl.create_rule(permit_deny=1, proto=17)
1865 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1866 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001867 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001868 self, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001869 [VppGbpContractRule(
1870 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1871 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001872 VppGbpContractRule(
1873 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1874 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001875 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001876 c1.add_vpp_config()
1877
1878 for l in learnt:
1879 p = (Ether(src=ep.mac, dst=l['mac']) /
1880 IP(dst=l['ip'], src=ep.ip4.address) /
1881 UDP(sport=1234, dport=1234) /
1882 Raw('\xa5' * 100))
1883
1884 self.send_and_expect(self.pg0, [p], self.pg2)
1885
1886 #
1887 # send UU packets from the local EP
1888 #
1889 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1890 self.logger.info(self.vapi.cli("sh gbp bridge"))
1891 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1892 IP(dst="10.0.0.133", src=ep.ip4.address) /
1893 UDP(sport=1234, dport=1234) /
1894 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001895 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001896
1897 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1898
1899 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1900 IP(dst="10.0.0.133", src=ep.ip4.address) /
1901 UDP(sport=1234, dport=1234) /
1902 Raw('\xa5' * 100))
1903 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1904
Neale Ranns879d11c2019-01-21 23:34:18 -08001905 for rx in rxs:
1906 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
1907 self.assertEqual(rx[IP].dst, "239.1.1.1")
1908 self.assertEqual(rx[UDP].dport, 48879)
1909 # the UDP source port is a random value for hashing
1910 self.assertEqual(rx[VXLAN].gpid, 112)
1911 self.assertEqual(rx[VXLAN].vni, 88)
1912 self.assertTrue(rx[VXLAN].flags.G)
1913 self.assertTrue(rx[VXLAN].flags.Instance)
1914 self.assertFalse(rx[VXLAN].gpflags.A)
1915 self.assertFalse(rx[VXLAN].gpflags.D)
1916
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001917 #
1918 # Check v6 Endpoints
1919 #
1920 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001921 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001922 p = (Ether(src=self.pg2.remote_mac,
1923 dst=self.pg2.local_mac) /
1924 IP(src=self.pg2.remote_hosts[1].ip4,
1925 dst=self.pg2.local_ip4) /
1926 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001927 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001928 Ether(src=l['mac'], dst=ep.mac) /
1929 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1930 UDP(sport=1234, dport=1234) /
1931 Raw('\xa5' * 100))
1932
Filip Vargaf4749ca2019-04-25 14:55:32 +02001933 rx = self.send_and_expect(self.pg2, p * 65, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001934
1935 self.assertTrue(find_gbp_endpoint(self,
1936 vx_tun_l2_1.sw_if_index,
1937 mac=l['mac']))
1938
1939 #
1940 # L3 Endpoint Learning
1941 # - configured on the bridge's BVI
1942 #
1943
1944 #
1945 # clean up
1946 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001947 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001948 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1949 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001950 self.pg2.unconfig_ip4()
1951 self.pg3.unconfig_ip4()
1952 self.pg4.unconfig_ip4()
1953
1954 self.logger.info(self.vapi.cli("sh int"))
1955 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1956
Mohsin Kazmi7363d472019-04-04 13:22:15 +02001957 def test_gbp_bd_flags(self):
1958 """ GBP BD FLAGS """
1959
1960 #
1961 # IP tables
1962 #
1963 gt4 = VppIpTable(self, 1)
1964 gt4.add_vpp_config()
1965 gt6 = VppIpTable(self, 1, is_ip6=True)
1966 gt6.add_vpp_config()
1967
1968 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1969 rd1.add_vpp_config()
1970
1971 #
1972 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1973 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1974 #
1975 self.pg3.config_ip4()
1976 self.pg3.resolve_arp()
1977 self.pg4.config_ip4()
1978 self.pg4.resolve_arp()
1979
1980 #
1981 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1982 #
1983 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1984 "239.1.1.1", 88,
1985 mcast_itf=self.pg4)
1986 tun_bm.add_vpp_config()
1987
1988 #
1989 # a GBP bridge domain with a BVI and a UU-flood interface
1990 #
1991 bd1 = VppBridgeDomain(self, 1)
1992 bd1.add_vpp_config()
1993
1994 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3, tun_bm,
1995 uu_drop=True, bm_drop=True)
1996 gbd1.add_vpp_config()
1997
1998 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1999 self.logger.info(self.vapi.cli("sh gbp bridge"))
2000
2001 # ... and has a /32 applied
2002 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2003 ip_addr.add_vpp_config()
2004
2005 #
2006 # The Endpoint-group
2007 #
2008 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2009 None, self.loop0,
2010 "10.0.0.128",
2011 "2001:10::128",
2012 VppGbpEndpointRetention(2))
2013 epg_220.add_vpp_config()
2014
2015 ep = VppGbpEndpoint(self, self.pg0,
2016 epg_220, None,
2017 "10.0.0.127", "11.0.0.127",
2018 "2001:10::1", "3001::1")
2019 ep.add_vpp_config()
2020 #
2021 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2022 # in bd
2023 #
2024 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2025 self.logger.info(self.vapi.cli("sh gbp bridge"))
2026 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
2027 IP(dst="10.0.0.133", src=ep.ip4.address) /
2028 UDP(sport=1234, dport=1234) /
2029 Raw('\xa5' * 100))
2030 self.send_and_assert_no_replies(ep.itf, [p_uu])
2031
2032 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2033 IP(dst="10.0.0.133", src=ep.ip4.address) /
2034 UDP(sport=1234, dport=1234) /
2035 Raw('\xa5' * 100))
2036 self.send_and_assert_no_replies(ep.itf, [p_bm])
2037
2038 self.pg3.unconfig_ip4()
2039 self.pg4.unconfig_ip4()
2040
2041 self.logger.info(self.vapi.cli("sh int"))
2042
Neale Rannsc29c0af2018-11-07 04:21:12 -08002043 def test_gbp_learn_vlan_l2(self):
2044 """ GBP L2 Endpoint w/ VLANs"""
2045
Neale Rannsb6a47952018-11-21 05:44:35 -08002046 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002047 learnt = [{'mac': '00:00:11:11:11:01',
2048 'ip': '10.0.0.1',
2049 'ip6': '2001:10::2'},
2050 {'mac': '00:00:11:11:11:02',
2051 'ip': '10.0.0.2',
2052 'ip6': '2001:10::3'}]
2053
2054 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002055 # IP tables
2056 #
2057 gt4 = VppIpTable(self, 1)
2058 gt4.add_vpp_config()
2059 gt6 = VppIpTable(self, 1, is_ip6=True)
2060 gt6.add_vpp_config()
2061
2062 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
2063 rd1.add_vpp_config()
2064
2065 #
2066 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2067 #
2068 self.pg2.config_ip4()
2069 self.pg2.resolve_arp()
2070 self.pg2.generate_remote_hosts(4)
2071 self.pg2.configure_ipv4_neighbors()
2072 self.pg3.config_ip4()
2073 self.pg3.resolve_arp()
2074
2075 #
2076 # The EP will be on a vlan sub-interface
2077 #
2078 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2079 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002080 self.vapi.l2_interface_vlan_tag_rewrite(
2081 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2082 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002083
2084 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2085 self.pg3.remote_ip4, 116)
2086 bd_uu_fwd.add_vpp_config()
2087
2088 #
2089 # a GBP bridge domain with a BVI and a UU-flood interface
2090 # The BD is marked as do not learn, so no endpoints are ever
2091 # learnt in this BD.
2092 #
2093 bd1 = VppBridgeDomain(self, 1)
2094 bd1.add_vpp_config()
2095 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
2096 learn=False)
2097 gbd1.add_vpp_config()
2098
2099 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2100 self.logger.info(self.vapi.cli("sh gbp bridge"))
2101
2102 # ... and has a /32 applied
2103 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2104 ip_addr.add_vpp_config()
2105
2106 #
2107 # The Endpoint-group in which we are learning endpoints
2108 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002109 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002110 None, self.loop0,
2111 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002112 "2001:10::128",
2113 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002114 epg_220.add_vpp_config()
2115
2116 #
2117 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002118 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002119 #
2120 vx_tun_l2_1 = VppGbpVxlanTunnel(
2121 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002122 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2123 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002124 vx_tun_l2_1.add_vpp_config()
2125
2126 #
2127 # A static endpoint that the learnt endpoints are trying to
2128 # talk to
2129 #
2130 ep = VppGbpEndpoint(self, vlan_11,
2131 epg_220, None,
2132 "10.0.0.127", "11.0.0.127",
2133 "2001:10::1", "3001::1")
2134 ep.add_vpp_config()
2135
2136 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2137
2138 #
2139 # Send to the static EP
2140 #
2141 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002142 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002143 # arriving on an unknown TEP
2144 p = (Ether(src=self.pg2.remote_mac,
2145 dst=self.pg2.local_mac) /
2146 IP(src=self.pg2.remote_hosts[1].ip4,
2147 dst=self.pg2.local_ip4) /
2148 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002149 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002150 Ether(src=l['mac'], dst=ep.mac) /
2151 IP(src=l['ip'], dst=ep.ip4.address) /
2152 UDP(sport=1234, dport=1234) /
2153 Raw('\xa5' * 100))
2154
2155 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2156
2157 #
2158 # packet to EP has the EP's vlan tag
2159 #
2160 for rx in rxs:
2161 self.assertEqual(rx[Dot1Q].vlan, 11)
2162
2163 #
2164 # the EP is not learnt since the BD setting prevents it
2165 # also no TEP too
2166 #
2167 self.assertFalse(find_gbp_endpoint(self,
2168 vx_tun_l2_1.sw_if_index,
2169 mac=l['mac']))
2170 self.assertEqual(INDEX_INVALID,
2171 find_vxlan_gbp_tunnel(
2172 self,
2173 self.pg2.local_ip4,
2174 self.pg2.remote_hosts[1].ip4,
2175 99))
2176
2177 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2178
2179 #
2180 # static to remotes
2181 # we didn't learn the remotes so they are sent to the UU-fwd
2182 #
2183 for l in learnt:
2184 p = (Ether(src=ep.mac, dst=l['mac']) /
2185 Dot1Q(vlan=11) /
2186 IP(dst=l['ip'], src=ep.ip4.address) /
2187 UDP(sport=1234, dport=1234) /
2188 Raw('\xa5' * 100))
2189
2190 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2191
2192 for rx in rxs:
2193 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2194 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2195 self.assertEqual(rx[UDP].dport, 48879)
2196 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002197 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002198 self.assertEqual(rx[VXLAN].vni, 116)
2199 self.assertTrue(rx[VXLAN].flags.G)
2200 self.assertTrue(rx[VXLAN].flags.Instance)
2201 self.assertFalse(rx[VXLAN].gpflags.A)
2202 self.assertFalse(rx[VXLAN].gpflags.D)
2203
2204 self.pg2.unconfig_ip4()
2205 self.pg3.unconfig_ip4()
2206
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002207 def test_gbp_learn_l3(self):
2208 """ GBP L3 Endpoint Learning """
2209
Neale Ranns13a08cc2018-11-07 09:25:54 -08002210 self.vapi.cli("set logging class gbp debug")
2211
Neale Rannsb6a47952018-11-21 05:44:35 -08002212 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002213 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2214 routed_src_mac = "00:22:bd:f8:19:ff"
2215
2216 learnt = [{'mac': '00:00:11:11:11:02',
2217 'ip': '10.0.1.2',
2218 'ip6': '2001:10::2'},
2219 {'mac': '00:00:11:11:11:03',
2220 'ip': '10.0.1.3',
2221 'ip6': '2001:10::3'}]
2222
2223 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002224 # IP tables
2225 #
2226 t4 = VppIpTable(self, 1)
2227 t4.add_vpp_config()
2228 t6 = VppIpTable(self, 1, True)
2229 t6.add_vpp_config()
2230
2231 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2232 self.pg4.remote_ip4, 114)
2233 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2234 self.pg4.remote_ip4, 116)
2235 tun_ip4_uu.add_vpp_config()
2236 tun_ip6_uu.add_vpp_config()
2237
2238 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2239 rd1.add_vpp_config()
2240
Ole Troan8006c6a2018-12-17 12:02:26 +01002241 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002242
2243 #
2244 # Bind the BVI to the RD
2245 #
2246 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2247 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2248
2249 #
2250 # Pg2 hosts the vxlan tunnel
2251 # hosts on pg2 to act as TEPs
2252 # pg3 is BD uu-fwd
2253 # pg4 is RD uu-fwd
2254 #
2255 self.pg2.config_ip4()
2256 self.pg2.resolve_arp()
2257 self.pg2.generate_remote_hosts(4)
2258 self.pg2.configure_ipv4_neighbors()
2259 self.pg3.config_ip4()
2260 self.pg3.resolve_arp()
2261 self.pg4.config_ip4()
2262 self.pg4.resolve_arp()
2263
2264 #
2265 # a GBP bridge domain with a BVI and a UU-flood interface
2266 #
2267 bd1 = VppBridgeDomain(self, 1)
2268 bd1.add_vpp_config()
2269 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2270 gbd1.add_vpp_config()
2271
2272 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2273 self.logger.info(self.vapi.cli("sh gbp bridge"))
2274 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002275
2276 # ... and has a /32 and /128 applied
2277 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2278 ip4_addr.add_vpp_config()
2279 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2280 ip6_addr.add_vpp_config()
2281
2282 #
2283 # The Endpoint-group in which we are learning endpoints
2284 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002285 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002286 None, self.loop0,
2287 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002288 "2001:10::128",
2289 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002290 epg_220.add_vpp_config()
2291
2292 #
2293 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002294 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002295 #
2296 vx_tun_l3 = VppGbpVxlanTunnel(
2297 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002298 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2299 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002300 vx_tun_l3.add_vpp_config()
2301
2302 #
2303 # A static endpoint that the learnt endpoints are trying to
2304 # talk to
2305 #
2306 ep = VppGbpEndpoint(self, self.pg0,
2307 epg_220, None,
2308 "10.0.0.127", "11.0.0.127",
2309 "2001:10::1", "3001::1")
2310 ep.add_vpp_config()
2311
2312 #
2313 # learn some remote IPv4 EPs
2314 #
2315 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002316 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002317 # arriving on an unknown TEP
2318 p = (Ether(src=self.pg2.remote_mac,
2319 dst=self.pg2.local_mac) /
2320 IP(src=self.pg2.remote_hosts[1].ip4,
2321 dst=self.pg2.local_ip4) /
2322 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002323 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002324 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2325 IP(src=l['ip'], dst=ep.ip4.address) /
2326 UDP(sport=1234, dport=1234) /
2327 Raw('\xa5' * 100))
2328
2329 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2330
2331 # the new TEP
2332 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2333 self,
2334 self.pg2.local_ip4,
2335 self.pg2.remote_hosts[1].ip4,
2336 vx_tun_l3.vni)
2337 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2338
2339 # endpoint learnt via the parent GBP-vxlan interface
2340 self.assertTrue(find_gbp_endpoint(self,
2341 vx_tun_l3._sw_if_index,
2342 ip=l['ip']))
2343
2344 #
2345 # Static IPv4 EP replies to learnt
2346 #
2347 for l in learnt:
2348 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2349 IP(dst=l['ip'], src=ep.ip4.address) /
2350 UDP(sport=1234, dport=1234) /
2351 Raw('\xa5' * 100))
2352
Filip Vargaf4749ca2019-04-25 14:55:32 +02002353 rxs = self.send_and_expect(self.pg0, p * 1, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002354
2355 for rx in rxs:
2356 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2357 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2358 self.assertEqual(rx[UDP].dport, 48879)
2359 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002360 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002361 self.assertEqual(rx[VXLAN].vni, 101)
2362 self.assertTrue(rx[VXLAN].flags.G)
2363 self.assertTrue(rx[VXLAN].flags.Instance)
2364 self.assertTrue(rx[VXLAN].gpflags.A)
2365 self.assertFalse(rx[VXLAN].gpflags.D)
2366
2367 inner = rx[VXLAN].payload
2368
2369 self.assertEqual(inner[Ether].src, routed_src_mac)
2370 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2371 self.assertEqual(inner[IP].src, ep.ip4.address)
2372 self.assertEqual(inner[IP].dst, l['ip'])
2373
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002374 for l in learnt:
2375 self.assertFalse(find_gbp_endpoint(self,
2376 tep1_sw_if_index,
2377 ip=l['ip']))
2378
2379 #
2380 # learn some remote IPv6 EPs
2381 #
2382 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002383 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002384 # arriving on an unknown TEP
2385 p = (Ether(src=self.pg2.remote_mac,
2386 dst=self.pg2.local_mac) /
2387 IP(src=self.pg2.remote_hosts[1].ip4,
2388 dst=self.pg2.local_ip4) /
2389 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002390 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002391 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2392 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2393 UDP(sport=1234, dport=1234) /
2394 Raw('\xa5' * 100))
2395
2396 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2397
2398 # the new TEP
2399 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2400 self,
2401 self.pg2.local_ip4,
2402 self.pg2.remote_hosts[1].ip4,
2403 vx_tun_l3.vni)
2404 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2405
2406 self.logger.info(self.vapi.cli("show gbp bridge"))
2407 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2408 self.logger.info(self.vapi.cli("show gbp vxlan"))
2409 self.logger.info(self.vapi.cli("show int addr"))
2410
2411 # endpoint learnt via the TEP
2412 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2413
2414 self.logger.info(self.vapi.cli("show gbp endpoint"))
2415 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2416
2417 #
2418 # Static EP replies to learnt
2419 #
2420 for l in learnt:
2421 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2422 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2423 UDP(sport=1234, dport=1234) /
2424 Raw('\xa5' * 100))
2425
Filip Vargaf4749ca2019-04-25 14:55:32 +02002426 rxs = self.send_and_expect(self.pg0, p * 65, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002427
2428 for rx in rxs:
2429 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2430 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2431 self.assertEqual(rx[UDP].dport, 48879)
2432 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002433 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002434 self.assertEqual(rx[VXLAN].vni, 101)
2435 self.assertTrue(rx[VXLAN].flags.G)
2436 self.assertTrue(rx[VXLAN].flags.Instance)
2437 self.assertTrue(rx[VXLAN].gpflags.A)
2438 self.assertFalse(rx[VXLAN].gpflags.D)
2439
2440 inner = rx[VXLAN].payload
2441
2442 self.assertEqual(inner[Ether].src, routed_src_mac)
2443 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2444 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2445 self.assertEqual(inner[IPv6].dst, l['ip6'])
2446
2447 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002448 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002449 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002450
2451 #
2452 # Static sends to unknown EP with no route
2453 #
2454 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2455 IP(dst="10.0.0.99", src=ep.ip4.address) /
2456 UDP(sport=1234, dport=1234) /
2457 Raw('\xa5' * 100))
2458
2459 self.send_and_assert_no_replies(self.pg0, [p])
2460
2461 #
2462 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002463 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002464 #
2465 se_10_24 = VppGbpSubnet(
2466 self, rd1, "10.0.0.0", 24,
2467 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2468 se_10_24.add_vpp_config()
2469
2470 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2471 IP(dst="10.0.0.99", src=ep.ip4.address) /
2472 UDP(sport=1234, dport=1234) /
2473 Raw('\xa5' * 100))
2474
2475 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2476 for rx in rxs:
2477 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2478 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2479 self.assertEqual(rx[UDP].dport, 48879)
2480 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002481 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002482 self.assertEqual(rx[VXLAN].vni, 114)
2483 self.assertTrue(rx[VXLAN].flags.G)
2484 self.assertTrue(rx[VXLAN].flags.Instance)
2485 # policy is not applied to packets sent to the uu-fwd interfaces
2486 self.assertFalse(rx[VXLAN].gpflags.A)
2487 self.assertFalse(rx[VXLAN].gpflags.D)
2488
2489 #
2490 # learn some remote IPv4 EPs
2491 #
2492 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002493 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002494 # arriving on an unknown TEP
2495 p = (Ether(src=self.pg2.remote_mac,
2496 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002497 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002498 dst=self.pg2.local_ip4) /
2499 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002500 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002501 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2502 IP(src=l['ip'], dst=ep.ip4.address) /
2503 UDP(sport=1234, dport=1234) /
2504 Raw('\xa5' * 100))
2505
2506 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2507
2508 # the new TEP
2509 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2510 self,
2511 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08002512 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002513 vx_tun_l3.vni)
2514 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2515
2516 # endpoint learnt via the parent GBP-vxlan interface
2517 self.assertTrue(find_gbp_endpoint(self,
2518 vx_tun_l3._sw_if_index,
2519 ip=l['ip']))
2520
2521 #
2522 # Add a remote endpoint from the API
2523 #
2524 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2525 epg_220, None,
2526 "10.0.0.88", "11.0.0.88",
2527 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002528 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002529 self.pg2.local_ip4,
2530 self.pg2.remote_hosts[1].ip4,
2531 mac=None)
2532 rep_88.add_vpp_config()
2533
2534 #
2535 # Add a remote endpoint from the API that matches an existing one
2536 #
2537 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2538 epg_220, None,
2539 learnt[0]['ip'], "11.0.0.101",
2540 learnt[0]['ip6'], "3001::101",
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_2.add_vpp_config()
2546
2547 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002548 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002549 # packets should be send on the v4/v6 uu=fwd interface resp.
2550 #
2551 se_10_1_24 = VppGbpSubnet(
2552 self, rd1, "10.0.1.0", 24,
2553 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2554 se_10_1_24.add_vpp_config()
2555
2556 self.logger.info(self.vapi.cli("show gbp endpoint"))
2557
2558 ips = ["10.0.0.88", learnt[0]['ip']]
2559 for ip in ips:
2560 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2561 IP(dst=ip, src=ep.ip4.address) /
2562 UDP(sport=1234, dport=1234) /
2563 Raw('\xa5' * 100))
2564
Filip Vargaf4749ca2019-04-25 14:55:32 +02002565 rxs = self.send_and_expect(self.pg0, p * 65, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002566
2567 for rx in rxs:
2568 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2569 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2570 self.assertEqual(rx[UDP].dport, 48879)
2571 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002572 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002573 self.assertEqual(rx[VXLAN].vni, 101)
2574 self.assertTrue(rx[VXLAN].flags.G)
2575 self.assertTrue(rx[VXLAN].flags.Instance)
2576 self.assertTrue(rx[VXLAN].gpflags.A)
2577 self.assertFalse(rx[VXLAN].gpflags.D)
2578
2579 inner = rx[VXLAN].payload
2580
2581 self.assertEqual(inner[Ether].src, routed_src_mac)
2582 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2583 self.assertEqual(inner[IP].src, ep.ip4.address)
2584 self.assertEqual(inner[IP].dst, ip)
2585
2586 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002587 # remove the API remote EPs, only API sourced is gone, the DP
2588 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002589 #
2590 rep_88.remove_vpp_config()
2591 rep_2.remove_vpp_config()
2592
Neale Ranns00a469d2018-12-20 06:12:19 -08002593 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2594
2595 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2596 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2597 UDP(sport=1234, dport=1234) /
2598 Raw('\xa5' * 100))
2599 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002600
Neale Ranns13a08cc2018-11-07 09:25:54 -08002601 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002602
Neale Ranns13a08cc2018-11-07 09:25:54 -08002603 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2604 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2605 UDP(sport=1234, dport=1234) /
2606 Raw('\xa5' * 100))
2607 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002608
Neale Ranns13a08cc2018-11-07 09:25:54 -08002609 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002610 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08002611 # present (because it's DP learnt) when the TC ends so wait until
2612 # it is removed
2613 #
Neale Ranns00a469d2018-12-20 06:12:19 -08002614 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
2615 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002616
2617 #
2618 # shutdown with learnt endpoint present
2619 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002620 p = (Ether(src=self.pg2.remote_mac,
2621 dst=self.pg2.local_mac) /
2622 IP(src=self.pg2.remote_hosts[1].ip4,
2623 dst=self.pg2.local_ip4) /
2624 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002625 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002626 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2627 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2628 UDP(sport=1234, dport=1234) /
2629 Raw('\xa5' * 100))
2630
2631 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2632
2633 # endpoint learnt via the parent GBP-vxlan interface
2634 self.assertTrue(find_gbp_endpoint(self,
2635 vx_tun_l3._sw_if_index,
2636 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002637
2638 #
2639 # TODO
2640 # remote endpoint becomes local
2641 #
2642 self.pg2.unconfig_ip4()
2643 self.pg3.unconfig_ip4()
2644 self.pg4.unconfig_ip4()
2645
Neale Ranns13a08cc2018-11-07 09:25:54 -08002646 def test_gbp_redirect(self):
2647 """ GBP Endpoint Redirect """
2648
2649 self.vapi.cli("set logging class gbp debug")
2650
Neale Rannsb6a47952018-11-21 05:44:35 -08002651 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002652 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2653 routed_src_mac = "00:22:bd:f8:19:ff"
2654
2655 learnt = [{'mac': '00:00:11:11:11:02',
2656 'ip': '10.0.1.2',
2657 'ip6': '2001:10::2'},
2658 {'mac': '00:00:11:11:11:03',
2659 'ip': '10.0.1.3',
2660 'ip6': '2001:10::3'}]
2661
2662 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002663 # IP tables
2664 #
2665 t4 = VppIpTable(self, 1)
2666 t4.add_vpp_config()
2667 t6 = VppIpTable(self, 1, True)
2668 t6.add_vpp_config()
2669
2670 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2671 rd1.add_vpp_config()
2672
Ole Troan8006c6a2018-12-17 12:02:26 +01002673 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002674
2675 #
2676 # Bind the BVI to the RD
2677 #
2678 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2679 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2680
2681 #
2682 # Pg7 hosts a BD's UU-fwd
2683 #
2684 self.pg7.config_ip4()
2685 self.pg7.resolve_arp()
2686
2687 #
2688 # a GBP bridge domains for the EPs
2689 #
2690 bd1 = VppBridgeDomain(self, 1)
2691 bd1.add_vpp_config()
2692 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2693 gbd1.add_vpp_config()
2694
2695 bd2 = VppBridgeDomain(self, 2)
2696 bd2.add_vpp_config()
2697 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2698 gbd2.add_vpp_config()
2699
2700 # ... and has a /32 and /128 applied
2701 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2702 ip4_addr.add_vpp_config()
2703 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2704 ip6_addr.add_vpp_config()
2705 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2706 ip4_addr.add_vpp_config()
2707 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2708 ip6_addr.add_vpp_config()
2709
2710 #
2711 # The Endpoint-groups in which we are learning endpoints
2712 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002713 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002714 None, gbd1.bvi,
2715 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002716 "2001:10::128",
2717 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002718 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002719 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002720 None, gbd2.bvi,
2721 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002722 "2001:11::128",
2723 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002724 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002725 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002726 None, gbd1.bvi,
2727 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002728 "2001:12::128",
2729 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002730 epg_222.add_vpp_config()
2731
2732 #
2733 # a GBP bridge domains for the SEPs
2734 #
2735 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2736 self.pg7.remote_ip4, 116)
2737 bd_uu1.add_vpp_config()
2738 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2739 self.pg7.remote_ip4, 117)
2740 bd_uu2.add_vpp_config()
2741
2742 bd3 = VppBridgeDomain(self, 3)
2743 bd3.add_vpp_config()
2744 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2745 gbd3.add_vpp_config()
2746 bd4 = VppBridgeDomain(self, 4)
2747 bd4.add_vpp_config()
2748 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2749 gbd4.add_vpp_config()
2750
2751 #
2752 # EPGs in which the service endpoints exist
2753 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002754 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002755 None, gbd1.bvi,
2756 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002757 "4001:10::128",
2758 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002759 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08002760 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002761 None, gbd2.bvi,
2762 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002763 "4001:11::128",
2764 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08002765 epg_321.add_vpp_config()
2766
2767 #
2768 # three local endpoints
2769 #
2770 ep1 = VppGbpEndpoint(self, self.pg0,
2771 epg_220, None,
2772 "10.0.0.1", "11.0.0.1",
2773 "2001:10::1", "3001:10::1")
2774 ep1.add_vpp_config()
2775 ep2 = VppGbpEndpoint(self, self.pg1,
2776 epg_221, None,
2777 "10.0.1.1", "11.0.1.1",
2778 "2001:11::1", "3001:11::1")
2779 ep2.add_vpp_config()
2780 ep3 = VppGbpEndpoint(self, self.pg2,
2781 epg_222, None,
2782 "10.0.2.2", "11.0.2.2",
2783 "2001:12::1", "3001:12::1")
2784 ep3.add_vpp_config()
2785
2786 #
2787 # service endpoints
2788 #
2789 sep1 = VppGbpEndpoint(self, self.pg3,
2790 epg_320, None,
2791 "12.0.0.1", "13.0.0.1",
2792 "4001:10::1", "5001:10::1")
2793 sep1.add_vpp_config()
2794 sep2 = VppGbpEndpoint(self, self.pg4,
2795 epg_320, None,
2796 "12.0.0.2", "13.0.0.2",
2797 "4001:10::2", "5001:10::2")
2798 sep2.add_vpp_config()
2799 sep3 = VppGbpEndpoint(self, self.pg5,
2800 epg_321, None,
2801 "12.0.1.1", "13.0.1.1",
2802 "4001:11::1", "5001:11::1")
2803 sep3.add_vpp_config()
2804 # this EP is not installed immediately
2805 sep4 = VppGbpEndpoint(self, self.pg6,
2806 epg_321, None,
2807 "12.0.1.2", "13.0.1.2",
2808 "4001:11::2", "5001:11::2")
2809
2810 #
2811 # an L2 switch packet between local EPs in different EPGs
2812 # different dest ports on each so the are LB hashed differently
2813 #
2814 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2815 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2816 UDP(sport=1234, dport=1234) /
2817 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002818 (Ether(src=ep3.mac, dst=ep1.mac) /
2819 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2820 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002821 Raw('\xa5' * 100))]
2822 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2823 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2824 UDP(sport=1234, dport=1234) /
2825 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002826 (Ether(src=ep3.mac, dst=ep1.mac) /
2827 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002828 UDP(sport=1234, dport=1230) /
2829 Raw('\xa5' * 100))]
2830
2831 # should be dropped since no contract yet
2832 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2833 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2834
2835 #
2836 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2837 # one of the next-hops is via an EP that is not known
2838 #
2839 acl = VppGbpAcl(self)
2840 rule4 = acl.create_rule(permit_deny=1, proto=17)
2841 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2842 acl_index = acl.add_vpp_config([rule4, rule6])
2843
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002844 #
2845 # test the src-ip hash mode
2846 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002847 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002848 self, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002849 [VppGbpContractRule(
2850 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002851 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002852 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2853 sep1.ip4, sep1.epg.rd),
2854 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2855 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02002856 VppGbpContractRule(
2857 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2858 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2859 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2860 sep3.ip6, sep3.epg.rd),
2861 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2862 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002863 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08002864 c1.add_vpp_config()
2865
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002866 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002867 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002868 [VppGbpContractRule(
2869 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2870 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2871 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2872 sep1.ip4, sep1.epg.rd),
2873 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2874 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02002875 VppGbpContractRule(
2876 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2877 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2878 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2879 sep3.ip6, sep3.epg.rd),
2880 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2881 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002882 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002883 c2.add_vpp_config()
2884
Neale Ranns13a08cc2018-11-07 09:25:54 -08002885 #
2886 # send again with the contract preset, now packets arrive
2887 # at SEP1 or SEP2 depending on the hashing
2888 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002889 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002890
2891 for rx in rxs:
2892 self.assertEqual(rx[Ether].src, routed_src_mac)
2893 self.assertEqual(rx[Ether].dst, sep1.mac)
2894 self.assertEqual(rx[IP].src, ep1.ip4.address)
2895 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2896
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002897 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2898
2899 for rx in rxs:
2900 self.assertEqual(rx[Ether].src, routed_src_mac)
2901 self.assertEqual(rx[Ether].dst, sep2.mac)
2902 self.assertEqual(rx[IP].src, ep3.ip4.address)
2903 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2904
Neale Ranns13a08cc2018-11-07 09:25:54 -08002905 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2906
2907 for rx in rxs:
2908 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2909 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2910 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2911 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2912 self.assertEqual(rx[VXLAN].vni, 117)
2913 self.assertTrue(rx[VXLAN].flags.G)
2914 self.assertTrue(rx[VXLAN].flags.Instance)
2915 # redirect policy has been applied
2916 self.assertTrue(rx[VXLAN].gpflags.A)
2917 self.assertFalse(rx[VXLAN].gpflags.D)
2918
2919 inner = rx[VXLAN].payload
2920
2921 self.assertEqual(inner[Ether].src, routed_src_mac)
2922 self.assertEqual(inner[Ether].dst, sep4.mac)
2923 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2924 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2925
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002926 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002927
2928 for rx in rxs:
2929 self.assertEqual(rx[Ether].src, routed_src_mac)
2930 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002931 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2932 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002933
2934 #
2935 # programme the unknown EP
2936 #
2937 sep4.add_vpp_config()
2938
2939 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2940
2941 for rx in rxs:
2942 self.assertEqual(rx[Ether].src, routed_src_mac)
2943 self.assertEqual(rx[Ether].dst, sep4.mac)
2944 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2945 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2946
2947 #
2948 # and revert back to unprogrammed
2949 #
2950 sep4.remove_vpp_config()
2951
2952 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2953
2954 for rx in rxs:
2955 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2956 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2957 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2958 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2959 self.assertEqual(rx[VXLAN].vni, 117)
2960 self.assertTrue(rx[VXLAN].flags.G)
2961 self.assertTrue(rx[VXLAN].flags.Instance)
2962 # redirect policy has been applied
2963 self.assertTrue(rx[VXLAN].gpflags.A)
2964 self.assertFalse(rx[VXLAN].gpflags.D)
2965
2966 inner = rx[VXLAN].payload
2967
2968 self.assertEqual(inner[Ether].src, routed_src_mac)
2969 self.assertEqual(inner[Ether].dst, sep4.mac)
2970 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2971 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2972
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002973 c1.remove_vpp_config()
2974 c2.remove_vpp_config()
2975
2976 #
2977 # test the symmetric hash mode
2978 #
2979 c1 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002980 self, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002981 [VppGbpContractRule(
2982 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2983 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2984 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2985 sep1.ip4, sep1.epg.rd),
2986 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2987 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02002988 VppGbpContractRule(
2989 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2990 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2991 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2992 sep3.ip6, sep3.epg.rd),
2993 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2994 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08002995 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002996 c1.add_vpp_config()
2997
2998 c2 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07002999 self, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003000 [VppGbpContractRule(
3001 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3002 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3003 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3004 sep1.ip4, sep1.epg.rd),
3005 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3006 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003007 VppGbpContractRule(
3008 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3009 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3010 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3011 sep3.ip6, sep3.epg.rd),
3012 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3013 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003014 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003015 c2.add_vpp_config()
3016
3017 #
3018 # send again with the contract preset, now packets arrive
3019 # at SEP1 for both directions
3020 #
3021 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3022
3023 for rx in rxs:
3024 self.assertEqual(rx[Ether].src, routed_src_mac)
3025 self.assertEqual(rx[Ether].dst, sep1.mac)
3026 self.assertEqual(rx[IP].src, ep1.ip4.address)
3027 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3028
3029 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3030
3031 for rx in rxs:
3032 self.assertEqual(rx[Ether].src, routed_src_mac)
3033 self.assertEqual(rx[Ether].dst, sep1.mac)
3034 self.assertEqual(rx[IP].src, ep3.ip4.address)
3035 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3036
Neale Ranns13a08cc2018-11-07 09:25:54 -08003037 #
3038 # programme the unknown EP for the L3 tests
3039 #
3040 sep4.add_vpp_config()
3041
3042 #
3043 # an L3 switch packet between local EPs in different EPGs
3044 # different dest ports on each so the are LB hashed differently
3045 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003046 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003047 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3048 UDP(sport=1234, dport=1234) /
3049 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003050 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003051 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3052 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003053 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003054 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003055 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3056 UDP(sport=1234, dport=1234) /
3057 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003058 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003059 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3060 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003061 Raw('\xa5' * 100))]
3062
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003063 c3 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003064 self, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003065 [VppGbpContractRule(
3066 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3067 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3068 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3069 sep1.ip4, sep1.epg.rd),
3070 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3071 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003072 VppGbpContractRule(
3073 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3074 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3075 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3076 sep3.ip6, sep3.epg.rd),
3077 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3078 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003079 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003080 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003081
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003082 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003083
3084 for rx in rxs:
3085 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003086 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003087 self.assertEqual(rx[IP].src, ep1.ip4.address)
3088 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3089
3090 #
3091 # learn a remote EP in EPG 221
3092 #
3093 vx_tun_l3 = VppGbpVxlanTunnel(
3094 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003095 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3096 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003097 vx_tun_l3.add_vpp_config()
3098
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003099 c4 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003100 self, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003101 [VppGbpContractRule(
3102 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3103 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003104 VppGbpContractRule(
3105 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3106 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003107 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003108 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003109
3110 p = (Ether(src=self.pg7.remote_mac,
3111 dst=self.pg7.local_mac) /
3112 IP(src=self.pg7.remote_ip4,
3113 dst=self.pg7.local_ip4) /
3114 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003115 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003116 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003117 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3118 UDP(sport=1234, dport=1234) /
3119 Raw('\xa5' * 100))
3120
3121 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3122
3123 # endpoint learnt via the parent GBP-vxlan interface
3124 self.assertTrue(find_gbp_endpoint(self,
3125 vx_tun_l3._sw_if_index,
3126 ip="10.0.0.88"))
3127
3128 p = (Ether(src=self.pg7.remote_mac,
3129 dst=self.pg7.local_mac) /
3130 IP(src=self.pg7.remote_ip4,
3131 dst=self.pg7.local_ip4) /
3132 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003133 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003134 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003135 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3136 UDP(sport=1234, dport=1234) /
3137 Raw('\xa5' * 100))
3138
3139 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3140
3141 # endpoint learnt via the parent GBP-vxlan interface
3142 self.assertTrue(find_gbp_endpoint(self,
3143 vx_tun_l3._sw_if_index,
3144 ip="2001:10::88"))
3145
3146 #
3147 # L3 switch from local to remote EP
3148 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003149 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003150 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3151 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003152 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003153 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003154 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3155 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003156 Raw('\xa5' * 100))]
3157
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003158 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003159
3160 for rx in rxs:
3161 self.assertEqual(rx[Ether].src, routed_src_mac)
3162 self.assertEqual(rx[Ether].dst, sep1.mac)
3163 self.assertEqual(rx[IP].src, ep1.ip4.address)
3164 self.assertEqual(rx[IP].dst, "10.0.0.88")
3165
3166 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3167
3168 for rx in rxs:
3169 self.assertEqual(rx[Ether].src, routed_src_mac)
3170 self.assertEqual(rx[Ether].dst, sep4.mac)
3171 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3172 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3173
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003174 #
3175 # test the dst-ip hash mode
3176 #
3177 c5 = VppGbpContract(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003178 self, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003179 [VppGbpContractRule(
3180 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3181 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3182 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3183 sep1.ip4, sep1.epg.rd),
3184 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3185 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003186 VppGbpContractRule(
3187 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3188 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3189 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3190 sep3.ip6, sep3.epg.rd),
3191 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3192 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003193 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003194 c5.add_vpp_config()
3195
3196 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3197
3198 for rx in rxs:
3199 self.assertEqual(rx[Ether].src, routed_src_mac)
3200 self.assertEqual(rx[Ether].dst, sep1.mac)
3201 self.assertEqual(rx[IP].src, ep1.ip4.address)
3202 self.assertEqual(rx[IP].dst, "10.0.0.88")
3203
3204 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003205
3206 for rx in rxs:
3207 self.assertEqual(rx[Ether].src, routed_src_mac)
3208 self.assertEqual(rx[Ether].dst, sep3.mac)
3209 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3210 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3211
Neale Rannsb6a47952018-11-21 05:44:35 -08003212 #
3213 # cleanup
3214 #
3215 self.pg7.unconfig_ip4()
3216
3217 def test_gbp_l3_out(self):
3218 """ GBP L3 Out """
3219
3220 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3221 self.vapi.cli("set logging class gbp debug")
3222
3223 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3224 routed_src_mac = "00:22:bd:f8:19:ff"
3225
3226 #
3227 # IP tables
3228 #
3229 t4 = VppIpTable(self, 1)
3230 t4.add_vpp_config()
3231 t6 = VppIpTable(self, 1, True)
3232 t6.add_vpp_config()
3233
3234 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3235 rd1.add_vpp_config()
3236
Ole Troan8006c6a2018-12-17 12:02:26 +01003237 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003238
3239 #
3240 # Bind the BVI to the RD
3241 #
3242 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3243 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3244
3245 #
3246 # Pg7 hosts a BD's BUM
3247 # Pg1 some other l3 interface
3248 #
3249 self.pg7.config_ip4()
3250 self.pg7.resolve_arp()
3251
3252 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003253 # a multicast vxlan-gbp tunnel for broadcast in the BD
3254 #
3255 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3256 "239.1.1.1", 88,
3257 mcast_itf=self.pg7)
3258 tun_bm.add_vpp_config()
3259
3260 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003261 # a GBP external bridge domains for the EPs
3262 #
3263 bd1 = VppBridgeDomain(self, 1)
3264 bd1.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003265 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003266 gbd1.add_vpp_config()
3267
3268 #
3269 # The Endpoint-groups in which the external endpoints exist
3270 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003271 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003272 None, gbd1.bvi,
3273 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003274 "2001:10::128",
3275 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003276 epg_220.add_vpp_config()
3277
3278 # the BVIs have the subnets applied ...
3279 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3280 ip4_addr.add_vpp_config()
3281 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3282 ip6_addr.add_vpp_config()
3283
3284 # ... which are L3-out subnets
3285 l3o_1 = VppGbpSubnet(
3286 self, rd1, "10.0.0.0", 24,
3287 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003288 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003289 l3o_1.add_vpp_config()
3290
3291 #
3292 # an external interface attached to the outside world and the
3293 # external BD
3294 #
3295 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3296 vlan_100.admin_up()
Neale Ranns36abbf12019-03-12 02:34:07 -07003297 VppL2Vtr(self, vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3298 vlan_101 = VppDot1QSubint(self, self.pg0, 101)
3299 vlan_101.admin_up()
3300 VppL2Vtr(self, vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
3301
3302 ext_itf = VppGbpExtItf(self, self.loop0, bd1, rd1)
Neale Rannsb6a47952018-11-21 05:44:35 -08003303 ext_itf.add_vpp_config()
3304
3305 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003306 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003307 #
3308 vx_tun_l3 = VppGbpVxlanTunnel(
3309 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003310 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3311 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003312 vx_tun_l3.add_vpp_config()
3313
3314 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003315 # External Endpoints
3316 #
3317 eep1 = VppGbpEndpoint(self, vlan_100,
3318 epg_220, None,
3319 "10.0.0.1", "11.0.0.1",
3320 "2001:10::1", "3001::1",
3321 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3322 eep1.add_vpp_config()
3323 eep2 = VppGbpEndpoint(self, vlan_101,
3324 epg_220, None,
3325 "10.0.0.2", "11.0.0.2",
3326 "2001:10::2", "3001::2",
3327 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3328 eep2.add_vpp_config()
3329
3330 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003331 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003332 #
3333 rep = VppGbpEndpoint(self, vx_tun_l3,
3334 epg_220, None,
3335 "10.0.0.101", "11.0.0.101",
3336 "2001:10::101", "3001::101",
3337 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3338 self.pg7.local_ip4,
3339 self.pg7.remote_ip4,
3340 mac=None)
3341 rep.add_vpp_config()
3342
3343 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003344 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003345 #
3346 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3347 Dot1Q(vlan=100) /
3348 ARP(op="who-has",
3349 psrc=eep1.ip4.address, pdst="10.0.0.128",
3350 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3351 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3352
3353 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003354 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003355 # are ARP'd for
3356 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003357 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003358 Dot1Q(vlan=100) /
3359 IP(src="10.0.0.1", dst="10.0.0.88") /
3360 UDP(sport=1234, dport=1234) /
3361 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003362 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003363 Dot1Q(vlan=100) /
3364 IPv6(src="2001:10::1", dst="2001:10::88") /
3365 UDP(sport=1234, dport=1234) /
3366 Raw('\xa5' * 100))
3367
3368 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3369
3370 for rx in rxs:
3371 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3372 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3373 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3374 self.assertEqual(rx[IP].dst, "239.1.1.1")
3375 self.assertEqual(rx[VXLAN].vni, 88)
3376 self.assertTrue(rx[VXLAN].flags.G)
3377 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003378 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003379 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003380 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003381 self.assertFalse(rx[VXLAN].gpflags.D)
3382
3383 inner = rx[VXLAN].payload
3384
3385 self.assertTrue(inner.haslayer(ARP))
3386
3387 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003388 # remote to external
3389 #
3390 p = (Ether(src=self.pg7.remote_mac,
3391 dst=self.pg7.local_mac) /
3392 IP(src=self.pg7.remote_ip4,
3393 dst=self.pg7.local_ip4) /
3394 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003395 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003396 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003397 IP(src="10.0.0.101", dst="10.0.0.1") /
3398 UDP(sport=1234, dport=1234) /
3399 Raw('\xa5' * 100))
3400
3401 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3402
3403 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003404 # local EP pings router
3405 #
3406 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3407 Dot1Q(vlan=100) /
3408 IP(src=eep1.ip4.address, dst="10.0.0.128") /
3409 ICMP(type='echo-request'))
3410
3411 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3412
3413 for rx in rxs:
3414 self.assertEqual(rx[Ether].src, str(self.router_mac))
3415 self.assertEqual(rx[Ether].dst, eep1.mac)
3416 self.assertEqual(rx[Dot1Q].vlan, 100)
3417
3418 #
3419 # local EP pings other local EP
3420 #
3421 p = (Ether(src=eep1.mac, dst=eep2.mac) /
3422 Dot1Q(vlan=100) /
3423 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
3424 ICMP(type='echo-request'))
3425
3426 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3427
3428 for rx in rxs:
3429 self.assertEqual(rx[Ether].src, eep1.mac)
3430 self.assertEqual(rx[Ether].dst, eep2.mac)
3431 self.assertEqual(rx[Dot1Q].vlan, 101)
3432
3433 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003434 # A subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08003435 #
3436 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07003437 [VppRoutePath(eep1.ip4.address,
3438 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08003439 table_id=t4.table_id)
3440 ip_220.add_vpp_config()
3441
3442 l3o_220 = VppGbpSubnet(
3443 self, rd1, "10.220.0.0", 24,
3444 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003445 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08003446 l3o_220.add_vpp_config()
3447
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003448 #
3449 # A subnet reachable through the external EP2
3450 #
3451 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
3452 [VppRoutePath(eep2.ip4.address,
3453 eep2.epg.bvi.sw_if_index)],
3454 table_id=t4.table_id)
3455 ip_221.add_vpp_config()
3456
3457 l3o_221 = VppGbpSubnet(
3458 self, rd1, "10.221.0.0", 24,
3459 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3460 sclass=4221)
3461 l3o_221.add_vpp_config()
3462
3463 #
3464 # ping between hosts in remote subnets
3465 # dropped without a contract
3466 #
3467 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3468 Dot1Q(vlan=100) /
3469 IP(src="10.220.0.1", dst="10.221.0.1") /
3470 ICMP(type='echo-request'))
3471
3472 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3473
3474 #
3475 # contract for the external nets to communicate
3476 #
3477 acl = VppGbpAcl(self)
3478 rule4 = acl.create_rule(permit_deny=1, proto=17)
3479 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3480 acl_index = acl.add_vpp_config([rule4, rule6])
3481
3482 c1 = VppGbpContract(
3483 self, 4220, 4221, acl_index,
3484 [VppGbpContractRule(
3485 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3486 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003487 VppGbpContractRule(
3488 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3489 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003490 [ETH_P_IP, ETH_P_IPV6])
3491 c1.add_vpp_config()
3492
3493 #
3494 # Contracts allowing ext-net 200 to talk with external EPs
3495 #
3496 c2 = VppGbpContract(
3497 self, 4220, 113, acl_index,
3498 [VppGbpContractRule(
3499 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3500 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003501 VppGbpContractRule(
3502 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3503 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003504 [ETH_P_IP, ETH_P_IPV6])
3505 c2.add_vpp_config()
3506 c3 = VppGbpContract(
3507 self, 113, 4220, acl_index,
3508 [VppGbpContractRule(
3509 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3510 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003511 VppGbpContractRule(
3512 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3513 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003514 [ETH_P_IP, ETH_P_IPV6])
3515 c3.add_vpp_config()
3516
3517 #
3518 # ping between hosts in remote subnets
3519 #
3520 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3521 Dot1Q(vlan=100) /
3522 IP(src="10.220.0.1", dst="10.221.0.1") /
3523 UDP(sport=1234, dport=1234) /
3524 Raw('\xa5' * 100))
3525
3526 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
3527
3528 for rx in rxs:
3529 self.assertEqual(rx[Ether].src, str(self.router_mac))
3530 self.assertEqual(rx[Ether].dst, eep2.mac)
3531 self.assertEqual(rx[Dot1Q].vlan, 101)
3532
3533 # we did not learn these external hosts
3534 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
3535 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
3536
3537 #
3538 # from remote external EP to local external EP
3539 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003540 p = (Ether(src=self.pg7.remote_mac,
3541 dst=self.pg7.local_mac) /
3542 IP(src=self.pg7.remote_ip4,
3543 dst=self.pg7.local_ip4) /
3544 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003545 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003546 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003547 IP(src="10.0.0.101", dst="10.220.0.1") /
3548 UDP(sport=1234, dport=1234) /
3549 Raw('\xa5' * 100))
3550
3551 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3552
3553 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003554 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07003555 #
3556 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3557 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003558 IP(src="10.220.0.1", dst=rep.ip4.address) /
3559 UDP(sport=1234, dport=1234) /
3560 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003561
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003562 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07003563
3564 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003565 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3566 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3567 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3568 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3569 self.assertEqual(rx[VXLAN].vni, 444)
3570 self.assertTrue(rx[VXLAN].flags.G)
3571 self.assertTrue(rx[VXLAN].flags.Instance)
3572 # the sclass of the ext-net the packet came from
3573 self.assertEqual(rx[VXLAN].gpid, 4220)
3574 # policy was applied to the original IP packet
3575 self.assertTrue(rx[VXLAN].gpflags.A)
3576 # since it's an external host the reciever should not learn it
3577 self.assertTrue(rx[VXLAN].gpflags.D)
3578 inner = rx[VXLAN].payload
3579 self.assertEqual(inner[IP].src, "10.220.0.1")
3580 self.assertEqual(inner[IP].dst, rep.ip4.address)
3581
3582 #
3583 # An external subnet reachable via the remote external EP
3584 #
3585
3586 #
3587 # first the VXLAN-GBP tunnel over which it is reached
3588 #
3589 vx_tun_r = VppVxlanGbpTunnel(
3590 self, self.pg7.local_ip4,
3591 self.pg7.remote_ip4, 445,
3592 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
3593 VXLAN_GBP_API_TUNNEL_MODE_L3))
3594 vx_tun_r.add_vpp_config()
3595 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
3596
3597 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
3598
3599 #
3600 # then the special adj to resolve through on that tunnel
3601 #
3602 n1 = VppNeighbor(self,
3603 vx_tun_r.sw_if_index,
3604 "00:0c:0c:0c:0c:0c",
3605 self.pg7.remote_ip4)
3606 n1.add_vpp_config()
3607
3608 #
3609 # the route via the adj above
3610 #
3611 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
3612 [VppRoutePath(self.pg7.remote_ip4,
3613 vx_tun_r.sw_if_index)],
3614 table_id=t4.table_id)
3615 ip_222.add_vpp_config()
3616
3617 l3o_222 = VppGbpSubnet(
3618 self, rd1, "10.222.0.0", 24,
3619 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3620 sclass=4222)
3621 l3o_222.add_vpp_config()
3622
3623 #
3624 # ping between hosts in local and remote external subnets
3625 # dropped without a contract
3626 #
3627 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3628 Dot1Q(vlan=100) /
3629 IP(src="10.220.0.1", dst="10.222.0.1") /
3630 UDP(sport=1234, dport=1234) /
3631 Raw('\xa5' * 100))
3632
3633 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
3634
3635 #
3636 # Add contracts ext-nets for 220 -> 222
3637 #
3638 c4 = VppGbpContract(
3639 self, 4220, 4222, acl_index,
3640 [VppGbpContractRule(
3641 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3642 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003643 VppGbpContractRule(
3644 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3645 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003646 [ETH_P_IP, ETH_P_IPV6])
3647 c4.add_vpp_config()
3648
3649 #
3650 # ping from host in local to remote external subnets
3651 #
3652 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
3653 Dot1Q(vlan=100) /
3654 IP(src="10.220.0.1", dst="10.222.0.1") /
3655 UDP(sport=1234, dport=1234) /
3656 Raw('\xa5' * 100))
3657
3658 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
3659
3660 for rx in rxs:
3661 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3662 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3663 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3664 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3665 self.assertEqual(rx[VXLAN].vni, 445)
3666 self.assertTrue(rx[VXLAN].flags.G)
3667 self.assertTrue(rx[VXLAN].flags.Instance)
3668 # the sclass of the ext-net the packet came from
3669 self.assertEqual(rx[VXLAN].gpid, 4220)
3670 # policy was applied to the original IP packet
3671 self.assertTrue(rx[VXLAN].gpflags.A)
3672 # since it's an external host the reciever should not learn it
3673 self.assertTrue(rx[VXLAN].gpflags.D)
3674 inner = rx[VXLAN].payload
3675 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
3676 self.assertEqual(inner[IP].src, "10.220.0.1")
3677 self.assertEqual(inner[IP].dst, "10.222.0.1")
3678
3679 #
3680 # ping from host in remote to local external subnets
3681 # there's no contract for this, but the A bit is set.
3682 #
3683 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3684 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3685 UDP(sport=1234, dport=48879) /
3686 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3687 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3688 IP(src="10.222.0.1", dst="10.220.0.1") /
3689 UDP(sport=1234, dport=1234) /
3690 Raw('\xa5' * 100))
3691
3692 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
3693 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07003694
3695 #
Neale Ranns2b600182019-03-29 05:08:27 -07003696 # ping from host in remote to remote external subnets
3697 # this is dropped by reflection check.
3698 #
3699 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
3700 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
3701 UDP(sport=1234, dport=48879) /
3702 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
3703 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
3704 IP(src="10.222.0.1", dst="10.222.0.2") /
3705 UDP(sport=1234, dport=1234) /
3706 Raw('\xa5' * 100))
3707
3708 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
3709
3710 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003711 # cleanup
3712 #
3713 self.pg7.unconfig_ip4()
Neale Ranns36abbf12019-03-12 02:34:07 -07003714 vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
Neale Rannsb6a47952018-11-21 05:44:35 -08003715
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003716
3717if __name__ == '__main__':
3718 unittest.main(testRunner=VppTestRunner)