blob: 9cf1817b29600bf35daed26481cfe9c3f2ab11dd [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, \
Neale Ranns69a85b52019-06-14 07:49:50 +000010 ICMPv6ND_NA, ICMPv6EchoRequest
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
Mohsin Kazmife52dea2019-04-18 15:54:58 +020013from scapy.data import ETH_P_IP, ETH_P_IPV6, ETH_P_ARP
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, \
Neale Ranns097fa662018-05-01 05:17:55 -070020 VppIpInterfaceAddress, VppIpInterfaceBind, find_route, FibPathProto, \
21 FibPathType
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080022from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
Neale Ranns36abbf12019-03-12 02:34:07 -070023 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port, VppL2Vtr
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -070024from vpp_sub_interface import L2_VTR_OP, VppDot1QSubint
Neale Ranns69a85b52019-06-14 07:49:50 +000025from vpp_ip import VppIpAddress, VppIpPrefix, DpoProto
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080026from vpp_papi import VppEnum, MACAddress
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -080027from vpp_vxlan_gbp_tunnel import find_vxlan_gbp_tunnel, INDEX_INVALID, \
28 VppVxlanGbpTunnel
Neale Ranns4dd4cf42019-03-27 05:06:47 -070029from vpp_neighbor import VppNeighbor
Neale Ranns3eea9de2019-06-21 02:09:25 -070030try:
31 text_type = unicode
32except NameError:
33 text_type = str
Neale Rannsbc27d1b2018-02-05 01:13:38 -080034
Paul Vinciguerra4271c972019-05-14 13:25:49 -040035NUM_PKTS = 67
36
Neale Rannsbc27d1b2018-02-05 01:13:38 -080037
Neale Ranns3eea9de2019-06-21 02:09:25 -070038def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, tep=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070039 if ip:
40 vip = VppIpAddress(ip)
41 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010042 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070043
44 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070045
Neale Rannsc0a93142018-09-05 15:42:26 -070046 for ep in eps:
Neale Ranns3eea9de2019-06-21 02:09:25 -070047 if tep:
48 src = VppIpAddress(tep[0])
49 dst = VppIpAddress(tep[1])
50 if src != ep.endpoint.tun.src or dst != ep.endpoint.tun.dst:
51 continue
Neale Ranns93cc3ee2018-10-10 07:22:51 -070052 if sw_if_index:
53 if ep.endpoint.sw_if_index != sw_if_index:
54 continue
55 if ip:
56 for eip in ep.endpoint.ips:
57 if vip == eip:
58 return True
59 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010060 if vmac.packed == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070061 return True
Neale Ranns3eea9de2019-06-21 02:09:25 -070062
Neale Rannsc0a93142018-09-05 15:42:26 -070063 return False
64
65
Neale Ranns93cc3ee2018-10-10 07:22:51 -070066def find_gbp_vxlan(test, vni):
67 ts = test.vapi.gbp_vxlan_tunnel_dump()
68 for t in ts:
69 if t.tunnel.vni == vni:
70 return True
71 return False
72
73
Neale Rannsbc27d1b2018-02-05 01:13:38 -080074class VppGbpEndpoint(VppObject):
75 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020076 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080077 """
78
Neale Ranns25b04942018-04-04 09:34:50 -070079 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -070080 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +010081 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -070082
83 @property
Neale Rannsc0a93142018-09-05 15:42:26 -070084 def ip4(self):
85 return self._ip4
86
87 @property
88 def fip4(self):
89 return self._fip4
90
91 @property
92 def ip6(self):
93 return self._ip6
94
95 @property
96 def fip6(self):
97 return self._fip6
98
99 @property
100 def ips(self):
101 return [self.ip4, self.ip6]
102
103 @property
104 def fips(self):
105 return [self.fip4, self.fip6]
106
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700107 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
108 flags=0,
109 tun_src="0.0.0.0",
110 tun_dst="0.0.0.0",
111 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800112 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700113 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800114 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700115 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700116
117 self._ip4 = VppIpAddress(ip4)
118 self._fip4 = VppIpAddress(fip4)
119 self._ip6 = VppIpAddress(ip6)
120 self._fip6 = VppIpAddress(fip6)
121
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700122 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100123 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700124 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100125 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700126
127 self.flags = flags
128 self.tun_src = VppIpAddress(tun_src)
129 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800130
131 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700132 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700133 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700134 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100135 self.vmac.packed,
Neale Ranns4ba67722019-02-28 11:11:39 +0000136 self.epg.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700137 self.flags,
138 self.tun_src.encode(),
139 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700140 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800141 self._test.registry.register(self, self._test.logger)
142
143 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700144 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800145
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800146 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700147 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
148 self.itf.sw_if_index,
149 self.ip4.address,
Neale Ranns4ba67722019-02-28 11:11:39 +0000150 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800151
152 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700153 return find_gbp_endpoint(self._test,
154 self.itf.sw_if_index,
155 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700156
157
158class VppGbpRecirc(VppObject):
159 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200160 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700161 """
162
163 def __init__(self, test, epg, recirc, is_ext=False):
164 self._test = test
165 self.recirc = recirc
166 self.epg = epg
167 self.is_ext = is_ext
168
169 def add_vpp_config(self):
170 self._test.vapi.gbp_recirc_add_del(
171 1,
172 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000173 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700174 self.is_ext)
175 self._test.registry.register(self, self._test.logger)
176
177 def remove_vpp_config(self):
178 self._test.vapi.gbp_recirc_add_del(
179 0,
180 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000181 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700182 self.is_ext)
183
Neale Ranns25b04942018-04-04 09:34:50 -0700184 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700185 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700186
187 def query_vpp_config(self):
188 rs = self._test.vapi.gbp_recirc_dump()
189 for r in rs:
190 if r.recirc.sw_if_index == self.recirc.sw_if_index:
191 return True
192 return False
193
194
Neale Rannsb6a47952018-11-21 05:44:35 -0800195class VppGbpExtItf(VppObject):
196 """
197 GBP ExtItfulation Interface
198 """
199
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200200 def __init__(self, test, itf, bd, rd, anon=False):
Neale Rannsb6a47952018-11-21 05:44:35 -0800201 self._test = test
202 self.itf = itf
203 self.bd = bd
204 self.rd = rd
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200205 self.flags = 1 if anon else 0
Neale Rannsb6a47952018-11-21 05:44:35 -0800206
207 def add_vpp_config(self):
208 self._test.vapi.gbp_ext_itf_add_del(
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200209 1, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
Neale Rannsb6a47952018-11-21 05:44:35 -0800210 self._test.registry.register(self, self._test.logger)
211
212 def remove_vpp_config(self):
213 self._test.vapi.gbp_ext_itf_add_del(
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200214 0, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
Neale Rannsb6a47952018-11-21 05:44:35 -0800215
Neale Rannsb6a47952018-11-21 05:44:35 -0800216 def object_id(self):
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200217 return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index,
218 " [anon]" if self.flags else "")
Neale Rannsb6a47952018-11-21 05:44:35 -0800219
220 def query_vpp_config(self):
221 rs = self._test.vapi.gbp_ext_itf_dump()
222 for r in rs:
223 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
224 return True
225 return False
226
227
Neale Ranns25b04942018-04-04 09:34:50 -0700228class VppGbpSubnet(VppObject):
229 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200230 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700231 """
Filip Vargaf4749ca2019-04-25 14:55:32 +0200232
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700233 def __init__(self, test, rd, address, address_len,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700234 type, sw_if_index=None, sclass=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700235 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700236 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200237 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700238 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700239 self.sw_if_index = sw_if_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700240 self.sclass = sclass
Neale Ranns25b04942018-04-04 09:34:50 -0700241
242 def add_vpp_config(self):
243 self._test.vapi.gbp_subnet_add_del(
244 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700245 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200246 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700247 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700248 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700249 sclass=self.sclass if self.sclass else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700250 self._test.registry.register(self, self._test.logger)
251
252 def remove_vpp_config(self):
253 self._test.vapi.gbp_subnet_add_del(
254 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700255 self.rd_id,
256 self.prefix.encode(),
257 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700258
Neale Ranns25b04942018-04-04 09:34:50 -0700259 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700260 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700261
262 def query_vpp_config(self):
263 ss = self._test.vapi.gbp_subnet_dump()
264 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700265 if s.subnet.rd_id == self.rd_id and \
Filip Vargaf4749ca2019-04-25 14:55:32 +0200266 s.subnet.type == self.type and \
267 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700268 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700269 return False
270
271
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800272class VppGbpEndpointRetention(object):
273 def __init__(self, remote_ep_timeout=0xffffffff):
274 self.remote_ep_timeout = remote_ep_timeout
275
276 def encode(self):
277 return {'remote_ep_timeout': self.remote_ep_timeout}
278
279
Neale Ranns25b04942018-04-04 09:34:50 -0700280class VppGbpEndpointGroup(VppObject):
281 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200282 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700283 """
284
Neale Ranns4ba67722019-02-28 11:11:39 +0000285 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800286 bvi, bvi_ip4, bvi_ip6=None,
287 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700288 self._test = test
289 self.uplink = uplink
290 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700291 self.bvi_ip4 = VppIpAddress(bvi_ip4)
292 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000293 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700294 self.bd = bd
295 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800296 self.sclass = sclass
297 if 0 == self.sclass:
298 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800299 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700300
301 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700302 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000303 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800304 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700305 self.bd.bd.bd_id,
306 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800307 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
308 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700309 self._test.registry.register(self, self._test.logger)
310
311 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000312 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700313
Neale Ranns25b04942018-04-04 09:34:50 -0700314 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000315 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700316
317 def query_vpp_config(self):
318 epgs = self._test.vapi.gbp_endpoint_group_dump()
319 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000320 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800321 return True
322 return False
323
324
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700325class VppGbpBridgeDomain(VppObject):
326 """
327 GBP Bridge Domain
328 """
329
Neale Ranns160c9232019-06-19 06:25:56 -0700330 def __init__(self, test, bd, rd, bvi, uu_fwd=None,
Neale Ranns69a85b52019-06-14 07:49:50 +0000331 bm_flood=None, learn=True,
332 uu_drop=False, bm_drop=False,
333 ucast_arp=False):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700334 self._test = test
335 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800336 self.uu_fwd = uu_fwd
337 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700338 self.bd = bd
Neale Ranns160c9232019-06-19 06:25:56 -0700339 self.rd = rd
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700340
Neale Rannsc29c0af2018-11-07 04:21:12 -0800341 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
Neale Ranns69a85b52019-06-14 07:49:50 +0000342
343 self.flags = e.GBP_BD_API_FLAG_NONE
344 if not learn:
345 self.flags |= e.GBP_BD_API_FLAG_DO_NOT_LEARN
346 if uu_drop:
347 self.flags |= e.GBP_BD_API_FLAG_UU_FWD_DROP
348 if bm_drop:
349 self.flags |= e.GBP_BD_API_FLAG_MCAST_DROP
350 if ucast_arp:
351 self.flags |= e.GBP_BD_API_FLAG_UCAST_ARP
Neale Rannsc29c0af2018-11-07 04:21:12 -0800352
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700353 def add_vpp_config(self):
354 self._test.vapi.gbp_bridge_domain_add(
355 self.bd.bd_id,
Neale Ranns160c9232019-06-19 06:25:56 -0700356 self.rd.rd_id,
Neale Ranns69a85b52019-06-14 07:49:50 +0000357 self.flags,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700358 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800359 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
360 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700361 self._test.registry.register(self, self._test.logger)
362
363 def remove_vpp_config(self):
364 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
365
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700366 def object_id(self):
367 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
368
369 def query_vpp_config(self):
370 bds = self._test.vapi.gbp_bridge_domain_dump()
371 for bd in bds:
372 if bd.bd.bd_id == self.bd.bd_id:
373 return True
374 return False
375
376
377class VppGbpRouteDomain(VppObject):
378 """
379 GBP Route Domain
380 """
381
Neale Ranns160c9232019-06-19 06:25:56 -0700382 def __init__(self, test, rd_id, scope, t4, t6, ip4_uu=None, ip6_uu=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700383 self._test = test
384 self.rd_id = rd_id
Neale Ranns160c9232019-06-19 06:25:56 -0700385 self.scope = scope
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700386 self.t4 = t4
387 self.t6 = t6
388 self.ip4_uu = ip4_uu
389 self.ip6_uu = ip6_uu
390
391 def add_vpp_config(self):
392 self._test.vapi.gbp_route_domain_add(
393 self.rd_id,
Neale Ranns160c9232019-06-19 06:25:56 -0700394 self.scope,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700395 self.t4.table_id,
396 self.t6.table_id,
397 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
398 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
399 self._test.registry.register(self, self._test.logger)
400
401 def remove_vpp_config(self):
402 self._test.vapi.gbp_route_domain_del(self.rd_id)
403
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700404 def object_id(self):
405 return "gbp-route-domain:[%d]" % (self.rd_id)
406
407 def query_vpp_config(self):
408 rds = self._test.vapi.gbp_route_domain_dump()
409 for rd in rds:
410 if rd.rd.rd_id == self.rd_id:
411 return True
412 return False
413
414
Neale Ranns13a08cc2018-11-07 09:25:54 -0800415class VppGbpContractNextHop():
416 def __init__(self, mac, bd, ip, rd):
417 self.mac = mac
418 self.ip = ip
419 self.bd = bd
420 self.rd = rd
421
422 def encode(self):
423 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100424 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800425 'bd_id': self.bd.bd.bd_id,
426 'rd_id': self.rd.rd_id}
427
428
429class VppGbpContractRule():
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400430 def __init__(self, action, hash_mode, nhs=None):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800431 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100432 self.hash_mode = hash_mode
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400433 self.nhs = [] if nhs is None else nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800434
435 def encode(self):
436 nhs = []
437 for nh in self.nhs:
438 nhs.append(nh.encode())
439 while len(nhs) < 8:
440 nhs.append({})
441 return {'action': self.action,
442 'nh_set': {
443 'hash_mode': self.hash_mode,
444 'n_nhs': len(self.nhs),
445 'nhs': nhs}}
446
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400447 def __repr__(self):
448 return '<VppGbpContractRule action=%s, hash_mode=%s>' % (
449 self.action, self.hash_mode)
450
Neale Ranns13a08cc2018-11-07 09:25:54 -0800451
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800452class VppGbpContract(VppObject):
453 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200454 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800455 """
456
Neale Ranns160c9232019-06-19 06:25:56 -0700457 def __init__(self, test, scope, sclass, dclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800458 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800459 self._test = test
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400460 if not isinstance(rules, list):
461 raise ValueError("'rules' must be a list.")
462 if not isinstance(allowed_ethertypes, list):
463 raise ValueError("'allowed_ethertypes' must be a list.")
Neale Ranns160c9232019-06-19 06:25:56 -0700464 self.scope = scope
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800465 self.acl_index = acl_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700466 self.sclass = sclass
467 self.dclass = dclass
Neale Ranns13a08cc2018-11-07 09:25:54 -0800468 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800469 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700470 while (len(self.allowed_ethertypes) < 16):
471 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800472
473 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800474 rules = []
475 for r in self.rules:
476 rules.append(r.encode())
Neale Ranns796c84b2019-03-28 07:56:23 -0700477 r = self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400478 is_add=1,
479 contract={
480 'acl_index': self.acl_index,
Neale Ranns160c9232019-06-19 06:25:56 -0700481 'scope': self.scope,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400482 'sclass': self.sclass,
483 'dclass': self.dclass,
484 'n_rules': len(rules),
485 'rules': rules,
486 'n_ether_types': len(self.allowed_ethertypes),
487 'allowed_ethertypes': self.allowed_ethertypes})
Neale Ranns796c84b2019-03-28 07:56:23 -0700488 self.stats_index = r.stats_index
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800489 self._test.registry.register(self, self._test.logger)
490
491 def remove_vpp_config(self):
492 self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400493 is_add=0,
494 contract={
495 'acl_index': self.acl_index,
Neale Ranns160c9232019-06-19 06:25:56 -0700496 'scope': self.scope,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400497 'sclass': self.sclass,
498 'dclass': self.dclass,
499 'n_rules': 0,
500 'rules': [],
501 'n_ether_types': len(self.allowed_ethertypes),
Neale Ranns160c9232019-06-19 06:25:56 -0700502 'allowed_ethertypes': self.allowed_ethertypes})
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800503
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800504 def object_id(self):
Neale Ranns160c9232019-06-19 06:25:56 -0700505 return "gbp-contract:[%d:%d:%d:%d]" % (self.scope,
506 self.sclass,
507 self.dclass,
508 self.acl_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800509
510 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700511 cs = self._test.vapi.gbp_contract_dump()
512 for c in cs:
Neale Ranns160c9232019-06-19 06:25:56 -0700513 if c.contract.scope == self.scope \
514 and c.contract.sclass == self.sclass \
515 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800516 return True
517 return False
518
Neale Ranns796c84b2019-03-28 07:56:23 -0700519 def get_drop_stats(self):
520 c = self._test.statistics.get_counter("/net/gbp/contract/drop")
521 return c[0][self.stats_index]
522
523 def get_permit_stats(self):
524 c = self._test.statistics.get_counter("/net/gbp/contract/permit")
525 return c[0][self.stats_index]
526
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800527
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700528class VppGbpVxlanTunnel(VppInterface):
529 """
530 GBP VXLAN tunnel
531 """
532
Neale Ranns8da9fc62019-03-04 14:08:11 -0800533 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700534 super(VppGbpVxlanTunnel, self).__init__(test)
535 self._test = test
536 self.vni = vni
537 self.bd_rd_id = bd_rd_id
538 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800539 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700540
541 def add_vpp_config(self):
542 r = self._test.vapi.gbp_vxlan_tunnel_add(
543 self.vni,
544 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800545 self.mode,
546 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700547 self.set_sw_if_index(r.sw_if_index)
548 self._test.registry.register(self, self._test.logger)
549
550 def remove_vpp_config(self):
551 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
552
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700553 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800554 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700555
556 def query_vpp_config(self):
557 return find_gbp_vxlan(self._test, self.vni)
558
559
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200560class VppGbpAcl(VppObject):
561 """
562 GBP Acl
563 """
564
565 def __init__(self, test):
566 self._test = test
567 self.acl_index = 4294967295
568
569 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800570 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
571 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200572 dport_from=0, dport_to=65535):
573 if proto == -1 or proto == 0:
574 sport_to = 0
575 dport_to = sport_to
576 elif proto == 1 or proto == 58:
577 sport_to = 255
578 dport_to = sport_to
579 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
580 'srcport_or_icmptype_first': sport_from,
581 'srcport_or_icmptype_last': sport_to,
582 'src_ip_prefix_len': s_prefix,
583 'src_ip_addr': s_ip,
584 'dstport_or_icmpcode_first': dport_from,
585 'dstport_or_icmpcode_last': dport_to,
586 'dst_ip_prefix_len': d_prefix,
587 'dst_ip_addr': d_ip})
588 return rule
589
590 def add_vpp_config(self, rules):
591
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400592 reply = self._test.vapi.acl_add_replace(acl_index=self.acl_index,
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200593 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800594 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200595 self.acl_index = reply.acl_index
596 return self.acl_index
597
598 def remove_vpp_config(self):
599 self._test.vapi.acl_del(self.acl_index)
600
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200601 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700602 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200603
604 def query_vpp_config(self):
605 cs = self._test.vapi.acl_dump()
606 for c in cs:
607 if c.acl_index == self.acl_index:
608 return True
609 return False
610
611
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800612class TestGBP(VppTestCase):
613 """ GBP Test Case """
614
Filip Vargadd1e3e72019-04-15 18:52:43 +0200615 @property
616 def config_flags(self):
617 return VppEnum.vl_api_nat_config_flags_t
618
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700619 @classmethod
620 def setUpClass(cls):
621 super(TestGBP, cls).setUpClass()
622
623 @classmethod
624 def tearDownClass(cls):
625 super(TestGBP, cls).tearDownClass()
626
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800627 def setUp(self):
628 super(TestGBP, self).setUp()
629
Neale Ranns25b04942018-04-04 09:34:50 -0700630 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700631 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700632
Ole Troan8006c6a2018-12-17 12:02:26 +0100633 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800634
635 for i in self.pg_interfaces:
636 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700637 for i in self.lo_interfaces:
638 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800639
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200640 self.vlan_100 = VppDot1QSubint(self, self.pg0, 100)
641 self.vlan_100.admin_up()
642 self.vlan_101 = VppDot1QSubint(self, self.pg0, 101)
643 self.vlan_101.admin_up()
644 self.vlan_102 = VppDot1QSubint(self, self.pg0, 102)
645 self.vlan_102.admin_up()
646
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800647 def tearDown(self):
648 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700649 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800650 super(TestGBP, self).tearDown()
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200651 self.vlan_102.remove_vpp_config()
652 self.vlan_101.remove_vpp_config()
653 self.vlan_100.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800654
Neale Ranns25b04942018-04-04 09:34:50 -0700655 def send_and_expect_bridged(self, src, tx, dst):
656 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800657
Neale Ranns25b04942018-04-04 09:34:50 -0700658 for r in rx:
659 self.assertEqual(r[Ether].src, tx[0][Ether].src)
660 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
661 self.assertEqual(r[IP].src, tx[0][IP].src)
662 self.assertEqual(r[IP].dst, tx[0][IP].dst)
663 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800664
Neale Ranns25b04942018-04-04 09:34:50 -0700665 def send_and_expect_bridged6(self, src, tx, dst):
666 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800667
Neale Ranns25b04942018-04-04 09:34:50 -0700668 for r in rx:
669 self.assertEqual(r[Ether].src, tx[0][Ether].src)
670 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
671 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
672 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
673 return rx
674
675 def send_and_expect_routed(self, src, tx, dst, src_mac):
676 rx = self.send_and_expect(src, tx, dst)
677
678 for r in rx:
679 self.assertEqual(r[Ether].src, src_mac)
680 self.assertEqual(r[Ether].dst, dst.remote_mac)
681 self.assertEqual(r[IP].src, tx[0][IP].src)
682 self.assertEqual(r[IP].dst, tx[0][IP].dst)
683 return rx
684
Neale Ranns69a85b52019-06-14 07:49:50 +0000685 def send_and_expect_routed6(self, src, tx, dst, src_mac):
686 rx = self.send_and_expect(src, tx, dst)
687
688 for r in rx:
689 self.assertEqual(r[Ether].src, src_mac)
690 self.assertEqual(r[Ether].dst, dst.remote_mac)
691 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
692 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
693 return rx
694
Neale Ranns25b04942018-04-04 09:34:50 -0700695 def send_and_expect_natted(self, src, tx, dst, src_ip):
696 rx = self.send_and_expect(src, tx, dst)
697
698 for r in rx:
699 self.assertEqual(r[Ether].src, tx[0][Ether].src)
700 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
701 self.assertEqual(r[IP].src, src_ip)
702 self.assertEqual(r[IP].dst, tx[0][IP].dst)
703 return rx
704
Neale Ranns4a6d0232018-04-24 07:45:33 -0700705 def send_and_expect_natted6(self, src, tx, dst, src_ip):
706 rx = self.send_and_expect(src, tx, dst)
707
708 for r in rx:
709 self.assertEqual(r[Ether].src, tx[0][Ether].src)
710 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
711 self.assertEqual(r[IPv6].src, src_ip)
712 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
713 return rx
714
Neale Ranns25b04942018-04-04 09:34:50 -0700715 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
716 rx = self.send_and_expect(src, tx, dst)
717
718 for r in rx:
719 self.assertEqual(r[Ether].src, tx[0][Ether].src)
720 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
721 self.assertEqual(r[IP].dst, dst_ip)
722 self.assertEqual(r[IP].src, tx[0][IP].src)
723 return rx
724
Neale Ranns4a6d0232018-04-24 07:45:33 -0700725 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
726 rx = self.send_and_expect(src, tx, dst)
727
728 for r in rx:
729 self.assertEqual(r[Ether].src, tx[0][Ether].src)
730 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
731 self.assertEqual(r[IPv6].dst, dst_ip)
732 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
733 return rx
734
Neale Ranns25b04942018-04-04 09:34:50 -0700735 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
736 rx = self.send_and_expect(src, tx, dst)
737
738 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100739 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700740 self.assertEqual(r[Ether].dst, dst.remote_mac)
741 self.assertEqual(r[IP].dst, dst_ip)
742 self.assertEqual(r[IP].src, src_ip)
743 return rx
744
Neale Ranns4a6d0232018-04-24 07:45:33 -0700745 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
746 rx = self.send_and_expect(src, tx, dst)
747
748 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100749 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700750 self.assertEqual(r[Ether].dst, dst.remote_mac)
751 self.assertEqual(r[IPv6].dst, dst_ip)
752 self.assertEqual(r[IPv6].src, src_ip)
753 return rx
754
Mohsin Kazmife52dea2019-04-18 15:54:58 +0200755 def send_and_expect_no_arp(self, src, tx, dst):
756 self.pg_send(src, tx)
757 dst.get_capture(0, timeout=1)
758 dst.assert_nothing_captured(remark="")
759 timeout = 0.1
760
761 def send_and_expect_arp(self, src, tx, dst):
762 rx = self.send_and_expect(src, tx, dst)
763
764 for r in rx:
765 self.assertEqual(r[Ether].src, tx[0][Ether].src)
766 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
767 self.assertEqual(r[ARP].psrc, tx[0][ARP].psrc)
768 self.assertEqual(r[ARP].pdst, tx[0][ARP].pdst)
769 self.assertEqual(r[ARP].hwsrc, tx[0][ARP].hwsrc)
770 self.assertEqual(r[ARP].hwdst, tx[0][ARP].hwdst)
771 return rx
772
Neale Ranns25b04942018-04-04 09:34:50 -0700773 def test_gbp(self):
774 """ Group Based Policy """
775
Neale Rannsb6a47952018-11-21 05:44:35 -0800776 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
777
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800778 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700779 # Route Domains
780 #
781 gt4 = VppIpTable(self, 0)
782 gt4.add_vpp_config()
783 gt6 = VppIpTable(self, 0, is_ip6=True)
784 gt6.add_vpp_config()
785 nt4 = VppIpTable(self, 20)
786 nt4.add_vpp_config()
787 nt6 = VppIpTable(self, 20, is_ip6=True)
788 nt6.add_vpp_config()
789
Neale Ranns160c9232019-06-19 06:25:56 -0700790 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
791 rd20 = VppGbpRouteDomain(self, 20, 420, nt4, nt6, None, None)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700792
793 rd0.add_vpp_config()
794 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700795
796 #
Neale Ranns160c9232019-06-19 06:25:56 -0700797 # Bridge Domains
798 #
799 bd1 = VppBridgeDomain(self, 1)
800 bd2 = VppBridgeDomain(self, 2)
801 bd20 = VppBridgeDomain(self, 20)
802
803 bd1.add_vpp_config()
804 bd2.add_vpp_config()
805 bd20.add_vpp_config()
806
807 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
808 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
809 gbd20 = VppGbpBridgeDomain(self, bd20, rd20, self.loop2)
810
811 gbd1.add_vpp_config()
812 gbd2.add_vpp_config()
813 gbd20.add_vpp_config()
814
815 #
Neale Ranns25b04942018-04-04 09:34:50 -0700816 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700817 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
818 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000819 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
820 self.pg4, self.loop0,
821 "10.0.0.128", "2001:10::128"),
822 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
823 self.pg5, self.loop0,
824 "10.0.1.128", "2001:10:1::128"),
825 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
826 self.pg6, self.loop1,
827 "10.0.2.128", "2001:10:2::128"),
828 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
829 self.pg7, self.loop2,
830 "11.0.0.128", "3001::128"),
831 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
832 self.pg8, self.loop2,
833 "11.0.0.129", "3001::129")]
834 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
835 VppGbpRecirc(self, epgs[1], self.loop4),
836 VppGbpRecirc(self, epgs[2], self.loop5),
837 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
838 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700839
840 epg_nat = epgs[3]
841 recirc_nat = recircs[3]
842
843 #
844 # 4 end-points, 2 in the same subnet, 3 in the same BD
845 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700846 eps = [VppGbpEndpoint(self, self.pg0,
847 epgs[0], recircs[0],
848 "10.0.0.1", "11.0.0.1",
849 "2001:10::1", "3001::1"),
850 VppGbpEndpoint(self, self.pg1,
851 epgs[0], recircs[0],
852 "10.0.0.2", "11.0.0.2",
853 "2001:10::2", "3001::2"),
854 VppGbpEndpoint(self, self.pg2,
855 epgs[1], recircs[1],
856 "10.0.1.1", "11.0.0.3",
857 "2001:10:1::1", "3001::3"),
858 VppGbpEndpoint(self, self.pg3,
859 epgs[2], recircs[2],
860 "10.0.2.1", "11.0.0.4",
861 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700862
863 #
864 # Config related to each of the EPGs
865 #
866 for epg in epgs:
867 # IP config on the BVI interfaces
868 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700869 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
870 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
871 self.vapi.sw_interface_set_mac_address(
872 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100873 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700874
875 # The BVIs are NAT inside interfaces
Filip Vargadd1e3e72019-04-15 18:52:43 +0200876 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +0200877 self.vapi.nat44_interface_add_del_feature(
878 sw_if_index=epg.bvi.sw_if_index,
879 flags=flags, is_add=1)
880 self.vapi.nat66_add_del_interface(
881 is_add=1, flags=flags,
882 sw_if_index=epg.bvi.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700883
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700884 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
885 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
886 if_ip4.add_vpp_config()
887 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700888
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700889 # EPG uplink interfaces in the RD
890 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
891 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700892
893 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700894 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100895 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -0700896 epg.bvi_ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700897 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100898 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -0700899 epg.bvi_ip6.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700900 epg.bd_arp_ip4.add_vpp_config()
901 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700902
903 # EPG in VPP
904 epg.add_vpp_config()
905
906 for recirc in recircs:
907 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700908 VppIpInterfaceBind(self, recirc.recirc,
909 recirc.epg.rd.t4).add_vpp_config()
910 VppIpInterfaceBind(self, recirc.recirc,
911 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700912
Neale Ranns4a6d0232018-04-24 07:45:33 -0700913 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200914 sw_if_index=recirc.recirc.sw_if_index, is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700915 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200916 is_add=1,
917 sw_if_index=recirc.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700918
919 recirc.add_vpp_config()
920
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700921 for recirc in recircs:
922 self.assertTrue(find_bridge_domain_port(self,
923 recirc.epg.bd.bd.bd_id,
924 recirc.recirc.sw_if_index))
925
Neale Ranns25b04942018-04-04 09:34:50 -0700926 for ep in eps:
927 self.pg_enable_capture(self.pg_interfaces)
928 self.pg_start()
929 #
930 # routes to the endpoints. We need these since there are no
931 # adj-fibs due to the fact the the BVI address has /32 and
932 # the subnet is not attached.
933 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700934 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700935 # Add static mappings for each EP from the 10/8 to 11/8 network
936 if ip.af == AF_INET:
Filip Vargadd1e3e72019-04-15 18:52:43 +0200937 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +0200938 self.vapi.nat44_add_del_static_mapping(
939 is_add=1,
940 local_ip_address=ip.bytes,
941 external_ip_address=fip.bytes,
942 external_sw_if_index=0xFFFFFFFF,
943 vrf_id=0,
944 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -0700945 else:
Filip Vargaf4749ca2019-04-25 14:55:32 +0200946 self.vapi.nat66_add_del_static_mapping(
947 local_ip_address=ip.bytes,
948 external_ip_address=fip.bytes,
949 vrf_id=0, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700950
Neale Ranns25b04942018-04-04 09:34:50 -0700951 # VPP EP create ...
952 ep.add_vpp_config()
953
Neale Rannsc0a93142018-09-05 15:42:26 -0700954 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700955
Neale Rannsc0a93142018-09-05 15:42:26 -0700956 # ... results in a Gratuitous ARP/ND on the EPG's uplink
957 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
958
959 for ii, ip in enumerate(ep.ips):
960 p = rx[ii]
961
962 if ip.is_ip6:
963 self.assertTrue(p.haslayer(ICMPv6ND_NA))
964 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
965 else:
966 self.assertTrue(p.haslayer(ARP))
967 self.assertEqual(p[ARP].psrc, ip.address)
968 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700969
970 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700971 for fip in ep.fips:
Neale Rannsbc764c82019-06-19 07:07:13 -0700972 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac,
973 fip.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700974 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700975
Neale Rannsc0a93142018-09-05 15:42:26 -0700976 # floating IPs route via EPG recirc
Neale Ranns097fa662018-05-01 05:17:55 -0700977 r = VppIpRoute(
978 self, fip.address, fip.length,
979 [VppRoutePath(fip.address,
980 ep.recirc.recirc.sw_if_index,
981 type=FibPathType.FIB_PATH_TYPE_DVR,
982 proto=fip.dpo_proto)],
983 table_id=20)
Neale Rannsc0a93142018-09-05 15:42:26 -0700984 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700985
986 # L2 FIB entries in the NAT EPG BD to bridge the packets from
987 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700988 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
989 ep.recirc.recirc, bvi_mac=0)
990 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700991
992 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700993 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700994 #
995 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
996 src=self.pg0.remote_mac) /
997 ARP(op="who-has",
998 hwdst="ff:ff:ff:ff:ff:ff",
999 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001000 pdst="10.0.0.88",
1001 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -07001002
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001003 self.vapi.cli("clear trace")
1004 self.pg0.add_stream(pkt_arp)
1005
1006 self.pg_enable_capture(self.pg_interfaces)
1007 self.pg_start()
1008
1009 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -07001010
1011 #
1012 # ARP/ND packets get a response
1013 #
1014 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
1015 src=self.pg0.remote_mac) /
1016 ARP(op="who-has",
1017 hwdst="ff:ff:ff:ff:ff:ff",
1018 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001019 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -07001020 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -07001021
1022 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
1023
Neale Rannsc0a93142018-09-05 15:42:26 -07001024 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -07001025 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001026 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
1027 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001028 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -07001029 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001030 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
1031 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
1032
1033 #
1034 # broadcast packets are flooded
1035 #
1036 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
1037 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001038 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001039 UDP(sport=1234, dport=1234) /
1040 Raw('\xa5' * 100))
1041
1042 self.vapi.cli("clear trace")
1043 self.pg0.add_stream(pkt_bcast)
1044
1045 self.pg_enable_capture(self.pg_interfaces)
1046 self.pg_start()
1047
1048 rxd = eps[1].itf.get_capture(1)
1049 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1050 rxd = epgs[0].uplink.get_capture(1)
1051 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1052
1053 #
1054 # packets to non-local L3 destinations dropped
1055 #
1056 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001057 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001058 IP(src=eps[0].ip4.address,
1059 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001060 UDP(sport=1234, dport=1234) /
1061 Raw('\xa5' * 100))
1062 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001063 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001064 IP(src=eps[0].ip4.address,
1065 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001066 UDP(sport=1234, dport=1234) /
1067 Raw('\xa5' * 100))
1068
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001069 self.send_and_assert_no_replies(self.pg0,
1070 pkt_intra_epg_220_ip4 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001071
1072 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001073 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001074 IPv6(src=eps[0].ip6.address,
1075 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001076 UDP(sport=1234, dport=1234) /
1077 Raw('\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001078 self.send_and_assert_no_replies(self.pg0,
1079 pkt_inter_epg_222_ip6 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001080
1081 #
1082 # Add the subnet routes
1083 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001084 s41 = VppGbpSubnet(
1085 self, rd0, "10.0.0.0", 24,
1086 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1087 s42 = VppGbpSubnet(
1088 self, rd0, "10.0.1.0", 24,
1089 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1090 s43 = VppGbpSubnet(
1091 self, rd0, "10.0.2.0", 24,
1092 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1093 s61 = VppGbpSubnet(
1094 self, rd0, "2001:10::1", 64,
1095 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1096 s62 = VppGbpSubnet(
1097 self, rd0, "2001:10:1::1", 64,
1098 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1099 s63 = VppGbpSubnet(
1100 self, rd0, "2001:10:2::1", 64,
1101 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001102 s41.add_vpp_config()
1103 s42.add_vpp_config()
1104 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001105 s61.add_vpp_config()
1106 s62.add_vpp_config()
1107 s63.add_vpp_config()
1108
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001109 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001110 pkt_intra_epg_220_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001111 eps[0].epg.uplink)
1112 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001113 pkt_inter_epg_222_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001114 eps[0].epg.uplink)
1115 self.send_and_expect_bridged6(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001116 pkt_inter_epg_222_ip6 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001117 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001118
1119 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1120 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1121 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1122 self.logger.info(self.vapi.cli("sh gbp recirc"))
1123 self.logger.info(self.vapi.cli("sh int"))
1124 self.logger.info(self.vapi.cli("sh int addr"))
1125 self.logger.info(self.vapi.cli("sh int feat loop6"))
1126 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1127 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001128 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001129
1130 #
1131 # Packet destined to unknown unicast is sent on the epg uplink ...
1132 #
1133 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1134 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001135 IP(src=eps[0].ip4.address,
1136 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001137 UDP(sport=1234, dport=1234) /
1138 Raw('\xa5' * 100))
1139
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001140 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001141 pkt_intra_epg_220_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001142 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001143 # ... and nowhere else
1144 self.pg1.get_capture(0, timeout=0.1)
1145 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1146
1147 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1148 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001149 IP(src=eps[0].ip4.address,
1150 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001151 UDP(sport=1234, dport=1234) /
1152 Raw('\xa5' * 100))
1153
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001154 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001155 pkt_intra_epg_221_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001156 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001157
1158 #
1159 # Packets from the uplink are forwarded in the absence of a contract
1160 #
1161 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1162 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001163 IP(src=eps[0].ip4.address,
1164 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001165 UDP(sport=1234, dport=1234) /
1166 Raw('\xa5' * 100))
1167
1168 self.send_and_expect_bridged(self.pg4,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001169 pkt_intra_epg_220_from_uplink * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001170 self.pg0)
1171
1172 #
1173 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001174 # can communicate
1175 #
1176 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001177 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001178 IP(src=eps[0].ip4.address,
1179 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001180 UDP(sport=1234, dport=1234) /
1181 Raw('\xa5' * 100))
1182
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001183 self.send_and_expect_bridged(self.pg0,
1184 pkt_intra_epg * NUM_PKTS,
1185 self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001186
1187 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001188 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001189 # cannot communicate
1190 #
1191 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001192 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001193 IP(src=eps[0].ip4.address,
1194 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001195 UDP(sport=1234, dport=1234) /
1196 Raw('\xa5' * 100))
1197 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001198 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001199 IP(src=eps[2].ip4.address,
1200 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001201 UDP(sport=1234, dport=1234) /
1202 Raw('\xa5' * 100))
1203 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001204 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001205 IP(src=eps[0].ip4.address,
1206 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001207 UDP(sport=1234, dport=1234) /
1208 Raw('\xa5' * 100))
1209
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001210 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001211 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001212 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001213 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001214
1215 #
1216 # A uni-directional contract from EPG 220 -> 221
1217 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001218 acl = VppGbpAcl(self)
1219 rule = acl.create_rule(permit_deny=1, proto=17)
1220 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1221 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001222 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001223 self, 400, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001224 [VppGbpContractRule(
1225 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001226 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001227 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001228 VppGbpContractRule(
1229 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001230 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001231 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001232 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001233 c1.add_vpp_config()
1234
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001235 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001236 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001237 eps[2].itf)
1238 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001239 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001240
1241 #
1242 # contract for the return direction
1243 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001244 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001245 self, 400, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001246 [VppGbpContractRule(
1247 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001248 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001249 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001250 VppGbpContractRule(
1251 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001252 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001253 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001254 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001255 c2.add_vpp_config()
1256
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001257 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001258 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001259 eps[2].itf)
1260 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001261 pkt_inter_epg_221_to_220 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001262 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001263
Neale Ranns796c84b2019-03-28 07:56:23 -07001264 ds = c2.get_drop_stats()
1265 self.assertEqual(ds['packets'], 0)
1266 ps = c2.get_permit_stats()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001267 self.assertEqual(ps['packets'], NUM_PKTS)
Neale Ranns796c84b2019-03-28 07:56:23 -07001268
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001269 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001270 # the contract does not allow non-IP
1271 #
1272 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1273 dst=self.pg2.remote_mac) /
1274 ARP())
1275 self.send_and_assert_no_replies(eps[0].itf,
1276 pkt_non_ip_inter_epg_220_to_221 * 17)
1277
1278 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001279 # check that inter group is still disabled for the groups
1280 # not in the contract.
1281 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001282 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001283 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001284
Neale Ranns25b04942018-04-04 09:34:50 -07001285 #
1286 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1287 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001288 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001289 self, 400, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001290 [VppGbpContractRule(
1291 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001292 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001293 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001294 VppGbpContractRule(
1295 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001296 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001297 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001298 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001299 c3.add_vpp_config()
1300
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001301 self.logger.info(self.vapi.cli("sh gbp contract"))
1302
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001303 self.send_and_expect_routed(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001304 pkt_inter_epg_220_to_222 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001305 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001306 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001307
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001308 #
1309 # remove both contracts, traffic stops in both directions
1310 #
1311 c2.remove_vpp_config()
1312 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001313 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001314 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001315
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001316 self.send_and_assert_no_replies(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001317 pkt_inter_epg_221_to_220 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001318 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001319 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001320 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001321 pkt_intra_epg * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001322 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001323
1324 #
Neale Ranns25b04942018-04-04 09:34:50 -07001325 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001326 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001327
Neale Ranns25b04942018-04-04 09:34:50 -07001328 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001329 se1 = VppGbpSubnet(
1330 self, rd0, "0.0.0.0", 0,
1331 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1332 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001333 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001334 se2 = VppGbpSubnet(
1335 self, rd0, "11.0.0.0", 8,
1336 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1337 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001338 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001339 se16 = VppGbpSubnet(
1340 self, rd0, "::", 0,
1341 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1342 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001343 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001344 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001345 se3 = VppGbpSubnet(
1346 self, rd20, "0.0.0.0", 0,
1347 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1348 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001349 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001350 se36 = VppGbpSubnet(
1351 self, rd20, "::", 0,
1352 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1353 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001354 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001355 se4 = VppGbpSubnet(
1356 self, rd20, "11.0.0.0", 8,
1357 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1358 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001359 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001360 se1.add_vpp_config()
1361 se2.add_vpp_config()
1362 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001363 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001364 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001365 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001366
Neale Ranns25b04942018-04-04 09:34:50 -07001367 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1368 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001369 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1370 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001371 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001372
Neale Ranns4a6d0232018-04-24 07:45:33 -07001373 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001374 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001375 #
Neale Ranns25b04942018-04-04 09:34:50 -07001376 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001377 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001378 IP(src=eps[0].ip4.address,
1379 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001380 UDP(sport=1234, dport=1234) /
1381 Raw('\xa5' * 100))
1382
1383 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001384 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001385 pkt_inter_epg_220_to_global * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001386
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001387 acl2 = VppGbpAcl(self)
1388 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1389 sport_to=1234, dport_from=1234, dport_to=1234)
1390 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1391 sport_from=1234, sport_to=1234,
1392 dport_from=1234, dport_to=1234)
1393
1394 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001395 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001396 self, 400, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001397 [VppGbpContractRule(
1398 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001399 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001400 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001401 VppGbpContractRule(
1402 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001403 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001404 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001405 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001406 c4.add_vpp_config()
1407
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001408 self.send_and_expect_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001409 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001410 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001411 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001412
Neale Ranns4a6d0232018-04-24 07:45:33 -07001413 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001414 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001415 IPv6(src=eps[0].ip6.address,
1416 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001417 UDP(sport=1234, dport=1234) /
1418 Raw('\xa5' * 100))
1419
1420 self.send_and_expect_natted6(self.pg0,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001421 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001422 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001423 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001424
1425 #
1426 # From a global address to an EP: OUT2IN
1427 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001428 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001429 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001430 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001431 src="1.1.1.1") /
1432 UDP(sport=1234, dport=1234) /
1433 Raw('\xa5' * 100))
1434
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001435 self.send_and_assert_no_replies(
1436 self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001437
Neale Ranns13a08cc2018-11-07 09:25:54 -08001438 c5 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001439 self, 400, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001440 [VppGbpContractRule(
1441 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001442 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001443 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001444 VppGbpContractRule(
1445 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001446 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001447 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001448 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001449 c5.add_vpp_config()
1450
1451 self.send_and_expect_unnatted(self.pg7,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001452 pkt_inter_epg_220_from_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001453 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001454 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001455
Ole Troan8006c6a2018-12-17 12:02:26 +01001456 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001457 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001458 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001459 src="6001::1") /
1460 UDP(sport=1234, dport=1234) /
1461 Raw('\xa5' * 100))
1462
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001463 self.send_and_expect_unnatted6(
1464 self.pg7,
1465 pkt_inter_epg_220_from_global * NUM_PKTS,
1466 eps[0].itf,
1467 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001468
1469 #
1470 # From a local VM to another local VM using resp. public addresses:
1471 # IN2OUT2IN
1472 #
Neale Ranns25b04942018-04-04 09:34:50 -07001473 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001474 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001475 IP(src=eps[0].ip4.address,
1476 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001477 UDP(sport=1234, dport=1234) /
1478 Raw('\xa5' * 100))
1479
Neale Ranns4a6d0232018-04-24 07:45:33 -07001480 self.send_and_expect_double_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001481 pkt_intra_epg_220_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001482 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001483 eps[0].fip4.address,
1484 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001485
Neale Rannsc0a93142018-09-05 15:42:26 -07001486 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001487 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001488 IPv6(src=eps[0].ip6.address,
1489 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001490 UDP(sport=1234, dport=1234) /
1491 Raw('\xa5' * 100))
1492
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001493 self.send_and_expect_double_natted6(
1494 eps[0].itf,
1495 pkt_intra_epg_220_global * NUM_PKTS,
1496 eps[1].itf,
1497 eps[0].fip6.address,
1498 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001499
1500 #
Neale Ranns25b04942018-04-04 09:34:50 -07001501 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001502 #
Neale Ranns25b04942018-04-04 09:34:50 -07001503 for ep in eps:
1504 # del static mappings for each EP from the 10/8 to 11/8 network
Filip Vargadd1e3e72019-04-15 18:52:43 +02001505 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +02001506 self.vapi.nat44_add_del_static_mapping(
1507 is_add=0,
1508 local_ip_address=ep.ip4.bytes,
1509 external_ip_address=ep.fip4.bytes,
1510 external_sw_if_index=0xFFFFFFFF,
1511 vrf_id=0,
1512 flags=flags)
1513 self.vapi.nat66_add_del_static_mapping(
1514 local_ip_address=ep.ip6.bytes,
1515 external_ip_address=ep.fip6.bytes,
1516 vrf_id=0, is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001517
Neale Ranns25b04942018-04-04 09:34:50 -07001518 for epg in epgs:
1519 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001520 if epg != epgs[0] and epg != epgs[3]:
Filip Vargadd1e3e72019-04-15 18:52:43 +02001521 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +02001522 self.vapi.nat44_interface_add_del_feature(
1523 sw_if_index=epg.bvi.sw_if_index,
1524 flags=flags,
1525 is_add=0)
1526 self.vapi.nat66_add_del_interface(
1527 is_add=0, flags=flags,
1528 sw_if_index=epg.bvi.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001529
Neale Ranns25b04942018-04-04 09:34:50 -07001530 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001531 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001532 sw_if_index=recirc.recirc.sw_if_index,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001533 is_add=0)
1534 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001535 is_add=0,
1536 sw_if_index=recirc.recirc.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001537
Neale Ranns774356a2018-11-29 12:02:16 +00001538 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
Neale Ranns3eea9de2019-06-21 02:09:25 -07001539 tep=None, n_tries=100, s_time=1):
Neale Ranns774356a2018-11-29 12:02:16 +00001540 while (n_tries):
Neale Ranns3eea9de2019-06-21 02:09:25 -07001541 if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep):
Neale Ranns774356a2018-11-29 12:02:16 +00001542 return True
1543 n_tries = n_tries - 1
1544 self.sleep(s_time)
1545 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1546 return False
1547
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001548 def test_gbp_learn_l2(self):
1549 """ GBP L2 Endpoint Learning """
1550
Neale Ranns69a85b52019-06-14 07:49:50 +00001551 drop_no_contract = self.statistics.get_err_counter(
1552 '/err/gbp-policy-port/drop-no-contract')
1553 allow_intra_class = self.statistics.get_err_counter(
1554 '/err/gbp-policy-port/allow-intra-sclass')
Neale Ranns796c84b2019-03-28 07:56:23 -07001555
Neale Rannsb6a47952018-11-21 05:44:35 -08001556 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001557 learnt = [{'mac': '00:00:11:11:11:01',
1558 'ip': '10.0.0.1',
1559 'ip6': '2001:10::2'},
1560 {'mac': '00:00:11:11:11:02',
1561 'ip': '10.0.0.2',
1562 'ip6': '2001:10::3'}]
1563
1564 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001565 # IP tables
1566 #
1567 gt4 = VppIpTable(self, 1)
1568 gt4.add_vpp_config()
1569 gt6 = VppIpTable(self, 1, is_ip6=True)
1570 gt6.add_vpp_config()
1571
Neale Ranns160c9232019-06-19 06:25:56 -07001572 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001573 rd1.add_vpp_config()
1574
1575 #
1576 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1577 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1578 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1579 #
1580 self.pg2.config_ip4()
1581 self.pg2.resolve_arp()
1582 self.pg2.generate_remote_hosts(4)
1583 self.pg2.configure_ipv4_neighbors()
1584 self.pg3.config_ip4()
1585 self.pg3.resolve_arp()
1586 self.pg4.config_ip4()
1587 self.pg4.resolve_arp()
1588
1589 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001590 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1591 #
1592 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1593 "239.1.1.1", 88,
1594 mcast_itf=self.pg4)
1595 tun_bm.add_vpp_config()
1596
1597 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001598 # a GBP bridge domain with a BVI and a UU-flood interface
1599 #
1600 bd1 = VppBridgeDomain(self, 1)
1601 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07001602 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
1603 self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001604 gbd1.add_vpp_config()
1605
1606 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1607 self.logger.info(self.vapi.cli("sh gbp bridge"))
1608
1609 # ... and has a /32 applied
1610 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1611 ip_addr.add_vpp_config()
1612
1613 #
1614 # The Endpoint-group in which we are learning endpoints
1615 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001616 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001617 None, self.loop0,
1618 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001619 "2001:10::128",
1620 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001621 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001622 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001623 None, self.loop1,
1624 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001625 "2001:11::128",
1626 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001627 epg_330.add_vpp_config()
1628
1629 #
1630 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001631 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001632 #
1633 vx_tun_l2_1 = VppGbpVxlanTunnel(
1634 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001635 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1636 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001637 vx_tun_l2_1.add_vpp_config()
1638
1639 #
1640 # A static endpoint that the learnt endpoints are trying to
1641 # talk to
1642 #
1643 ep = VppGbpEndpoint(self, self.pg0,
1644 epg_220, None,
1645 "10.0.0.127", "11.0.0.127",
1646 "2001:10::1", "3001::1")
1647 ep.add_vpp_config()
1648
1649 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1650
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001651 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001652 p = (Ether(src=self.pg2.remote_mac,
1653 dst=self.pg2.local_mac) /
1654 IP(src=self.pg2.remote_hosts[0].ip4,
1655 dst=self.pg2.local_ip4) /
1656 UDP(sport=1234, dport=48879) /
1657 VXLAN(vni=99, gpid=88, flags=0x88) /
1658 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1659 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1660 UDP(sport=1234, dport=1234) /
1661 Raw('\xa5' * 100))
1662
1663 self.send_and_assert_no_replies(self.pg2, p)
1664
Neale Ranns796c84b2019-03-28 07:56:23 -07001665 self.logger.info(self.vapi.cli("sh error"))
Neale Ranns69a85b52019-06-14 07:49:50 +00001666 self.assert_error_counter_equal(
1667 '/err/gbp-policy-port/drop-no-contract',
1668 drop_no_contract + 1)
Neale Ranns796c84b2019-03-28 07:56:23 -07001669
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001670 #
1671 # we should not have learnt a new tunnel endpoint, since
1672 # the EPG was not learnt.
1673 #
1674 self.assertEqual(INDEX_INVALID,
1675 find_vxlan_gbp_tunnel(self,
1676 self.pg2.local_ip4,
1677 self.pg2.remote_hosts[0].ip4,
1678 99))
1679
Neale Ranns69a85b52019-06-14 07:49:50 +00001680 # ep is not learnt, because the EPG is unknown
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001681 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1682
Neale Ranns8da9fc62019-03-04 14:08:11 -08001683 #
1684 # Learn new EPs from IP packets
1685 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001686 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001687 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001688 # arriving on an unknown TEP
1689 p = (Ether(src=self.pg2.remote_mac,
1690 dst=self.pg2.local_mac) /
1691 IP(src=self.pg2.remote_hosts[1].ip4,
1692 dst=self.pg2.local_ip4) /
1693 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001694 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001695 Ether(src=l['mac'], dst=ep.mac) /
1696 IP(src=l['ip'], dst=ep.ip4.address) /
1697 UDP(sport=1234, dport=1234) /
1698 Raw('\xa5' * 100))
1699
1700 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1701
1702 # the new TEP
1703 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1704 self,
1705 self.pg2.local_ip4,
1706 self.pg2.remote_hosts[1].ip4,
1707 99)
1708 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1709
1710 #
1711 # the EP is learnt via the learnt TEP
1712 # both from its MAC and its IP
1713 #
1714 self.assertTrue(find_gbp_endpoint(self,
1715 vx_tun_l2_1.sw_if_index,
1716 mac=l['mac']))
1717 self.assertTrue(find_gbp_endpoint(self,
1718 vx_tun_l2_1.sw_if_index,
1719 ip=l['ip']))
1720
Neale Ranns69a85b52019-06-14 07:49:50 +00001721 self.assert_error_counter_equal(
1722 '/err/gbp-policy-port/allow-intra-sclass',
1723 allow_intra_class + 2)
Neale Ranns796c84b2019-03-28 07:56:23 -07001724
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001725 self.logger.info(self.vapi.cli("show gbp endpoint"))
1726 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001727 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001728
1729 #
1730 # If we sleep for the threshold time, the learnt endpoints should
1731 # age out
1732 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001733 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001734 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1735 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001736
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001737 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001738 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1739 #
1740 for ii, l in enumerate(learnt):
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001741 # add some junk in the reserved field of the vxlan-header
1742 # next to the VNI. we should accept since reserved bits are
1743 # ignored on rx.
Neale Ranns8da9fc62019-03-04 14:08:11 -08001744 p = (Ether(src=self.pg2.remote_mac,
1745 dst=self.pg2.local_mac) /
1746 IP(src=self.pg2.remote_hosts[1].ip4,
1747 dst="239.1.1.1") /
1748 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001749 VXLAN(vni=88, reserved2=0x80, gpid=112, flags=0x88) /
Neale Ranns8da9fc62019-03-04 14:08:11 -08001750 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1751 ARP(op="who-has",
1752 psrc=l['ip'], pdst=l['ip'],
1753 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1754
1755 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1756
1757 # the new TEP
1758 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1759 self,
1760 self.pg2.local_ip4,
1761 self.pg2.remote_hosts[1].ip4,
1762 99)
1763 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1764
1765 #
1766 # the EP is learnt via the learnt TEP
1767 # both from its MAC and its IP
1768 #
1769 self.assertTrue(find_gbp_endpoint(self,
1770 vx_tun_l2_1.sw_if_index,
1771 mac=l['mac']))
1772 self.assertTrue(find_gbp_endpoint(self,
1773 vx_tun_l2_1.sw_if_index,
1774 ip=l['ip']))
1775
1776 #
1777 # wait for the learnt endpoints to age out
1778 #
1779 for l in learnt:
1780 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1781 mac=l['mac'])
1782
1783 #
1784 # Learn new EPs from L2 packets
1785 #
1786 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001787 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001788 # arriving on an unknown TEP
1789 p = (Ether(src=self.pg2.remote_mac,
1790 dst=self.pg2.local_mac) /
1791 IP(src=self.pg2.remote_hosts[1].ip4,
1792 dst=self.pg2.local_ip4) /
1793 UDP(sport=1234, dport=48879) /
1794 VXLAN(vni=99, gpid=112, flags=0x88) /
1795 Ether(src=l['mac'], dst=ep.mac) /
1796 Raw('\xa5' * 100))
1797
1798 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1799
1800 # the new TEP
1801 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1802 self,
1803 self.pg2.local_ip4,
1804 self.pg2.remote_hosts[1].ip4,
1805 99)
1806 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1807
1808 #
1809 # the EP is learnt via the learnt TEP
1810 # both from its MAC and its IP
1811 #
1812 self.assertTrue(find_gbp_endpoint(self,
1813 vx_tun_l2_1.sw_if_index,
1814 mac=l['mac']))
1815
1816 self.logger.info(self.vapi.cli("show gbp endpoint"))
1817 self.logger.info(self.vapi.cli("show gbp vxlan"))
1818 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1819
1820 #
1821 # wait for the learnt endpoints to age out
1822 #
1823 for l in learnt:
1824 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1825 mac=l['mac'])
1826
1827 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001828 # repeat. the do not learn bit is set so the EPs are not learnt
1829 #
1830 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001831 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001832 p = (Ether(src=self.pg2.remote_mac,
1833 dst=self.pg2.local_mac) /
1834 IP(src=self.pg2.remote_hosts[1].ip4,
1835 dst=self.pg2.local_ip4) /
1836 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001837 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001838 Ether(src=l['mac'], dst=ep.mac) /
1839 IP(src=l['ip'], dst=ep.ip4.address) /
1840 UDP(sport=1234, dport=1234) /
1841 Raw('\xa5' * 100))
1842
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001843 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001844
1845 for l in learnt:
1846 self.assertFalse(find_gbp_endpoint(self,
1847 vx_tun_l2_1.sw_if_index,
1848 mac=l['mac']))
1849
1850 #
1851 # repeat
1852 #
1853 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001854 # a packet with an sclass from a known EPG
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001855 # set a reserved bit in addition to the G and I
1856 # reserved bits should not be checked on rx.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001857 p = (Ether(src=self.pg2.remote_mac,
1858 dst=self.pg2.local_mac) /
1859 IP(src=self.pg2.remote_hosts[1].ip4,
1860 dst=self.pg2.local_ip4) /
1861 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001862 VXLAN(vni=99, gpid=112, flags=0xc8) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001863 Ether(src=l['mac'], dst=ep.mac) /
1864 IP(src=l['ip'], dst=ep.ip4.address) /
1865 UDP(sport=1234, dport=1234) /
1866 Raw('\xa5' * 100))
1867
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001868 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001869
1870 self.assertTrue(find_gbp_endpoint(self,
1871 vx_tun_l2_1.sw_if_index,
1872 mac=l['mac']))
1873
1874 #
1875 # Static EP replies to dynamics
1876 #
1877 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
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 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1885
1886 for rx in rxs:
1887 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1888 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1889 self.assertEqual(rx[UDP].dport, 48879)
1890 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001891 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001892 self.assertEqual(rx[VXLAN].vni, 99)
1893 self.assertTrue(rx[VXLAN].flags.G)
1894 self.assertTrue(rx[VXLAN].flags.Instance)
1895 self.assertTrue(rx[VXLAN].gpflags.A)
1896 self.assertFalse(rx[VXLAN].gpflags.D)
1897
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001898 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001899 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1900 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001901
1902 #
1903 # repeat in the other EPG
1904 # there's no contract between 220 and 330, but the A-bit is set
1905 # so the packet is cleared for delivery
1906 #
1907 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001908 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001909 p = (Ether(src=self.pg2.remote_mac,
1910 dst=self.pg2.local_mac) /
1911 IP(src=self.pg2.remote_hosts[1].ip4,
1912 dst=self.pg2.local_ip4) /
1913 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001914 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001915 Ether(src=l['mac'], dst=ep.mac) /
1916 IP(src=l['ip'], dst=ep.ip4.address) /
1917 UDP(sport=1234, dport=1234) /
1918 Raw('\xa5' * 100))
1919
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001920 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02001921
1922 self.assertTrue(find_gbp_endpoint(self,
1923 vx_tun_l2_1.sw_if_index,
1924 mac=l['mac']))
1925
1926 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001927 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001928 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001929 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001930 p = (Ether(src=ep.mac, dst=l['mac']) /
1931 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1932 UDP(sport=1234, dport=1234) /
1933 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001934
Neale Ranns13a08cc2018-11-07 09:25:54 -08001935 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001936
1937 #
1938 # refresh the entries after the check for no replies above
1939 #
1940 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001941 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001942 p = (Ether(src=self.pg2.remote_mac,
1943 dst=self.pg2.local_mac) /
1944 IP(src=self.pg2.remote_hosts[1].ip4,
1945 dst=self.pg2.local_ip4) /
1946 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001947 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001948 Ether(src=l['mac'], dst=ep.mac) /
1949 IP(src=l['ip'], dst=ep.ip4.address) /
1950 UDP(sport=1234, dport=1234) /
1951 Raw('\xa5' * 100))
1952
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001953 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001954
1955 self.assertTrue(find_gbp_endpoint(self,
1956 vx_tun_l2_1.sw_if_index,
1957 mac=l['mac']))
1958
1959 #
1960 # Add the contract so they can talk
1961 #
1962 acl = VppGbpAcl(self)
1963 rule = acl.create_rule(permit_deny=1, proto=17)
1964 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1965 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001966 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001967 self, 401, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001968 [VppGbpContractRule(
1969 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001970 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001971 []),
Neale Rannse28c87c2019-07-05 00:53:45 -07001972 VppGbpContractRule(
1973 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1974 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
1975 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001976 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001977 c1.add_vpp_config()
1978
1979 for l in learnt:
1980 p = (Ether(src=ep.mac, dst=l['mac']) /
1981 IP(dst=l['ip'], src=ep.ip4.address) /
1982 UDP(sport=1234, dport=1234) /
1983 Raw('\xa5' * 100))
1984
1985 self.send_and_expect(self.pg0, [p], self.pg2)
1986
1987 #
1988 # send UU packets from the local EP
1989 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001990 self.logger.info(self.vapi.cli("sh gbp bridge"))
Neale Rannse28c87c2019-07-05 00:53:45 -07001991 self.logger.info(self.vapi.cli("sh bridge-domain 1 detail"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001992 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1993 IP(dst="10.0.0.133", src=ep.ip4.address) /
1994 UDP(sport=1234, dport=1234) /
1995 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08001996 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001997
1998 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1999
2000 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2001 IP(dst="10.0.0.133", src=ep.ip4.address) /
2002 UDP(sport=1234, dport=1234) /
2003 Raw('\xa5' * 100))
2004 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
2005
Neale Ranns879d11c2019-01-21 23:34:18 -08002006 for rx in rxs:
2007 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2008 self.assertEqual(rx[IP].dst, "239.1.1.1")
2009 self.assertEqual(rx[UDP].dport, 48879)
2010 # the UDP source port is a random value for hashing
2011 self.assertEqual(rx[VXLAN].gpid, 112)
2012 self.assertEqual(rx[VXLAN].vni, 88)
2013 self.assertTrue(rx[VXLAN].flags.G)
2014 self.assertTrue(rx[VXLAN].flags.Instance)
2015 self.assertFalse(rx[VXLAN].gpflags.A)
2016 self.assertFalse(rx[VXLAN].gpflags.D)
2017
Neale Rannse28c87c2019-07-05 00:53:45 -07002018 acl = VppGbpAcl(self)
2019 rule = acl.create_rule(permit_deny=1, proto=17)
2020 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2021 acl_index = acl.add_vpp_config([rule, rule2])
2022 c2 = VppGbpContract(
2023 self, 401, epg_330.sclass, epg_220.sclass, acl_index,
2024 [VppGbpContractRule(
2025 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2026 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2027 []),
2028 VppGbpContractRule(
2029 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2030 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2031 [])],
2032 [ETH_P_IP, ETH_P_IPV6])
2033 c2.add_vpp_config()
2034
2035 for l in learnt:
2036 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2037 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002038 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002039 # Check v6 Endpoints learning
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002040 #
2041 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002042 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002043 p = (Ether(src=self.pg2.remote_mac,
2044 dst=self.pg2.local_mac) /
2045 IP(src=self.pg2.remote_hosts[1].ip4,
2046 dst=self.pg2.local_ip4) /
2047 UDP(sport=1234, dport=48879) /
Neale Rannse28c87c2019-07-05 00:53:45 -07002048 VXLAN(vni=99, gpid=113, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002049 Ether(src=l['mac'], dst=ep.mac) /
2050 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2051 UDP(sport=1234, dport=1234) /
2052 Raw('\xa5' * 100))
2053
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002054 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Rannse28c87c2019-07-05 00:53:45 -07002055 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002056
Neale Rannse28c87c2019-07-05 00:53:45 -07002057 self.assertTrue(find_gbp_endpoint(
2058 self,
2059 vx_tun_l2_1.sw_if_index,
2060 ip=l['ip6'],
2061 tep=[self.pg2.local_ip4,
2062 self.pg2.remote_hosts[1].ip4]))
2063
2064 self.logger.info(self.vapi.cli("sh int"))
2065 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
2066 self.logger.info(self.vapi.cli("sh gbp vxlan"))
2067 self.logger.info(self.vapi.cli("sh gbp endpoint"))
2068 self.logger.info(self.vapi.cli("sh gbp interface"))
2069
2070 #
2071 # EP moves to a different TEP
2072 #
2073 for l in learnt:
2074 # a packet with an sclass from a known EPG
2075 p = (Ether(src=self.pg2.remote_mac,
2076 dst=self.pg2.local_mac) /
2077 IP(src=self.pg2.remote_hosts[2].ip4,
2078 dst=self.pg2.local_ip4) /
2079 UDP(sport=1234, dport=48879) /
2080 VXLAN(vni=99, gpid=113, flags=0x88) /
2081 Ether(src=l['mac'], dst=ep.mac) /
2082 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2083 UDP(sport=1234, dport=1234) /
2084 Raw('\xa5' * 100))
2085
2086 rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
2087 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
2088
2089 self.assertTrue(find_gbp_endpoint(
2090 self,
2091 vx_tun_l2_1.sw_if_index,
2092 mac=l['mac'],
2093 tep=[self.pg2.local_ip4,
2094 self.pg2.remote_hosts[2].ip4]))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002095
2096 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002097 # v6 remote EP reachability
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002098 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002099 for l in learnt:
2100 p = (Ether(src=ep.mac, dst=l['mac']) /
2101 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2102 UDP(sport=1234, dport=1234) /
2103 Raw('\xa5' * 100))
2104
2105 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
2106
2107 for rx in rxs:
2108 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Rannse28c87c2019-07-05 00:53:45 -07002109 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns69a85b52019-06-14 07:49:50 +00002110 self.assertEqual(rx[UDP].dport, 48879)
2111 # the UDP source port is a random value for hashing
2112 self.assertEqual(rx[VXLAN].gpid, 112)
2113 self.assertEqual(rx[VXLAN].vni, 99)
2114 self.assertTrue(rx[VXLAN].flags.G)
2115 self.assertTrue(rx[VXLAN].flags.Instance)
2116 self.assertTrue(rx[VXLAN].gpflags.A)
2117 self.assertFalse(rx[VXLAN].gpflags.D)
2118 self.assertEqual(rx[IPv6].dst, l['ip6'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002119
2120 #
2121 # clean up
2122 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002123 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002124 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2125 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002126 self.pg2.unconfig_ip4()
2127 self.pg3.unconfig_ip4()
2128 self.pg4.unconfig_ip4()
2129
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002130 def test_gbp_contract(self):
Neale Ranns69a85b52019-06-14 07:49:50 +00002131 """ GBP Contracts """
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002132
2133 #
Neale Ranns160c9232019-06-19 06:25:56 -07002134 # Route Domains
2135 #
2136 gt4 = VppIpTable(self, 0)
2137 gt4.add_vpp_config()
2138 gt6 = VppIpTable(self, 0, is_ip6=True)
2139 gt6.add_vpp_config()
2140
2141 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
2142
2143 rd0.add_vpp_config()
2144
2145 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002146 # Bridge Domains
2147 #
2148 bd1 = VppBridgeDomain(self, 1, arp_term=0)
2149 bd2 = VppBridgeDomain(self, 2, arp_term=0)
2150
2151 bd1.add_vpp_config()
2152 bd2.add_vpp_config()
2153
Neale Ranns160c9232019-06-19 06:25:56 -07002154 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
2155 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002156
2157 gbd1.add_vpp_config()
2158 gbd2.add_vpp_config()
2159
2160 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002161 # 3 EPGs, 2 of which share a BD.
2162 #
2163 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
2164 None, self.loop0,
2165 "10.0.0.128", "2001:10::128"),
2166 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
2167 None, self.loop0,
2168 "10.0.1.128", "2001:10:1::128"),
2169 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
2170 None, self.loop1,
2171 "10.0.2.128", "2001:10:2::128")]
2172 #
2173 # 4 end-points, 2 in the same subnet, 3 in the same BD
2174 #
2175 eps = [VppGbpEndpoint(self, self.pg0,
2176 epgs[0], None,
2177 "10.0.0.1", "11.0.0.1",
2178 "2001:10::1", "3001::1"),
2179 VppGbpEndpoint(self, self.pg1,
2180 epgs[0], None,
2181 "10.0.0.2", "11.0.0.2",
2182 "2001:10::2", "3001::2"),
2183 VppGbpEndpoint(self, self.pg2,
2184 epgs[1], None,
2185 "10.0.1.1", "11.0.0.3",
2186 "2001:10:1::1", "3001::3"),
2187 VppGbpEndpoint(self, self.pg3,
2188 epgs[2], None,
2189 "10.0.2.1", "11.0.0.4",
2190 "2001:10:2::1", "3001::4")]
2191
2192 #
2193 # Config related to each of the EPGs
2194 #
2195 for epg in epgs:
2196 # IP config on the BVI interfaces
2197 if epg != epgs[1]:
2198 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
2199 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
2200 self.vapi.sw_interface_set_mac_address(
2201 epg.bvi.sw_if_index,
2202 self.router_mac.packed)
2203
2204 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
2205 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
2206 if_ip4.add_vpp_config()
2207 if_ip6.add_vpp_config()
2208
2209 # add the BD ARP termination entry for BVI IP
2210 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
2211 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -07002212 epg.bvi_ip4.address)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002213 epg.bd_arp_ip4.add_vpp_config()
2214
2215 # EPG in VPP
2216 epg.add_vpp_config()
2217
2218 #
2219 # config ep
2220 #
2221 for ep in eps:
2222 ep.add_vpp_config()
2223
2224 self.logger.info(self.vapi.cli("show gbp endpoint"))
2225 self.logger.info(self.vapi.cli("show interface"))
2226 self.logger.info(self.vapi.cli("show br"))
2227
2228 #
2229 # Intra epg allowed without contract
2230 #
2231 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2232 dst=self.pg1.remote_mac) /
2233 IP(src=eps[0].ip4.address,
2234 dst=eps[1].ip4.address) /
2235 UDP(sport=1234, dport=1234) /
2236 Raw('\xa5' * 100))
2237
2238 self.send_and_expect_bridged(self.pg0,
2239 pkt_intra_epg_220_to_220 * 65,
2240 self.pg1)
2241
Neale Ranns69a85b52019-06-14 07:49:50 +00002242 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2243 dst=self.pg1.remote_mac) /
2244 IPv6(src=eps[0].ip6.address,
2245 dst=eps[1].ip6.address) /
2246 UDP(sport=1234, dport=1234) /
2247 Raw('\xa5' * 100))
2248
2249 self.send_and_expect_bridged6(self.pg0,
2250 pkt_intra_epg_220_to_220 * 65,
2251 self.pg1)
2252
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002253 #
2254 # Inter epg denied without contract
2255 #
2256 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
2257 dst=self.pg2.remote_mac) /
2258 IP(src=eps[0].ip4.address,
2259 dst=eps[2].ip4.address) /
2260 UDP(sport=1234, dport=1234) /
2261 Raw('\xa5' * 100))
2262
2263 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221)
2264
2265 #
2266 # A uni-directional contract from EPG 220 -> 221
2267 #
2268 acl = VppGbpAcl(self)
2269 rule = acl.create_rule(permit_deny=1, proto=17)
2270 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
Neale Ranns69a85b52019-06-14 07:49:50 +00002271 rule3 = acl.create_rule(permit_deny=1, proto=1)
2272 acl_index = acl.add_vpp_config([rule, rule2, rule3])
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002273 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002274 self, 400, epgs[0].sclass, epgs[1].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002275 [VppGbpContractRule(
2276 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002277 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002278 []),
2279 VppGbpContractRule(
2280 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002281 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns69a85b52019-06-14 07:49:50 +00002282 []),
2283 VppGbpContractRule(
2284 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2285 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002286 [])],
2287 [ETH_P_IP, ETH_P_IPV6])
2288 c1.add_vpp_config()
2289
2290 self.send_and_expect_bridged(eps[0].itf,
2291 pkt_inter_epg_220_to_221 * 65,
2292 eps[2].itf)
2293
2294 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
2295 dst=str(self.router_mac)) /
2296 IP(src=eps[0].ip4.address,
2297 dst=eps[3].ip4.address) /
2298 UDP(sport=1234, dport=1234) /
2299 Raw('\xa5' * 100))
2300 self.send_and_assert_no_replies(eps[0].itf,
2301 pkt_inter_epg_220_to_222 * 65)
2302
2303 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002304 # ping router IP in different BD
2305 #
2306 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2307 dst=str(self.router_mac)) /
2308 IP(src=eps[0].ip4.address,
2309 dst=epgs[1].bvi_ip4.address) /
2310 ICMP(type='echo-request'))
2311
2312 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2313
2314 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2315 dst=str(self.router_mac)) /
2316 IPv6(src=eps[0].ip6.address,
2317 dst=epgs[1].bvi_ip6.address) /
2318 ICMPv6EchoRequest())
2319
2320 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2321
2322 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002323 # contract for the return direction
2324 #
2325 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002326 self, 400, epgs[1].sclass, epgs[0].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002327 [VppGbpContractRule(
2328 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002329 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002330 []),
2331 VppGbpContractRule(
2332 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002333 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002334 [])],
2335 [ETH_P_IP, ETH_P_IPV6])
2336 c2.add_vpp_config()
2337
2338 self.send_and_expect_bridged(eps[0].itf,
2339 pkt_inter_epg_220_to_221 * 65,
2340 eps[2].itf)
2341 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2342 dst=self.pg0.remote_mac) /
2343 IP(src=eps[2].ip4.address,
2344 dst=eps[0].ip4.address) /
2345 UDP(sport=1234, dport=1234) /
2346 Raw('\xa5' * 100))
2347 self.send_and_expect_bridged(eps[2].itf,
2348 pkt_inter_epg_221_to_220 * 65,
2349 eps[0].itf)
Neale Ranns69a85b52019-06-14 07:49:50 +00002350 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2351 dst=str(self.router_mac)) /
2352 IP(src=eps[2].ip4.address,
2353 dst=eps[0].ip4.address) /
2354 UDP(sport=1234, dport=1234) /
2355 Raw('\xa5' * 100))
2356 self.send_and_expect_routed(eps[2].itf,
2357 pkt_inter_epg_221_to_220 * 65,
2358 eps[0].itf,
2359 str(self.router_mac))
2360 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2361 dst=str(self.router_mac)) /
2362 IPv6(src=eps[2].ip6.address,
2363 dst=eps[0].ip6.address) /
2364 UDP(sport=1234, dport=1234) /
2365 Raw('\xa5' * 100))
2366 self.send_and_expect_routed6(eps[2].itf,
2367 pkt_inter_epg_221_to_220 * 65,
2368 eps[0].itf,
2369 str(self.router_mac))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002370
2371 #
2372 # contract between 220 and 222 uni-direction
2373 #
2374 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002375 self, 400, epgs[0].sclass, epgs[2].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002376 [VppGbpContractRule(
2377 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002378 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002379 []),
2380 VppGbpContractRule(
2381 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002382 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002383 [])],
2384 [ETH_P_IP, ETH_P_IPV6])
2385 c3.add_vpp_config()
2386
2387 self.send_and_expect(eps[0].itf,
2388 pkt_inter_epg_220_to_222 * 65,
2389 eps[3].itf)
2390
2391 c3.remove_vpp_config()
2392 c1.remove_vpp_config()
2393 c2.remove_vpp_config()
2394 acl.remove_vpp_config()
2395
Neale Ranns69a85b52019-06-14 07:49:50 +00002396 def test_gbp_bd_drop_flags(self):
2397 """ GBP BD drop flags """
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002398
2399 #
2400 # IP tables
2401 #
2402 gt4 = VppIpTable(self, 1)
2403 gt4.add_vpp_config()
2404 gt6 = VppIpTable(self, 1, is_ip6=True)
2405 gt6.add_vpp_config()
2406
Neale Ranns160c9232019-06-19 06:25:56 -07002407 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002408 rd1.add_vpp_config()
2409
2410 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002411 # a GBP bridge domain with a BVI only
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002412 #
2413 bd1 = VppBridgeDomain(self, 1)
2414 bd1.add_vpp_config()
2415
Neale Ranns69a85b52019-06-14 07:49:50 +00002416 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2417 None, None,
2418 uu_drop=True, bm_drop=True)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002419 gbd1.add_vpp_config()
2420
2421 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2422 self.logger.info(self.vapi.cli("sh gbp bridge"))
2423
2424 # ... and has a /32 applied
2425 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2426 ip_addr.add_vpp_config()
2427
2428 #
2429 # The Endpoint-group
2430 #
2431 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2432 None, self.loop0,
2433 "10.0.0.128",
2434 "2001:10::128",
2435 VppGbpEndpointRetention(2))
2436 epg_220.add_vpp_config()
2437
2438 ep = VppGbpEndpoint(self, self.pg0,
2439 epg_220, None,
2440 "10.0.0.127", "11.0.0.127",
2441 "2001:10::1", "3001::1")
2442 ep.add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00002443
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002444 #
2445 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2446 # in bd
2447 #
2448 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2449 self.logger.info(self.vapi.cli("sh gbp bridge"))
2450 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
2451 IP(dst="10.0.0.133", src=ep.ip4.address) /
2452 UDP(sport=1234, dport=1234) /
2453 Raw('\xa5' * 100))
2454 self.send_and_assert_no_replies(ep.itf, [p_uu])
2455
2456 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2457 IP(dst="10.0.0.133", src=ep.ip4.address) /
2458 UDP(sport=1234, dport=1234) /
2459 Raw('\xa5' * 100))
2460 self.send_and_assert_no_replies(ep.itf, [p_bm])
2461
2462 self.pg3.unconfig_ip4()
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002463
2464 self.logger.info(self.vapi.cli("sh int"))
2465
Neale Ranns69a85b52019-06-14 07:49:50 +00002466 def test_gbp_bd_arp_flags(self):
2467 """ GBP BD arp flags """
2468
2469 #
2470 # IP tables
2471 #
2472 gt4 = VppIpTable(self, 1)
2473 gt4.add_vpp_config()
2474 gt6 = VppIpTable(self, 1, is_ip6=True)
2475 gt6.add_vpp_config()
2476
2477 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
2478 rd1.add_vpp_config()
2479
2480 #
2481 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
2482 #
2483 self.pg4.config_ip4()
2484 self.pg4.resolve_arp()
2485
2486 #
2487 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
2488 #
2489 tun_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2490 "239.1.1.1", 88,
2491 mcast_itf=self.pg4)
2492 tun_uu.add_vpp_config()
2493
2494 #
2495 # a GBP bridge domain with a BVI and a UU-flood interface
2496 #
2497 bd1 = VppBridgeDomain(self, 1)
2498 bd1.add_vpp_config()
2499
2500 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2501 tun_uu, None,
2502 ucast_arp=True)
2503 gbd1.add_vpp_config()
2504
2505 # ... and has a /32 applied
2506 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2507 ip_addr.add_vpp_config()
2508
2509 #
2510 # The Endpoint-group
2511 #
2512 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2513 None, self.loop0,
2514 "10.0.0.128",
2515 "2001:10::128",
2516 VppGbpEndpointRetention(2))
2517 epg_220.add_vpp_config()
2518
2519 ep = VppGbpEndpoint(self, self.pg0,
2520 epg_220, None,
2521 "10.0.0.127", "11.0.0.127",
2522 "2001:10::1", "3001::1")
2523 ep.add_vpp_config()
2524
2525 #
2526 # send ARP packet from the local EP expect it on the uu interface
2527 #
2528 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2529 self.logger.info(self.vapi.cli("sh gbp bridge"))
2530 p_arp = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2531 ARP(op="who-has",
2532 psrc=ep.ip4.address, pdst="10.0.0.99",
2533 hwsrc=ep.mac,
2534 hwdst="ff:ff:ff:ff:ff:ff"))
2535 self.send_and_expect(ep.itf, [p_arp], self.pg4)
2536
2537 self.pg4.unconfig_ip4()
2538
Neale Rannsc29c0af2018-11-07 04:21:12 -08002539 def test_gbp_learn_vlan_l2(self):
2540 """ GBP L2 Endpoint w/ VLANs"""
2541
Neale Rannsb6a47952018-11-21 05:44:35 -08002542 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002543 learnt = [{'mac': '00:00:11:11:11:01',
2544 'ip': '10.0.0.1',
2545 'ip6': '2001:10::2'},
2546 {'mac': '00:00:11:11:11:02',
2547 'ip': '10.0.0.2',
2548 'ip6': '2001:10::3'}]
2549
2550 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002551 # IP tables
2552 #
2553 gt4 = VppIpTable(self, 1)
2554 gt4.add_vpp_config()
2555 gt6 = VppIpTable(self, 1, is_ip6=True)
2556 gt6.add_vpp_config()
2557
Neale Ranns160c9232019-06-19 06:25:56 -07002558 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002559 rd1.add_vpp_config()
2560
2561 #
2562 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2563 #
2564 self.pg2.config_ip4()
2565 self.pg2.resolve_arp()
2566 self.pg2.generate_remote_hosts(4)
2567 self.pg2.configure_ipv4_neighbors()
2568 self.pg3.config_ip4()
2569 self.pg3.resolve_arp()
2570
2571 #
2572 # The EP will be on a vlan sub-interface
2573 #
2574 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2575 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002576 self.vapi.l2_interface_vlan_tag_rewrite(
2577 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2578 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002579
2580 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2581 self.pg3.remote_ip4, 116)
2582 bd_uu_fwd.add_vpp_config()
2583
2584 #
2585 # a GBP bridge domain with a BVI and a UU-flood interface
2586 # The BD is marked as do not learn, so no endpoints are ever
2587 # learnt in this BD.
2588 #
2589 bd1 = VppBridgeDomain(self, 1)
2590 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002591 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002592 learn=False)
2593 gbd1.add_vpp_config()
2594
2595 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2596 self.logger.info(self.vapi.cli("sh gbp bridge"))
2597
2598 # ... and has a /32 applied
2599 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2600 ip_addr.add_vpp_config()
2601
2602 #
2603 # The Endpoint-group in which we are learning endpoints
2604 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002605 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002606 None, self.loop0,
2607 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002608 "2001:10::128",
2609 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002610 epg_220.add_vpp_config()
2611
2612 #
2613 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002614 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002615 #
2616 vx_tun_l2_1 = VppGbpVxlanTunnel(
2617 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002618 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2619 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002620 vx_tun_l2_1.add_vpp_config()
2621
2622 #
2623 # A static endpoint that the learnt endpoints are trying to
2624 # talk to
2625 #
2626 ep = VppGbpEndpoint(self, vlan_11,
2627 epg_220, None,
2628 "10.0.0.127", "11.0.0.127",
2629 "2001:10::1", "3001::1")
2630 ep.add_vpp_config()
2631
2632 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2633
2634 #
2635 # Send to the static EP
2636 #
2637 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002638 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002639 # arriving on an unknown TEP
2640 p = (Ether(src=self.pg2.remote_mac,
2641 dst=self.pg2.local_mac) /
2642 IP(src=self.pg2.remote_hosts[1].ip4,
2643 dst=self.pg2.local_ip4) /
2644 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002645 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002646 Ether(src=l['mac'], dst=ep.mac) /
2647 IP(src=l['ip'], dst=ep.ip4.address) /
2648 UDP(sport=1234, dport=1234) /
2649 Raw('\xa5' * 100))
2650
2651 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2652
2653 #
2654 # packet to EP has the EP's vlan tag
2655 #
2656 for rx in rxs:
2657 self.assertEqual(rx[Dot1Q].vlan, 11)
2658
2659 #
2660 # the EP is not learnt since the BD setting prevents it
2661 # also no TEP too
2662 #
2663 self.assertFalse(find_gbp_endpoint(self,
2664 vx_tun_l2_1.sw_if_index,
2665 mac=l['mac']))
2666 self.assertEqual(INDEX_INVALID,
2667 find_vxlan_gbp_tunnel(
2668 self,
2669 self.pg2.local_ip4,
2670 self.pg2.remote_hosts[1].ip4,
2671 99))
2672
2673 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2674
2675 #
2676 # static to remotes
2677 # we didn't learn the remotes so they are sent to the UU-fwd
2678 #
2679 for l in learnt:
2680 p = (Ether(src=ep.mac, dst=l['mac']) /
2681 Dot1Q(vlan=11) /
2682 IP(dst=l['ip'], src=ep.ip4.address) /
2683 UDP(sport=1234, dport=1234) /
2684 Raw('\xa5' * 100))
2685
2686 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2687
2688 for rx in rxs:
2689 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2690 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2691 self.assertEqual(rx[UDP].dport, 48879)
2692 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002693 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002694 self.assertEqual(rx[VXLAN].vni, 116)
2695 self.assertTrue(rx[VXLAN].flags.G)
2696 self.assertTrue(rx[VXLAN].flags.Instance)
2697 self.assertFalse(rx[VXLAN].gpflags.A)
2698 self.assertFalse(rx[VXLAN].gpflags.D)
2699
2700 self.pg2.unconfig_ip4()
2701 self.pg3.unconfig_ip4()
2702
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002703 def test_gbp_learn_l3(self):
2704 """ GBP L3 Endpoint Learning """
2705
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04002706 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08002707
Neale Rannsb6a47952018-11-21 05:44:35 -08002708 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002709 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2710 routed_src_mac = "00:22:bd:f8:19:ff"
2711
2712 learnt = [{'mac': '00:00:11:11:11:02',
2713 'ip': '10.0.1.2',
2714 'ip6': '2001:10::2'},
2715 {'mac': '00:00:11:11:11:03',
2716 'ip': '10.0.1.3',
2717 'ip6': '2001:10::3'}]
2718
2719 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002720 # IP tables
2721 #
2722 t4 = VppIpTable(self, 1)
2723 t4.add_vpp_config()
2724 t6 = VppIpTable(self, 1, True)
2725 t6.add_vpp_config()
2726
2727 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2728 self.pg4.remote_ip4, 114)
2729 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2730 self.pg4.remote_ip4, 116)
2731 tun_ip4_uu.add_vpp_config()
2732 tun_ip6_uu.add_vpp_config()
2733
Neale Ranns160c9232019-06-19 06:25:56 -07002734 rd1 = VppGbpRouteDomain(self, 2, 401, t4, t6, tun_ip4_uu, tun_ip6_uu)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002735 rd1.add_vpp_config()
2736
Ole Troan8006c6a2018-12-17 12:02:26 +01002737 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002738
2739 #
2740 # Bind the BVI to the RD
2741 #
2742 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2743 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2744
2745 #
2746 # Pg2 hosts the vxlan tunnel
2747 # hosts on pg2 to act as TEPs
2748 # pg3 is BD uu-fwd
2749 # pg4 is RD uu-fwd
2750 #
2751 self.pg2.config_ip4()
2752 self.pg2.resolve_arp()
2753 self.pg2.generate_remote_hosts(4)
2754 self.pg2.configure_ipv4_neighbors()
2755 self.pg3.config_ip4()
2756 self.pg3.resolve_arp()
2757 self.pg4.config_ip4()
2758 self.pg4.resolve_arp()
2759
2760 #
2761 # a GBP bridge domain with a BVI and a UU-flood interface
2762 #
2763 bd1 = VppBridgeDomain(self, 1)
2764 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002765 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002766 gbd1.add_vpp_config()
2767
2768 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2769 self.logger.info(self.vapi.cli("sh gbp bridge"))
2770 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002771
2772 # ... and has a /32 and /128 applied
2773 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2774 ip4_addr.add_vpp_config()
2775 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2776 ip6_addr.add_vpp_config()
2777
2778 #
2779 # The Endpoint-group in which we are learning endpoints
2780 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002781 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002782 None, self.loop0,
2783 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002784 "2001:10::128",
2785 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002786 epg_220.add_vpp_config()
2787
2788 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002789 # The VXLAN GBP tunnel is in L3 mode with learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002790 #
2791 vx_tun_l3 = VppGbpVxlanTunnel(
2792 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002793 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2794 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002795 vx_tun_l3.add_vpp_config()
2796
2797 #
2798 # A static endpoint that the learnt endpoints are trying to
2799 # talk to
2800 #
2801 ep = VppGbpEndpoint(self, self.pg0,
2802 epg_220, None,
2803 "10.0.0.127", "11.0.0.127",
2804 "2001:10::1", "3001::1")
2805 ep.add_vpp_config()
2806
2807 #
2808 # learn some remote IPv4 EPs
2809 #
2810 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002811 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002812 # arriving on an unknown TEP
2813 p = (Ether(src=self.pg2.remote_mac,
2814 dst=self.pg2.local_mac) /
2815 IP(src=self.pg2.remote_hosts[1].ip4,
2816 dst=self.pg2.local_ip4) /
2817 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002818 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002819 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2820 IP(src=l['ip'], dst=ep.ip4.address) /
2821 UDP(sport=1234, dport=1234) /
2822 Raw('\xa5' * 100))
2823
2824 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2825
2826 # the new TEP
2827 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2828 self,
2829 self.pg2.local_ip4,
2830 self.pg2.remote_hosts[1].ip4,
2831 vx_tun_l3.vni)
2832 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2833
2834 # endpoint learnt via the parent GBP-vxlan interface
2835 self.assertTrue(find_gbp_endpoint(self,
2836 vx_tun_l3._sw_if_index,
2837 ip=l['ip']))
2838
2839 #
2840 # Static IPv4 EP replies to learnt
2841 #
2842 for l in learnt:
2843 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2844 IP(dst=l['ip'], src=ep.ip4.address) /
2845 UDP(sport=1234, dport=1234) /
2846 Raw('\xa5' * 100))
2847
Filip Vargaf4749ca2019-04-25 14:55:32 +02002848 rxs = self.send_and_expect(self.pg0, p * 1, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002849
2850 for rx in rxs:
2851 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2852 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2853 self.assertEqual(rx[UDP].dport, 48879)
2854 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002855 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002856 self.assertEqual(rx[VXLAN].vni, 101)
2857 self.assertTrue(rx[VXLAN].flags.G)
2858 self.assertTrue(rx[VXLAN].flags.Instance)
2859 self.assertTrue(rx[VXLAN].gpflags.A)
2860 self.assertFalse(rx[VXLAN].gpflags.D)
2861
2862 inner = rx[VXLAN].payload
2863
2864 self.assertEqual(inner[Ether].src, routed_src_mac)
2865 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2866 self.assertEqual(inner[IP].src, ep.ip4.address)
2867 self.assertEqual(inner[IP].dst, l['ip'])
2868
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002869 for l in learnt:
2870 self.assertFalse(find_gbp_endpoint(self,
2871 tep1_sw_if_index,
2872 ip=l['ip']))
2873
2874 #
2875 # learn some remote IPv6 EPs
2876 #
2877 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002878 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002879 # arriving on an unknown TEP
2880 p = (Ether(src=self.pg2.remote_mac,
2881 dst=self.pg2.local_mac) /
2882 IP(src=self.pg2.remote_hosts[1].ip4,
2883 dst=self.pg2.local_ip4) /
2884 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002885 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002886 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2887 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2888 UDP(sport=1234, dport=1234) /
2889 Raw('\xa5' * 100))
2890
2891 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2892
2893 # the new TEP
2894 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2895 self,
2896 self.pg2.local_ip4,
2897 self.pg2.remote_hosts[1].ip4,
2898 vx_tun_l3.vni)
2899 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2900
2901 self.logger.info(self.vapi.cli("show gbp bridge"))
2902 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2903 self.logger.info(self.vapi.cli("show gbp vxlan"))
2904 self.logger.info(self.vapi.cli("show int addr"))
2905
2906 # endpoint learnt via the TEP
2907 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2908
2909 self.logger.info(self.vapi.cli("show gbp endpoint"))
2910 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2911
2912 #
2913 # Static EP replies to learnt
2914 #
2915 for l in learnt:
2916 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2917 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2918 UDP(sport=1234, dport=1234) /
2919 Raw('\xa5' * 100))
2920
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002921 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002922
2923 for rx in rxs:
2924 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2925 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2926 self.assertEqual(rx[UDP].dport, 48879)
2927 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002928 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002929 self.assertEqual(rx[VXLAN].vni, 101)
2930 self.assertTrue(rx[VXLAN].flags.G)
2931 self.assertTrue(rx[VXLAN].flags.Instance)
2932 self.assertTrue(rx[VXLAN].gpflags.A)
2933 self.assertFalse(rx[VXLAN].gpflags.D)
2934
2935 inner = rx[VXLAN].payload
2936
2937 self.assertEqual(inner[Ether].src, routed_src_mac)
2938 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2939 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2940 self.assertEqual(inner[IPv6].dst, l['ip6'])
2941
2942 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002943 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002944 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002945
2946 #
2947 # Static sends to unknown EP with no route
2948 #
2949 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2950 IP(dst="10.0.0.99", src=ep.ip4.address) /
2951 UDP(sport=1234, dport=1234) /
2952 Raw('\xa5' * 100))
2953
2954 self.send_and_assert_no_replies(self.pg0, [p])
2955
2956 #
2957 # Add a route to static EP's v4 and v6 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002958 #
2959 se_10_24 = VppGbpSubnet(
2960 self, rd1, "10.0.0.0", 24,
2961 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2962 se_10_24.add_vpp_config()
2963
Neale Ranns69a85b52019-06-14 07:49:50 +00002964 #
2965 # static pings router
2966 #
2967 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2968 IP(dst=epg_220.bvi_ip4.address, src=ep.ip4.address) /
2969 UDP(sport=1234, dport=1234) /
2970 Raw('\xa5' * 100))
2971
2972 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
2973
2974 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2975 IPv6(dst=epg_220.bvi_ip6.address, src=ep.ip6.address) /
2976 UDP(sport=1234, dport=1234) /
2977 Raw('\xa5' * 100))
2978
2979 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
2980
2981 #
2982 # packets to address in the subnet are sent on the uu-fwd
2983 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002984 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2985 IP(dst="10.0.0.99", src=ep.ip4.address) /
2986 UDP(sport=1234, dport=1234) /
2987 Raw('\xa5' * 100))
2988
2989 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2990 for rx in rxs:
2991 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2992 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2993 self.assertEqual(rx[UDP].dport, 48879)
2994 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002995 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002996 self.assertEqual(rx[VXLAN].vni, 114)
2997 self.assertTrue(rx[VXLAN].flags.G)
2998 self.assertTrue(rx[VXLAN].flags.Instance)
2999 # policy is not applied to packets sent to the uu-fwd interfaces
3000 self.assertFalse(rx[VXLAN].gpflags.A)
3001 self.assertFalse(rx[VXLAN].gpflags.D)
3002
3003 #
3004 # learn some remote IPv4 EPs
3005 #
3006 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003007 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003008 # arriving on an unknown TEP
3009 p = (Ether(src=self.pg2.remote_mac,
3010 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003011 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003012 dst=self.pg2.local_ip4) /
3013 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003014 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003015 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3016 IP(src=l['ip'], dst=ep.ip4.address) /
3017 UDP(sport=1234, dport=1234) /
3018 Raw('\xa5' * 100))
3019
3020 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3021
3022 # the new TEP
3023 tep1_sw_if_index = find_vxlan_gbp_tunnel(
3024 self,
3025 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08003026 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003027 vx_tun_l3.vni)
3028 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
3029
3030 # endpoint learnt via the parent GBP-vxlan interface
3031 self.assertTrue(find_gbp_endpoint(self,
3032 vx_tun_l3._sw_if_index,
3033 ip=l['ip']))
3034
3035 #
3036 # Add a remote endpoint from the API
3037 #
3038 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
3039 epg_220, None,
3040 "10.0.0.88", "11.0.0.88",
3041 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08003042 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003043 self.pg2.local_ip4,
Neale Ranns3eea9de2019-06-21 02:09:25 -07003044 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003045 mac=None)
3046 rep_88.add_vpp_config()
3047
3048 #
3049 # Add a remote endpoint from the API that matches an existing one
Neale Ranns3eea9de2019-06-21 02:09:25 -07003050 # this is a lower priority, hence the packet is sent to the DP leanrt
3051 # TEP
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003052 #
3053 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
3054 epg_220, None,
3055 learnt[0]['ip'], "11.0.0.101",
3056 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08003057 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003058 self.pg2.local_ip4,
3059 self.pg2.remote_hosts[1].ip4,
3060 mac=None)
3061 rep_2.add_vpp_config()
3062
3063 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003064 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003065 # packets should be send on the v4/v6 uu=fwd interface resp.
3066 #
3067 se_10_1_24 = VppGbpSubnet(
3068 self, rd1, "10.0.1.0", 24,
3069 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
3070 se_10_1_24.add_vpp_config()
3071
3072 self.logger.info(self.vapi.cli("show gbp endpoint"))
3073
3074 ips = ["10.0.0.88", learnt[0]['ip']]
3075 for ip in ips:
3076 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3077 IP(dst=ip, src=ep.ip4.address) /
3078 UDP(sport=1234, dport=1234) /
3079 Raw('\xa5' * 100))
3080
Paul Vinciguerra4271c972019-05-14 13:25:49 -04003081 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003082
3083 for rx in rxs:
3084 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Ranns3eea9de2019-06-21 02:09:25 -07003085 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003086 self.assertEqual(rx[UDP].dport, 48879)
3087 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003088 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003089 self.assertEqual(rx[VXLAN].vni, 101)
3090 self.assertTrue(rx[VXLAN].flags.G)
3091 self.assertTrue(rx[VXLAN].flags.Instance)
3092 self.assertTrue(rx[VXLAN].gpflags.A)
3093 self.assertFalse(rx[VXLAN].gpflags.D)
3094
3095 inner = rx[VXLAN].payload
3096
3097 self.assertEqual(inner[Ether].src, routed_src_mac)
3098 self.assertEqual(inner[Ether].dst, routed_dst_mac)
3099 self.assertEqual(inner[IP].src, ep.ip4.address)
3100 self.assertEqual(inner[IP].dst, ip)
3101
3102 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003103 # remove the API remote EPs, only API sourced is gone, the DP
3104 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003105 #
3106 rep_88.remove_vpp_config()
3107 rep_2.remove_vpp_config()
3108
Neale Ranns00a469d2018-12-20 06:12:19 -08003109 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
3110
3111 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3112 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
3113 UDP(sport=1234, dport=1234) /
3114 Raw('\xa5' * 100))
3115 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003116
Neale Ranns13a08cc2018-11-07 09:25:54 -08003117 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003118
Neale Ranns13a08cc2018-11-07 09:25:54 -08003119 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3120 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
3121 UDP(sport=1234, dport=1234) /
3122 Raw('\xa5' * 100))
3123 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003124
Neale Ranns13a08cc2018-11-07 09:25:54 -08003125 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003126 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08003127 # present (because it's DP learnt) when the TC ends so wait until
3128 # it is removed
3129 #
Neale Ranns00a469d2018-12-20 06:12:19 -08003130 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
3131 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003132
3133 #
Neale Ranns3eea9de2019-06-21 02:09:25 -07003134 # Same as above, learn a remote EP via CP and DP
3135 # this time remove the DP one first. expect the CP data to remain
3136 #
3137 rep_3 = VppGbpEndpoint(self, vx_tun_l3,
3138 epg_220, None,
3139 "10.0.1.4", "11.0.0.103",
3140 "2001::10:3", "3001::103",
3141 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3142 self.pg2.local_ip4,
3143 self.pg2.remote_hosts[1].ip4,
3144 mac=None)
3145 rep_3.add_vpp_config()
3146
3147 p = (Ether(src=self.pg2.remote_mac,
3148 dst=self.pg2.local_mac) /
3149 IP(src=self.pg2.remote_hosts[2].ip4,
3150 dst=self.pg2.local_ip4) /
3151 UDP(sport=1234, dport=48879) /
3152 VXLAN(vni=101, gpid=441, flags=0x88) /
3153 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3154 IP(src="10.0.1.4", dst=ep.ip4.address) /
3155 UDP(sport=1234, dport=1234) /
3156 Raw('\xa5' * 100))
3157 rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
3158
3159 self.assertTrue(find_gbp_endpoint(self,
3160 vx_tun_l3._sw_if_index,
3161 ip=rep_3.ip4.address,
3162 tep=[self.pg2.local_ip4,
3163 self.pg2.remote_hosts[2].ip4]))
3164
3165 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3166 IP(dst="10.0.1.4", src=ep.ip4.address) /
3167 UDP(sport=1234, dport=1234) /
3168 Raw('\xa5' * 100))
3169 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3170
3171 # host 2 is the DP learned TEP
3172 for rx in rxs:
3173 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3174 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
3175
3176 self.wait_for_ep_timeout(ip=rep_3.ip4.address,
3177 tep=[self.pg2.local_ip4,
3178 self.pg2.remote_hosts[2].ip4])
3179
3180 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3181
3182 # host 1 is the CP learned TEP
3183 for rx in rxs:
3184 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3185 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
3186
3187 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003188 # shutdown with learnt endpoint present
3189 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003190 p = (Ether(src=self.pg2.remote_mac,
3191 dst=self.pg2.local_mac) /
3192 IP(src=self.pg2.remote_hosts[1].ip4,
3193 dst=self.pg2.local_ip4) /
3194 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003195 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003196 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3197 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
3198 UDP(sport=1234, dport=1234) /
3199 Raw('\xa5' * 100))
3200
3201 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3202
3203 # endpoint learnt via the parent GBP-vxlan interface
3204 self.assertTrue(find_gbp_endpoint(self,
3205 vx_tun_l3._sw_if_index,
3206 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003207
3208 #
3209 # TODO
3210 # remote endpoint becomes local
3211 #
3212 self.pg2.unconfig_ip4()
3213 self.pg3.unconfig_ip4()
3214 self.pg4.unconfig_ip4()
3215
Neale Ranns13a08cc2018-11-07 09:25:54 -08003216 def test_gbp_redirect(self):
3217 """ GBP Endpoint Redirect """
3218
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04003219 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08003220
Neale Rannsb6a47952018-11-21 05:44:35 -08003221 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08003222 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3223 routed_src_mac = "00:22:bd:f8:19:ff"
3224
3225 learnt = [{'mac': '00:00:11:11:11:02',
3226 'ip': '10.0.1.2',
3227 'ip6': '2001:10::2'},
3228 {'mac': '00:00:11:11:11:03',
3229 'ip': '10.0.1.3',
3230 'ip6': '2001:10::3'}]
3231
3232 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003233 # IP tables
3234 #
3235 t4 = VppIpTable(self, 1)
3236 t4.add_vpp_config()
3237 t6 = VppIpTable(self, 1, True)
3238 t6.add_vpp_config()
3239
Neale Ranns160c9232019-06-19 06:25:56 -07003240 rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003241 rd1.add_vpp_config()
3242
Ole Troan8006c6a2018-12-17 12:02:26 +01003243 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003244
3245 #
3246 # Bind the BVI to the RD
3247 #
3248 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3249 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3250
3251 #
3252 # Pg7 hosts a BD's UU-fwd
3253 #
3254 self.pg7.config_ip4()
3255 self.pg7.resolve_arp()
3256
3257 #
3258 # a GBP bridge domains for the EPs
3259 #
3260 bd1 = VppBridgeDomain(self, 1)
3261 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003262 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003263 gbd1.add_vpp_config()
3264
3265 bd2 = VppBridgeDomain(self, 2)
3266 bd2.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003267 gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003268 gbd2.add_vpp_config()
3269
3270 # ... and has a /32 and /128 applied
3271 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
3272 ip4_addr.add_vpp_config()
3273 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
3274 ip6_addr.add_vpp_config()
3275 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
3276 ip4_addr.add_vpp_config()
3277 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
3278 ip6_addr.add_vpp_config()
3279
3280 #
3281 # The Endpoint-groups in which we are learning endpoints
3282 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003283 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003284 None, gbd1.bvi,
3285 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003286 "2001:10::128",
3287 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003288 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003289 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003290 None, gbd2.bvi,
3291 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003292 "2001:11::128",
3293 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003294 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003295 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003296 None, gbd1.bvi,
3297 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003298 "2001:12::128",
3299 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003300 epg_222.add_vpp_config()
3301
3302 #
3303 # a GBP bridge domains for the SEPs
3304 #
3305 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3306 self.pg7.remote_ip4, 116)
3307 bd_uu1.add_vpp_config()
3308 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3309 self.pg7.remote_ip4, 117)
3310 bd_uu2.add_vpp_config()
3311
3312 bd3 = VppBridgeDomain(self, 3)
3313 bd3.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003314 gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2,
3315 bd_uu1, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003316 gbd3.add_vpp_config()
3317 bd4 = VppBridgeDomain(self, 4)
3318 bd4.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003319 gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3,
3320 bd_uu2, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003321 gbd4.add_vpp_config()
3322
3323 #
3324 # EPGs in which the service endpoints exist
3325 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003326 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003327 None, gbd1.bvi,
3328 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003329 "4001:10::128",
3330 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003331 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003332 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003333 None, gbd2.bvi,
3334 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003335 "4001:11::128",
3336 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003337 epg_321.add_vpp_config()
3338
3339 #
3340 # three local endpoints
3341 #
3342 ep1 = VppGbpEndpoint(self, self.pg0,
3343 epg_220, None,
3344 "10.0.0.1", "11.0.0.1",
3345 "2001:10::1", "3001:10::1")
3346 ep1.add_vpp_config()
3347 ep2 = VppGbpEndpoint(self, self.pg1,
3348 epg_221, None,
3349 "10.0.1.1", "11.0.1.1",
3350 "2001:11::1", "3001:11::1")
3351 ep2.add_vpp_config()
3352 ep3 = VppGbpEndpoint(self, self.pg2,
3353 epg_222, None,
3354 "10.0.2.2", "11.0.2.2",
3355 "2001:12::1", "3001:12::1")
3356 ep3.add_vpp_config()
3357
3358 #
3359 # service endpoints
3360 #
3361 sep1 = VppGbpEndpoint(self, self.pg3,
3362 epg_320, None,
3363 "12.0.0.1", "13.0.0.1",
3364 "4001:10::1", "5001:10::1")
3365 sep1.add_vpp_config()
3366 sep2 = VppGbpEndpoint(self, self.pg4,
3367 epg_320, None,
3368 "12.0.0.2", "13.0.0.2",
3369 "4001:10::2", "5001:10::2")
3370 sep2.add_vpp_config()
3371 sep3 = VppGbpEndpoint(self, self.pg5,
3372 epg_321, None,
3373 "12.0.1.1", "13.0.1.1",
3374 "4001:11::1", "5001:11::1")
3375 sep3.add_vpp_config()
3376 # this EP is not installed immediately
3377 sep4 = VppGbpEndpoint(self, self.pg6,
3378 epg_321, None,
3379 "12.0.1.2", "13.0.1.2",
3380 "4001:11::2", "5001:11::2")
3381
3382 #
3383 # an L2 switch packet between local EPs in different EPGs
3384 # different dest ports on each so the are LB hashed differently
3385 #
3386 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
3387 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
3388 UDP(sport=1234, dport=1234) /
3389 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003390 (Ether(src=ep3.mac, dst=ep1.mac) /
3391 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
3392 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003393 Raw('\xa5' * 100))]
3394 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
3395 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
3396 UDP(sport=1234, dport=1234) /
3397 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003398 (Ether(src=ep3.mac, dst=ep1.mac) /
3399 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003400 UDP(sport=1234, dport=1230) /
3401 Raw('\xa5' * 100))]
3402
3403 # should be dropped since no contract yet
3404 self.send_and_assert_no_replies(self.pg0, [p4[0]])
3405 self.send_and_assert_no_replies(self.pg0, [p6[0]])
3406
3407 #
3408 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
3409 # one of the next-hops is via an EP that is not known
3410 #
3411 acl = VppGbpAcl(self)
3412 rule4 = acl.create_rule(permit_deny=1, proto=17)
3413 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3414 acl_index = acl.add_vpp_config([rule4, rule6])
3415
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003416 #
3417 # test the src-ip hash mode
3418 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003419 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003420 self, 402, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003421 [VppGbpContractRule(
3422 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003423 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003424 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3425 sep1.ip4, sep1.epg.rd),
3426 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3427 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003428 VppGbpContractRule(
3429 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3430 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3431 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3432 sep3.ip6, sep3.epg.rd),
3433 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3434 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003435 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08003436 c1.add_vpp_config()
3437
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003438 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003439 self, 402, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003440 [VppGbpContractRule(
3441 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3442 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3443 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3444 sep1.ip4, sep1.epg.rd),
3445 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3446 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003447 VppGbpContractRule(
3448 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3449 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3450 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3451 sep3.ip6, sep3.epg.rd),
3452 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3453 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003454 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003455 c2.add_vpp_config()
3456
Neale Ranns13a08cc2018-11-07 09:25:54 -08003457 #
3458 # send again with the contract preset, now packets arrive
3459 # at SEP1 or SEP2 depending on the hashing
3460 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003461 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003462
3463 for rx in rxs:
3464 self.assertEqual(rx[Ether].src, routed_src_mac)
3465 self.assertEqual(rx[Ether].dst, sep1.mac)
3466 self.assertEqual(rx[IP].src, ep1.ip4.address)
3467 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3468
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003469 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
3470
3471 for rx in rxs:
3472 self.assertEqual(rx[Ether].src, routed_src_mac)
3473 self.assertEqual(rx[Ether].dst, sep2.mac)
3474 self.assertEqual(rx[IP].src, ep3.ip4.address)
3475 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3476
Neale Ranns13a08cc2018-11-07 09:25:54 -08003477 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3478
3479 for rx in rxs:
3480 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3481 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3482 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3483 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3484 self.assertEqual(rx[VXLAN].vni, 117)
3485 self.assertTrue(rx[VXLAN].flags.G)
3486 self.assertTrue(rx[VXLAN].flags.Instance)
3487 # redirect policy has been applied
3488 self.assertTrue(rx[VXLAN].gpflags.A)
3489 self.assertFalse(rx[VXLAN].gpflags.D)
3490
3491 inner = rx[VXLAN].payload
3492
3493 self.assertEqual(inner[Ether].src, routed_src_mac)
3494 self.assertEqual(inner[Ether].dst, sep4.mac)
3495 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
3496 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
3497
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003498 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003499
3500 for rx in rxs:
3501 self.assertEqual(rx[Ether].src, routed_src_mac)
3502 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003503 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
3504 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003505
3506 #
3507 # programme the unknown EP
3508 #
3509 sep4.add_vpp_config()
3510
3511 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3512
3513 for rx in rxs:
3514 self.assertEqual(rx[Ether].src, routed_src_mac)
3515 self.assertEqual(rx[Ether].dst, sep4.mac)
3516 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3517 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
3518
3519 #
3520 # and revert back to unprogrammed
3521 #
3522 sep4.remove_vpp_config()
3523
3524 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3525
3526 for rx in rxs:
3527 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3528 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3529 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3530 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3531 self.assertEqual(rx[VXLAN].vni, 117)
3532 self.assertTrue(rx[VXLAN].flags.G)
3533 self.assertTrue(rx[VXLAN].flags.Instance)
3534 # redirect policy has been applied
3535 self.assertTrue(rx[VXLAN].gpflags.A)
3536 self.assertFalse(rx[VXLAN].gpflags.D)
3537
3538 inner = rx[VXLAN].payload
3539
3540 self.assertEqual(inner[Ether].src, routed_src_mac)
3541 self.assertEqual(inner[Ether].dst, sep4.mac)
3542 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
3543 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
3544
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003545 c1.remove_vpp_config()
3546 c2.remove_vpp_config()
3547
3548 #
3549 # test the symmetric hash mode
3550 #
3551 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003552 self, 402, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003553 [VppGbpContractRule(
3554 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3555 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3556 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3557 sep1.ip4, sep1.epg.rd),
3558 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3559 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003560 VppGbpContractRule(
3561 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3562 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3563 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3564 sep3.ip6, sep3.epg.rd),
3565 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3566 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003567 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003568 c1.add_vpp_config()
3569
3570 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003571 self, 402, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003572 [VppGbpContractRule(
3573 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3574 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3575 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3576 sep1.ip4, sep1.epg.rd),
3577 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3578 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003579 VppGbpContractRule(
3580 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3581 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3582 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3583 sep3.ip6, sep3.epg.rd),
3584 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3585 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003586 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003587 c2.add_vpp_config()
3588
3589 #
3590 # send again with the contract preset, now packets arrive
3591 # at SEP1 for both directions
3592 #
3593 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3594
3595 for rx in rxs:
3596 self.assertEqual(rx[Ether].src, routed_src_mac)
3597 self.assertEqual(rx[Ether].dst, sep1.mac)
3598 self.assertEqual(rx[IP].src, ep1.ip4.address)
3599 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3600
3601 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3602
3603 for rx in rxs:
3604 self.assertEqual(rx[Ether].src, routed_src_mac)
3605 self.assertEqual(rx[Ether].dst, sep1.mac)
3606 self.assertEqual(rx[IP].src, ep3.ip4.address)
3607 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3608
Neale Ranns13a08cc2018-11-07 09:25:54 -08003609 #
3610 # programme the unknown EP for the L3 tests
3611 #
3612 sep4.add_vpp_config()
3613
3614 #
3615 # an L3 switch packet between local EPs in different EPGs
3616 # different dest ports on each so the are LB hashed differently
3617 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003618 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003619 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3620 UDP(sport=1234, dport=1234) /
3621 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003622 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003623 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3624 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003625 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003626 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003627 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3628 UDP(sport=1234, dport=1234) /
3629 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003630 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003631 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3632 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003633 Raw('\xa5' * 100))]
3634
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003635 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003636 self, 402, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003637 [VppGbpContractRule(
3638 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3639 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3640 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3641 sep1.ip4, sep1.epg.rd),
3642 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3643 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003644 VppGbpContractRule(
3645 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3646 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3647 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3648 sep3.ip6, sep3.epg.rd),
3649 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3650 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003651 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003652 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003653
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003654 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003655
3656 for rx in rxs:
3657 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003658 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003659 self.assertEqual(rx[IP].src, ep1.ip4.address)
3660 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3661
3662 #
3663 # learn a remote EP in EPG 221
3664 #
3665 vx_tun_l3 = VppGbpVxlanTunnel(
3666 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003667 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3668 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003669 vx_tun_l3.add_vpp_config()
3670
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003671 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003672 self, 402, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003673 [VppGbpContractRule(
3674 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003675 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003676 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003677 VppGbpContractRule(
3678 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003679 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02003680 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003681 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003682 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003683
3684 p = (Ether(src=self.pg7.remote_mac,
3685 dst=self.pg7.local_mac) /
3686 IP(src=self.pg7.remote_ip4,
3687 dst=self.pg7.local_ip4) /
3688 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003689 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003690 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003691 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3692 UDP(sport=1234, dport=1234) /
3693 Raw('\xa5' * 100))
3694
3695 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3696
3697 # endpoint learnt via the parent GBP-vxlan interface
3698 self.assertTrue(find_gbp_endpoint(self,
3699 vx_tun_l3._sw_if_index,
3700 ip="10.0.0.88"))
3701
3702 p = (Ether(src=self.pg7.remote_mac,
3703 dst=self.pg7.local_mac) /
3704 IP(src=self.pg7.remote_ip4,
3705 dst=self.pg7.local_ip4) /
3706 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003707 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003708 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003709 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3710 UDP(sport=1234, dport=1234) /
3711 Raw('\xa5' * 100))
3712
3713 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3714
3715 # endpoint learnt via the parent GBP-vxlan interface
3716 self.assertTrue(find_gbp_endpoint(self,
3717 vx_tun_l3._sw_if_index,
3718 ip="2001:10::88"))
3719
3720 #
3721 # L3 switch from local to remote EP
3722 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003723 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003724 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3725 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003726 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003727 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003728 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3729 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003730 Raw('\xa5' * 100))]
3731
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003732 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003733
3734 for rx in rxs:
3735 self.assertEqual(rx[Ether].src, routed_src_mac)
3736 self.assertEqual(rx[Ether].dst, sep1.mac)
3737 self.assertEqual(rx[IP].src, ep1.ip4.address)
3738 self.assertEqual(rx[IP].dst, "10.0.0.88")
3739
3740 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3741
3742 for rx in rxs:
3743 self.assertEqual(rx[Ether].src, routed_src_mac)
3744 self.assertEqual(rx[Ether].dst, sep4.mac)
3745 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3746 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3747
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003748 #
3749 # test the dst-ip hash mode
3750 #
3751 c5 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003752 self, 402, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003753 [VppGbpContractRule(
3754 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3755 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3756 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3757 sep1.ip4, sep1.epg.rd),
3758 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3759 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003760 VppGbpContractRule(
3761 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3762 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3763 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3764 sep3.ip6, sep3.epg.rd),
3765 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3766 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003767 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003768 c5.add_vpp_config()
3769
3770 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3771
3772 for rx in rxs:
3773 self.assertEqual(rx[Ether].src, routed_src_mac)
3774 self.assertEqual(rx[Ether].dst, sep1.mac)
3775 self.assertEqual(rx[IP].src, ep1.ip4.address)
3776 self.assertEqual(rx[IP].dst, "10.0.0.88")
3777
3778 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003779
3780 for rx in rxs:
3781 self.assertEqual(rx[Ether].src, routed_src_mac)
3782 self.assertEqual(rx[Ether].dst, sep3.mac)
3783 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3784 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3785
Neale Rannsb6a47952018-11-21 05:44:35 -08003786 #
3787 # cleanup
3788 #
3789 self.pg7.unconfig_ip4()
3790
3791 def test_gbp_l3_out(self):
3792 """ GBP L3 Out """
3793
3794 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04003795 self.vapi.cli("set logging class gbp level debug")
Neale Rannsb6a47952018-11-21 05:44:35 -08003796
3797 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3798 routed_src_mac = "00:22:bd:f8:19:ff"
3799
3800 #
3801 # IP tables
3802 #
3803 t4 = VppIpTable(self, 1)
3804 t4.add_vpp_config()
3805 t6 = VppIpTable(self, 1, True)
3806 t6.add_vpp_config()
3807
Neale Ranns160c9232019-06-19 06:25:56 -07003808 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
Neale Rannsb6a47952018-11-21 05:44:35 -08003809 rd1.add_vpp_config()
3810
Ole Troan8006c6a2018-12-17 12:02:26 +01003811 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003812
3813 #
3814 # Bind the BVI to the RD
3815 #
3816 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3817 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3818
3819 #
3820 # Pg7 hosts a BD's BUM
3821 # Pg1 some other l3 interface
3822 #
3823 self.pg7.config_ip4()
3824 self.pg7.resolve_arp()
3825
3826 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003827 # a multicast vxlan-gbp tunnel for broadcast in the BD
3828 #
3829 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3830 "239.1.1.1", 88,
3831 mcast_itf=self.pg7)
3832 tun_bm.add_vpp_config()
3833
3834 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003835 # a GBP external bridge domains for the EPs
3836 #
3837 bd1 = VppBridgeDomain(self, 1)
3838 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003839 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003840 gbd1.add_vpp_config()
3841
3842 #
3843 # The Endpoint-groups in which the external endpoints exist
3844 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003845 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003846 None, gbd1.bvi,
3847 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003848 "2001:10::128",
3849 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003850 epg_220.add_vpp_config()
3851
3852 # the BVIs have the subnets applied ...
3853 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3854 ip4_addr.add_vpp_config()
3855 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3856 ip6_addr.add_vpp_config()
3857
3858 # ... which are L3-out subnets
3859 l3o_1 = VppGbpSubnet(
3860 self, rd1, "10.0.0.0", 24,
3861 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003862 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003863 l3o_1.add_vpp_config()
3864
3865 #
3866 # an external interface attached to the outside world and the
3867 # external BD
3868 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003869 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3870 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00003871 vlan_144 = VppDot1QSubint(self, self.pg0, 144)
3872 vlan_144.admin_up()
Benoît Ganne286921e2019-06-05 19:08:40 +02003873 # vlan_102 is not poped
Neale Ranns36abbf12019-03-12 02:34:07 -07003874
Neale Rannsb6a47952018-11-21 05:44:35 -08003875 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003876 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003877 #
3878 vx_tun_l3 = VppGbpVxlanTunnel(
3879 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003880 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3881 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003882 vx_tun_l3.add_vpp_config()
3883
3884 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003885 # External Endpoints
3886 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003887 eep1 = VppGbpEndpoint(self, self.vlan_100,
Neale Ranns36abbf12019-03-12 02:34:07 -07003888 epg_220, None,
3889 "10.0.0.1", "11.0.0.1",
3890 "2001:10::1", "3001::1",
3891 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3892 eep1.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003893 eep2 = VppGbpEndpoint(self, self.vlan_101,
Neale Ranns36abbf12019-03-12 02:34:07 -07003894 epg_220, None,
3895 "10.0.0.2", "11.0.0.2",
3896 "2001:10::2", "3001::2",
3897 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3898 eep2.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003899 eep3 = VppGbpEndpoint(self, self.vlan_102,
Benoît Ganne286921e2019-06-05 19:08:40 +02003900 epg_220, None,
3901 "10.0.0.3", "11.0.0.3",
3902 "2001:10::3", "3001::3",
3903 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3904 eep3.add_vpp_config()
Neale Ranns36abbf12019-03-12 02:34:07 -07003905
3906 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003907 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003908 #
3909 rep = VppGbpEndpoint(self, vx_tun_l3,
3910 epg_220, None,
3911 "10.0.0.101", "11.0.0.101",
3912 "2001:10::101", "3001::101",
3913 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3914 self.pg7.local_ip4,
3915 self.pg7.remote_ip4,
3916 mac=None)
3917 rep.add_vpp_config()
3918
3919 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02003920 # EP1 impersonating EP3 is dropped
3921 #
3922 p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3923 Dot1Q(vlan=100) /
3924 ARP(op="who-has",
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003925 psrc="10.0.0.3", pdst="10.0.0.128",
3926 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Gannec47b97d2019-06-06 17:53:21 +02003927 self.send_and_assert_no_replies(self.pg0, p)
3928
3929 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003930 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003931 #
3932 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3933 Dot1Q(vlan=100) /
3934 ARP(op="who-has",
3935 psrc=eep1.ip4.address, pdst="10.0.0.128",
3936 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
3937 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3938
3939 #
Benoît Ganne286921e2019-06-05 19:08:40 +02003940 # ARP packet from host in remote subnet are accepted and replied to
3941 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02003942 p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") /
Benoît Ganne286921e2019-06-05 19:08:40 +02003943 Dot1Q(vlan=102) /
3944 ARP(op="who-has",
Benoît Gannec47b97d2019-06-06 17:53:21 +02003945 psrc=eep3.ip4.address, pdst="10.0.0.128",
3946 hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Ganne286921e2019-06-05 19:08:40 +02003947 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
3948
3949 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07003950 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08003951 # are ARP'd for
3952 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003953 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003954 Dot1Q(vlan=100) /
3955 IP(src="10.0.0.1", dst="10.0.0.88") /
3956 UDP(sport=1234, dport=1234) /
3957 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07003958 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003959 Dot1Q(vlan=100) /
3960 IPv6(src="2001:10::1", dst="2001:10::88") /
3961 UDP(sport=1234, dport=1234) /
3962 Raw('\xa5' * 100))
3963
3964 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3965
3966 for rx in rxs:
3967 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3968 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3969 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3970 self.assertEqual(rx[IP].dst, "239.1.1.1")
3971 self.assertEqual(rx[VXLAN].vni, 88)
3972 self.assertTrue(rx[VXLAN].flags.G)
3973 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08003974 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08003975 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08003976 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08003977 self.assertFalse(rx[VXLAN].gpflags.D)
3978
3979 inner = rx[VXLAN].payload
3980
3981 self.assertTrue(inner.haslayer(ARP))
3982
3983 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003984 # remote to external
3985 #
3986 p = (Ether(src=self.pg7.remote_mac,
3987 dst=self.pg7.local_mac) /
3988 IP(src=self.pg7.remote_ip4,
3989 dst=self.pg7.local_ip4) /
3990 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003991 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003992 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08003993 IP(src="10.0.0.101", dst="10.0.0.1") /
3994 UDP(sport=1234, dport=1234) /
3995 Raw('\xa5' * 100))
3996
3997 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3998
3999 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004000 # local EP pings router
4001 #
4002 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4003 Dot1Q(vlan=100) /
4004 IP(src=eep1.ip4.address, dst="10.0.0.128") /
4005 ICMP(type='echo-request'))
4006
4007 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4008
4009 for rx in rxs:
4010 self.assertEqual(rx[Ether].src, str(self.router_mac))
4011 self.assertEqual(rx[Ether].dst, eep1.mac)
4012 self.assertEqual(rx[Dot1Q].vlan, 100)
4013
4014 #
4015 # local EP pings other local EP
4016 #
4017 p = (Ether(src=eep1.mac, dst=eep2.mac) /
4018 Dot1Q(vlan=100) /
4019 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
4020 ICMP(type='echo-request'))
4021
4022 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4023
4024 for rx in rxs:
4025 self.assertEqual(rx[Ether].src, eep1.mac)
4026 self.assertEqual(rx[Ether].dst, eep2.mac)
4027 self.assertEqual(rx[Dot1Q].vlan, 101)
4028
4029 #
Benoît Ganne286921e2019-06-05 19:08:40 +02004030 # local EP pings router w/o vlan tag poped
4031 #
4032 p = (Ether(src=eep3.mac, dst=str(self.router_mac)) /
4033 Dot1Q(vlan=102) /
4034 IP(src=eep3.ip4.address, dst="10.0.0.128") /
4035 ICMP(type='echo-request'))
4036
4037 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4038
4039 for rx in rxs:
4040 self.assertEqual(rx[Ether].src, str(self.router_mac))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004041 self.assertEqual(rx[Ether].dst, self.vlan_102.remote_mac)
Benoît Ganne286921e2019-06-05 19:08:40 +02004042
4043 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004044 # A ip4 subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08004045 #
4046 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07004047 [VppRoutePath(eep1.ip4.address,
4048 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08004049 table_id=t4.table_id)
4050 ip_220.add_vpp_config()
4051
4052 l3o_220 = VppGbpSubnet(
4053 self, rd1, "10.220.0.0", 24,
4054 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004055 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08004056 l3o_220.add_vpp_config()
4057
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004058 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004059 # An ip6 subnet reachable through the external EP1
4060 #
4061 ip6_220 = VppIpRoute(self, "10:220::", 64,
4062 [VppRoutePath(eep1.ip6.address,
4063 eep1.epg.bvi.sw_if_index)],
4064 table_id=t6.table_id)
4065 ip6_220.add_vpp_config()
4066
4067 l3o6_220 = VppGbpSubnet(
4068 self, rd1, "10:220::", 64,
4069 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4070 sclass=4220)
4071 l3o6_220.add_vpp_config()
4072
4073 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004074 # A subnet reachable through the external EP2
4075 #
4076 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
4077 [VppRoutePath(eep2.ip4.address,
4078 eep2.epg.bvi.sw_if_index)],
4079 table_id=t4.table_id)
4080 ip_221.add_vpp_config()
4081
4082 l3o_221 = VppGbpSubnet(
4083 self, rd1, "10.221.0.0", 24,
4084 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4085 sclass=4221)
4086 l3o_221.add_vpp_config()
4087
4088 #
4089 # ping between hosts in remote subnets
4090 # dropped without a contract
4091 #
4092 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4093 Dot1Q(vlan=100) /
4094 IP(src="10.220.0.1", dst="10.221.0.1") /
4095 ICMP(type='echo-request'))
4096
Neale Ranns160c9232019-06-19 06:25:56 -07004097 self.send_and_assert_no_replies(self.pg0, p * 1)
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004098
4099 #
4100 # contract for the external nets to communicate
4101 #
4102 acl = VppGbpAcl(self)
4103 rule4 = acl.create_rule(permit_deny=1, proto=17)
4104 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
4105 acl_index = acl.add_vpp_config([rule4, rule6])
4106
Neale Ranns160c9232019-06-19 06:25:56 -07004107 #
4108 # A contract with the wrong scope is not matched
4109 #
4110 c_44 = VppGbpContract(
4111 self, 44, 4220, 4221, acl_index,
4112 [VppGbpContractRule(
4113 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4114 []),
4115 VppGbpContractRule(
4116 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4117 [])],
4118 [ETH_P_IP, ETH_P_IPV6])
4119 c_44.add_vpp_config()
4120 self.send_and_assert_no_replies(self.pg0, p * 1)
4121
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004122 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004123 self, 55, 4220, 4221, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004124 [VppGbpContractRule(
4125 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004126 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004127 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004128 VppGbpContractRule(
4129 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004130 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004131 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004132 [ETH_P_IP, ETH_P_IPV6])
4133 c1.add_vpp_config()
4134
4135 #
4136 # Contracts allowing ext-net 200 to talk with external EPs
4137 #
4138 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004139 self, 55, 4220, 113, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004140 [VppGbpContractRule(
4141 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004142 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004143 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004144 VppGbpContractRule(
4145 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004146 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004147 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004148 [ETH_P_IP, ETH_P_IPV6])
4149 c2.add_vpp_config()
4150 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004151 self, 55, 113, 4220, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004152 [VppGbpContractRule(
4153 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004154 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004155 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004156 VppGbpContractRule(
4157 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004158 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004159 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004160 [ETH_P_IP, ETH_P_IPV6])
4161 c3.add_vpp_config()
4162
4163 #
4164 # ping between hosts in remote subnets
4165 #
4166 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4167 Dot1Q(vlan=100) /
4168 IP(src="10.220.0.1", dst="10.221.0.1") /
4169 UDP(sport=1234, dport=1234) /
4170 Raw('\xa5' * 100))
4171
4172 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4173
4174 for rx in rxs:
4175 self.assertEqual(rx[Ether].src, str(self.router_mac))
4176 self.assertEqual(rx[Ether].dst, eep2.mac)
4177 self.assertEqual(rx[Dot1Q].vlan, 101)
4178
4179 # we did not learn these external hosts
4180 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
4181 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
4182
4183 #
4184 # from remote external EP to local external EP
4185 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004186 p = (Ether(src=self.pg7.remote_mac,
4187 dst=self.pg7.local_mac) /
4188 IP(src=self.pg7.remote_ip4,
4189 dst=self.pg7.local_ip4) /
4190 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08004191 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01004192 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004193 IP(src="10.0.0.101", dst="10.220.0.1") /
4194 UDP(sport=1234, dport=1234) /
4195 Raw('\xa5' * 100))
4196
4197 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4198
4199 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004200 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07004201 #
4202 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4203 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004204 IP(src="10.220.0.1", dst=rep.ip4.address) /
4205 UDP(sport=1234, dport=1234) /
4206 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07004207
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004208 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07004209
4210 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004211 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4212 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4213 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4214 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4215 self.assertEqual(rx[VXLAN].vni, 444)
4216 self.assertTrue(rx[VXLAN].flags.G)
4217 self.assertTrue(rx[VXLAN].flags.Instance)
4218 # the sclass of the ext-net the packet came from
4219 self.assertEqual(rx[VXLAN].gpid, 4220)
4220 # policy was applied to the original IP packet
4221 self.assertTrue(rx[VXLAN].gpflags.A)
4222 # since it's an external host the reciever should not learn it
4223 self.assertTrue(rx[VXLAN].gpflags.D)
4224 inner = rx[VXLAN].payload
4225 self.assertEqual(inner[IP].src, "10.220.0.1")
4226 self.assertEqual(inner[IP].dst, rep.ip4.address)
4227
4228 #
4229 # An external subnet reachable via the remote external EP
4230 #
4231
4232 #
4233 # first the VXLAN-GBP tunnel over which it is reached
4234 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004235 vx_tun_r1 = VppVxlanGbpTunnel(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004236 self, self.pg7.local_ip4,
4237 self.pg7.remote_ip4, 445,
4238 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4239 VXLAN_GBP_API_TUNNEL_MODE_L3))
Neale Ranns69a85b52019-06-14 07:49:50 +00004240 vx_tun_r1.add_vpp_config()
4241 VppIpInterfaceBind(self, vx_tun_r1, t4).add_vpp_config()
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004242
4243 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4244
4245 #
4246 # then the special adj to resolve through on that tunnel
4247 #
4248 n1 = VppNeighbor(self,
Neale Ranns69a85b52019-06-14 07:49:50 +00004249 vx_tun_r1.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004250 "00:0c:0c:0c:0c:0c",
4251 self.pg7.remote_ip4)
4252 n1.add_vpp_config()
4253
4254 #
4255 # the route via the adj above
4256 #
4257 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
4258 [VppRoutePath(self.pg7.remote_ip4,
Neale Ranns69a85b52019-06-14 07:49:50 +00004259 vx_tun_r1.sw_if_index)],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004260 table_id=t4.table_id)
4261 ip_222.add_vpp_config()
4262
4263 l3o_222 = VppGbpSubnet(
4264 self, rd1, "10.222.0.0", 24,
4265 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4266 sclass=4222)
4267 l3o_222.add_vpp_config()
4268
4269 #
4270 # ping between hosts in local and remote external subnets
4271 # dropped without a contract
4272 #
4273 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4274 Dot1Q(vlan=100) /
4275 IP(src="10.220.0.1", dst="10.222.0.1") /
4276 UDP(sport=1234, dport=1234) /
4277 Raw('\xa5' * 100))
4278
4279 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
4280
4281 #
4282 # Add contracts ext-nets for 220 -> 222
4283 #
4284 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004285 self, 55, 4220, 4222, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004286 [VppGbpContractRule(
4287 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004288 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004289 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004290 VppGbpContractRule(
4291 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004292 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004293 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004294 [ETH_P_IP, ETH_P_IPV6])
4295 c4.add_vpp_config()
4296
4297 #
4298 # ping from host in local to remote external subnets
4299 #
4300 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4301 Dot1Q(vlan=100) /
4302 IP(src="10.220.0.1", dst="10.222.0.1") /
4303 UDP(sport=1234, dport=1234) /
4304 Raw('\xa5' * 100))
4305
4306 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
4307
4308 for rx in rxs:
4309 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4310 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4311 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4312 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4313 self.assertEqual(rx[VXLAN].vni, 445)
4314 self.assertTrue(rx[VXLAN].flags.G)
4315 self.assertTrue(rx[VXLAN].flags.Instance)
4316 # the sclass of the ext-net the packet came from
4317 self.assertEqual(rx[VXLAN].gpid, 4220)
4318 # policy was applied to the original IP packet
4319 self.assertTrue(rx[VXLAN].gpflags.A)
4320 # since it's an external host the reciever should not learn it
4321 self.assertTrue(rx[VXLAN].gpflags.D)
4322 inner = rx[VXLAN].payload
4323 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
4324 self.assertEqual(inner[IP].src, "10.220.0.1")
4325 self.assertEqual(inner[IP].dst, "10.222.0.1")
4326
4327 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004328 # make the external subnet ECMP
4329 #
4330 vx_tun_r2 = VppVxlanGbpTunnel(
4331 self, self.pg7.local_ip4,
4332 self.pg7.remote_ip4, 446,
4333 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4334 VXLAN_GBP_API_TUNNEL_MODE_L3))
4335 vx_tun_r2.add_vpp_config()
4336 VppIpInterfaceBind(self, vx_tun_r2, t4).add_vpp_config()
4337
4338 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4339
4340 n2 = VppNeighbor(self,
4341 vx_tun_r2.sw_if_index,
4342 "00:0c:0c:0c:0c:0c",
4343 self.pg7.remote_ip4)
4344 n2.add_vpp_config()
4345
4346 ip_222.modify([VppRoutePath(self.pg7.remote_ip4,
4347 vx_tun_r1.sw_if_index),
4348 VppRoutePath(self.pg7.remote_ip4,
4349 vx_tun_r2.sw_if_index)])
4350
4351 #
4352 # now expect load-balance
4353 #
4354 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
4355 Dot1Q(vlan=100) /
4356 IP(src="10.220.0.1", dst="10.222.0.1") /
4357 UDP(sport=1234, dport=1234) /
4358 Raw('\xa5' * 100)),
4359 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4360 Dot1Q(vlan=100) /
4361 IP(src="10.220.0.1", dst="10.222.0.1") /
4362 UDP(sport=1222, dport=1235) /
4363 Raw('\xa5' * 100))]
4364
4365 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4366
4367 self.assertEqual(rxs[0][VXLAN].vni, 445)
4368 self.assertEqual(rxs[1][VXLAN].vni, 446)
4369
4370 #
4371 # Same LB test for v6
4372 #
4373 n3 = VppNeighbor(self,
4374 vx_tun_r1.sw_if_index,
4375 "00:0c:0c:0c:0c:0c",
4376 self.pg7.remote_ip6)
4377 n3.add_vpp_config()
4378 n4 = VppNeighbor(self,
4379 vx_tun_r2.sw_if_index,
4380 "00:0c:0c:0c:0c:0c",
4381 self.pg7.remote_ip6)
4382 n4.add_vpp_config()
4383
4384 ip_222_6 = VppIpRoute(self, "10:222::", 64,
4385 [VppRoutePath(self.pg7.remote_ip6,
4386 vx_tun_r1.sw_if_index),
4387 VppRoutePath(self.pg7.remote_ip6,
4388 vx_tun_r2.sw_if_index)],
4389 table_id=t6.table_id)
4390 ip_222_6.add_vpp_config()
4391
4392 l3o_222_6 = VppGbpSubnet(
4393 self, rd1, "10:222::", 64,
4394 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4395 sclass=4222)
4396 l3o_222_6.add_vpp_config()
4397
4398 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
4399 Dot1Q(vlan=100) /
4400 IPv6(src="10:220::1", dst="10:222::1") /
4401 UDP(sport=1234, dport=1234) /
4402 Raw('\xa5' * 100)),
4403 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4404 Dot1Q(vlan=100) /
4405 IPv6(src="10:220::1", dst="10:222::1") /
4406 UDP(sport=7777, dport=8881) /
4407 Raw('\xa5' * 100))]
4408
4409 self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1"))
4410 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4411
4412 self.assertEqual(rxs[0][VXLAN].vni, 445)
4413 self.assertEqual(rxs[1][VXLAN].vni, 446)
4414
4415 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004416 # ping from host in remote to local external subnets
4417 # there's no contract for this, but the A bit is set.
4418 #
4419 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4420 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4421 UDP(sport=1234, dport=48879) /
4422 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4423 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4424 IP(src="10.222.0.1", dst="10.220.0.1") /
4425 UDP(sport=1234, dport=1234) /
4426 Raw('\xa5' * 100))
4427
4428 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
4429 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07004430
4431 #
Neale Ranns2b600182019-03-29 05:08:27 -07004432 # ping from host in remote to remote external subnets
4433 # this is dropped by reflection check.
4434 #
4435 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4436 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4437 UDP(sport=1234, dport=48879) /
4438 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4439 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4440 IP(src="10.222.0.1", dst="10.222.0.2") /
4441 UDP(sport=1234, dport=1234) /
4442 Raw('\xa5' * 100))
4443
4444 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
4445
Neale Ranns69a85b52019-06-14 07:49:50 +00004446 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4447 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4448 UDP(sport=1234, dport=48879) /
4449 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4450 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4451 IPv6(src="10:222::1", dst="10:222::2") /
4452 UDP(sport=1234, dport=1234) /
4453 Raw('\xa5' * 100))
4454
4455 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
4456
4457 #
4458 # local EP
4459 #
4460 lep1 = VppGbpEndpoint(self, vlan_144,
4461 epg_220, None,
4462 "10.0.0.44", "11.0.0.44",
4463 "2001:10::44", "3001::44")
4464 lep1.add_vpp_config()
4465
4466 #
4467 # local EP to local ip4 external subnet
4468 #
4469 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4470 Dot1Q(vlan=144) /
4471 IP(src=lep1.ip4.address, dst="10.220.0.1") /
4472 UDP(sport=1234, dport=1234) /
4473 Raw('\xa5' * 100))
4474
4475 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4476
4477 for rx in rxs:
4478 self.assertEqual(rx[Ether].src, str(self.router_mac))
4479 self.assertEqual(rx[Ether].dst, eep1.mac)
4480 self.assertEqual(rx[Dot1Q].vlan, 100)
4481
4482 #
4483 # local EP to local ip6 external subnet
4484 #
4485 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4486 Dot1Q(vlan=144) /
4487 IPv6(src=lep1.ip6.address, dst="10:220::1") /
4488 UDP(sport=1234, dport=1234) /
4489 Raw('\xa5' * 100))
4490
4491 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4492
4493 for rx in rxs:
4494 self.assertEqual(rx[Ether].src, str(self.router_mac))
4495 self.assertEqual(rx[Ether].dst, eep1.mac)
4496 self.assertEqual(rx[Dot1Q].vlan, 100)
4497
4498 #
4499 # ip4 and ip6 subnets that load-balance
4500 #
4501 ip_20 = VppIpRoute(self, "10.20.0.0", 24,
4502 [VppRoutePath(eep1.ip4.address,
4503 eep1.epg.bvi.sw_if_index),
4504 VppRoutePath(eep2.ip4.address,
4505 eep2.epg.bvi.sw_if_index)],
4506 table_id=t4.table_id)
4507 ip_20.add_vpp_config()
4508
4509 l3o_20 = VppGbpSubnet(
4510 self, rd1, "10.20.0.0", 24,
4511 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4512 sclass=4220)
4513 l3o_20.add_vpp_config()
4514
4515 ip6_20 = VppIpRoute(self, "10:20::", 64,
4516 [VppRoutePath(eep1.ip6.address,
4517 eep1.epg.bvi.sw_if_index),
4518 VppRoutePath(eep2.ip6.address,
4519 eep2.epg.bvi.sw_if_index)],
4520 table_id=t6.table_id)
4521 ip6_20.add_vpp_config()
4522
4523 l3o6_20 = VppGbpSubnet(
4524 self, rd1, "10:20::", 64,
4525 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4526 sclass=4220)
4527 l3o6_20.add_vpp_config()
4528
4529 self.logger.info(self.vapi.cli("sh ip fib 10.20.0.1"))
4530 self.logger.info(self.vapi.cli("sh ip6 fib 10:20::1"))
4531
4532 # two ip6 packets whose port are chosen so they load-balance
4533 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
4534 Dot1Q(vlan=144) /
4535 IPv6(src=lep1.ip6.address, dst="10:20::1") /
4536 UDP(sport=1234, dport=1234) /
4537 Raw('\xa5' * 100)),
4538 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4539 Dot1Q(vlan=144) /
4540 IPv6(src=lep1.ip6.address, dst="10:20::1") /
4541 UDP(sport=124, dport=1230) /
4542 Raw('\xa5' * 100))]
4543
4544 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
4545
4546 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
4547 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
4548
4549 # two ip4 packets whose port are chosen so they load-balance
4550 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
4551 Dot1Q(vlan=144) /
4552 IP(src=lep1.ip4.address, dst="10.20.0.1") /
4553 UDP(sport=1235, dport=1235) /
4554 Raw('\xa5' * 100)),
4555 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4556 Dot1Q(vlan=144) /
4557 IP(src=lep1.ip4.address, dst="10.20.0.1") /
4558 UDP(sport=124, dport=1230) /
4559 Raw('\xa5' * 100))]
4560
4561 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
4562
4563 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
4564 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
4565
Neale Ranns2b600182019-03-29 05:08:27 -07004566 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004567 # cleanup
4568 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004569 ip_222.remove_vpp_config()
Neale Rannsb6a47952018-11-21 05:44:35 -08004570 self.pg7.unconfig_ip4()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004571 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
4572 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
4573
4574 def test_gbp_anon_l3_out(self):
4575 """ GBP Anonymous L3 Out """
4576
4577 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
4578 self.vapi.cli("set logging class gbp level debug")
4579
4580 routed_dst_mac = "00:0c:0c:0c:0c:0c"
4581 routed_src_mac = "00:22:bd:f8:19:ff"
4582
4583 #
4584 # IP tables
4585 #
4586 t4 = VppIpTable(self, 1)
4587 t4.add_vpp_config()
4588 t6 = VppIpTable(self, 1, True)
4589 t6.add_vpp_config()
4590
4591 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
4592 rd1.add_vpp_config()
4593
4594 self.loop0.set_mac(self.router_mac)
4595
4596 #
4597 # Bind the BVI to the RD
4598 #
4599 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
4600 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
4601
4602 #
4603 # Pg7 hosts a BD's BUM
4604 # Pg1 some other l3 interface
4605 #
4606 self.pg7.config_ip4()
4607 self.pg7.resolve_arp()
4608
4609 #
4610 # a GBP external bridge domains for the EPs
4611 #
4612 bd1 = VppBridgeDomain(self, 1)
4613 bd1.add_vpp_config()
4614 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, None)
4615 gbd1.add_vpp_config()
4616
4617 #
4618 # The Endpoint-groups in which the external endpoints exist
4619 #
4620 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
4621 None, gbd1.bvi,
4622 "10.0.0.128",
4623 "2001:10::128",
4624 VppGbpEndpointRetention(2))
4625 epg_220.add_vpp_config()
4626
4627 # the BVIs have the subnet applied ...
4628 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
4629 ip4_addr.add_vpp_config()
4630
4631 # ... which is an Anonymous L3-out subnets
4632 l3o_1 = VppGbpSubnet(
4633 self, rd1, "10.0.0.0", 24,
4634 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_ANON_L3_OUT,
4635 sclass=113)
4636 l3o_1.add_vpp_config()
4637
4638 #
4639 # an external interface attached to the outside world and the
4640 # external BD
4641 #
4642 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
4643 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
4644
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004645 #
4646 # vlan_100 and vlan_101 are anonymous l3-out interfaces
4647 #
4648 ext_itf = VppGbpExtItf(self, self.vlan_100, bd1, rd1, anon=True)
4649 ext_itf.add_vpp_config()
4650 ext_itf = VppGbpExtItf(self, self.vlan_101, bd1, rd1, anon=True)
4651 ext_itf.add_vpp_config()
4652
4653 #
4654 # an unicast vxlan-gbp for inter-RD traffic
4655 #
4656 vx_tun_l3 = VppGbpVxlanTunnel(
4657 self, 444, rd1.rd_id,
4658 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
4659 self.pg2.local_ip4)
4660 vx_tun_l3.add_vpp_config()
4661
4662 #
4663 # A remote external endpoint
4664 #
4665 rep = VppGbpEndpoint(self, vx_tun_l3,
4666 epg_220, None,
4667 "10.0.0.201", "11.0.0.201",
4668 "2001:10::201", "3001::101",
4669 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
4670 self.pg7.local_ip4,
4671 self.pg7.remote_ip4,
4672 mac=None)
4673 rep.add_vpp_config()
4674
4675 #
4676 # ARP packet from host in external subnet are accepted, flooded and
4677 # replied to. We expect 2 packets:
4678 # - APR request flooded over the other vlan subif
4679 # - ARP reply from BVI
4680 #
4681 p_arp = (Ether(src=self.vlan_100.remote_mac,
4682 dst="ff:ff:ff:ff:ff:ff") /
4683 Dot1Q(vlan=100) /
4684 ARP(op="who-has",
4685 psrc="10.0.0.100",
4686 pdst="10.0.0.128",
4687 hwsrc=self.vlan_100.remote_mac,
4688 hwdst="ff:ff:ff:ff:ff:ff"))
4689 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
4690
4691 p_arp = (Ether(src=self.vlan_101.remote_mac,
4692 dst="ff:ff:ff:ff:ff:ff") /
4693 Dot1Q(vlan=101) /
4694 ARP(op="who-has",
4695 psrc='10.0.0.101',
4696 pdst="10.0.0.128",
4697 hwsrc=self.vlan_101.remote_mac,
4698 hwdst="ff:ff:ff:ff:ff:ff"))
4699 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
4700
4701 #
4702 # remote to external
4703 #
4704 p = (Ether(src=self.pg7.remote_mac,
4705 dst=self.pg7.local_mac) /
4706 IP(src=self.pg7.remote_ip4,
4707 dst=self.pg7.local_ip4) /
4708 UDP(sport=1234, dport=48879) /
4709 VXLAN(vni=vx_tun_l3.vni, gpid=epg_220.sclass, flags=0x88) /
4710 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4711 IP(src=str(rep.ip4), dst="10.0.0.100") /
4712 UDP(sport=1234, dport=1234) /
4713 Raw('\xa5' * 100))
4714 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4715
4716 #
4717 # local EP pings router
4718 #
4719 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4720 Dot1Q(vlan=100) /
4721 IP(src="10.0.0.100", dst="10.0.0.128") /
4722 ICMP(type='echo-request'))
4723 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4724
4725 for rx in rxs:
4726 self.assertEqual(rx[Ether].src, str(self.router_mac))
4727 self.assertEqual(rx[Ether].dst, self.vlan_100.remote_mac)
4728 self.assertEqual(rx[Dot1Q].vlan, 100)
4729
4730 #
4731 # local EP pings other local EP
4732 #
4733 p = (Ether(src=self.vlan_100.remote_mac,
4734 dst=self.vlan_101.remote_mac) /
4735 Dot1Q(vlan=100) /
4736 IP(src="10.0.0.100", dst="10.0.0.101") /
4737 ICMP(type='echo-request'))
4738 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4739
4740 for rx in rxs:
4741 self.assertEqual(rx[Ether].src, self.vlan_100.remote_mac)
4742 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
4743 self.assertEqual(rx[Dot1Q].vlan, 101)
4744
4745 #
4746 # A subnet reachable through an external router on vlan 100
4747 #
4748 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
4749 [VppRoutePath("10.0.0.100",
4750 epg_220.bvi.sw_if_index)],
4751 table_id=t4.table_id)
4752 ip_220.add_vpp_config()
4753
4754 l3o_220 = VppGbpSubnet(
4755 self, rd1, "10.220.0.0", 24,
4756 # note: this a "regular" L3 out subnet (not connected)
4757 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4758 sclass=4220)
4759 l3o_220.add_vpp_config()
4760
4761 #
4762 # A subnet reachable through an external router on vlan 101
4763 #
4764 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
4765 [VppRoutePath("10.0.0.101",
4766 epg_220.bvi.sw_if_index)],
4767 table_id=t4.table_id)
4768 ip_221.add_vpp_config()
4769
4770 l3o_221 = VppGbpSubnet(
4771 self, rd1, "10.221.0.0", 24,
4772 # note: this a "regular" L3 out subnet (not connected)
4773 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4774 sclass=4221)
4775 l3o_221.add_vpp_config()
4776
4777 #
4778 # ping between hosts in remote subnets
4779 # dropped without a contract
4780 #
4781 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4782 Dot1Q(vlan=100) /
4783 IP(src="10.220.0.1", dst="10.221.0.1") /
4784 ICMP(type='echo-request'))
4785
4786 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
4787
4788 #
4789 # contract for the external nets to communicate
4790 #
4791 acl = VppGbpAcl(self)
4792 rule4 = acl.create_rule(permit_deny=1, proto=17)
4793 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
4794 acl_index = acl.add_vpp_config([rule4, rule6])
4795
4796 c1 = VppGbpContract(
4797 self, 55, 4220, 4221, acl_index,
4798 [VppGbpContractRule(
4799 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4800 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4801 []),
4802 VppGbpContractRule(
4803 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4804 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4805 [])],
4806 [ETH_P_IP, ETH_P_IPV6])
4807 c1.add_vpp_config()
4808
4809 #
4810 # Contracts allowing ext-net 200 to talk with external EPs
4811 #
4812 c2 = VppGbpContract(
4813 self, 55, 4220, 113, acl_index,
4814 [VppGbpContractRule(
4815 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4816 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4817 []),
4818 VppGbpContractRule(
4819 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4820 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4821 [])],
4822 [ETH_P_IP, ETH_P_IPV6])
4823 c2.add_vpp_config()
4824 c3 = VppGbpContract(
4825 self, 55, 113, 4220, acl_index,
4826 [VppGbpContractRule(
4827 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4828 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4829 []),
4830 VppGbpContractRule(
4831 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4832 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4833 [])],
4834 [ETH_P_IP, ETH_P_IPV6])
4835 c3.add_vpp_config()
4836
4837 #
4838 # ping between hosts in remote subnets
4839 #
4840 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4841 Dot1Q(vlan=100) /
4842 IP(src="10.220.0.1", dst="10.221.0.1") /
4843 UDP(sport=1234, dport=1234) /
4844 Raw('\xa5' * 100))
4845
4846 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4847
4848 for rx in rxs:
4849 self.assertEqual(rx[Ether].src, str(self.router_mac))
4850 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
4851 self.assertEqual(rx[Dot1Q].vlan, 101)
4852
4853 # we did not learn these external hosts
4854 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
4855 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
4856
4857 #
4858 # from remote external EP to local external EP
4859 #
4860 p = (Ether(src=self.pg7.remote_mac,
4861 dst=self.pg7.local_mac) /
4862 IP(src=self.pg7.remote_ip4,
4863 dst=self.pg7.local_ip4) /
4864 UDP(sport=1234, dport=48879) /
4865 VXLAN(vni=444, gpid=113, flags=0x88) /
4866 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4867 IP(src=rep.ip4.address, dst="10.220.0.1") /
4868 UDP(sport=1234, dport=1234) /
4869 Raw('\xa5' * 100))
4870
4871 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4872
4873 #
4874 # ping from an external host to the remote external EP
4875 #
4876 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4877 Dot1Q(vlan=100) /
4878 IP(src="10.220.0.1", dst=rep.ip4.address) /
4879 UDP(sport=1234, dport=1234) /
4880 Raw('\xa5' * 100))
4881
4882 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
4883
4884 for rx in rxs:
4885 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4886 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4887 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4888 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4889 self.assertEqual(rx[VXLAN].vni, 444)
4890 self.assertTrue(rx[VXLAN].flags.G)
4891 self.assertTrue(rx[VXLAN].flags.Instance)
4892 # the sclass of the ext-net the packet came from
4893 self.assertEqual(rx[VXLAN].gpid, 4220)
4894 # policy was applied to the original IP packet
4895 self.assertTrue(rx[VXLAN].gpflags.A)
4896 # since it's an external host the reciever should not learn it
4897 self.assertTrue(rx[VXLAN].gpflags.D)
4898 inner = rx[VXLAN].payload
4899 self.assertEqual(inner[IP].src, "10.220.0.1")
4900 self.assertEqual(inner[IP].dst, rep.ip4.address)
4901
4902 #
4903 # An external subnet reachable via the remote external EP
4904 #
4905
4906 #
4907 # first the VXLAN-GBP tunnel over which it is reached
4908 #
4909 vx_tun_r = VppVxlanGbpTunnel(
4910 self, self.pg7.local_ip4,
4911 self.pg7.remote_ip4, 445,
4912 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4913 VXLAN_GBP_API_TUNNEL_MODE_L3))
4914 vx_tun_r.add_vpp_config()
4915 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
4916
4917 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4918
4919 #
4920 # then the special adj to resolve through on that tunnel
4921 #
4922 n1 = VppNeighbor(self,
4923 vx_tun_r.sw_if_index,
4924 "00:0c:0c:0c:0c:0c",
4925 self.pg7.remote_ip4)
4926 n1.add_vpp_config()
4927
4928 #
4929 # the route via the adj above
4930 #
4931 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
4932 [VppRoutePath(self.pg7.remote_ip4,
4933 vx_tun_r.sw_if_index)],
4934 table_id=t4.table_id)
4935 ip_222.add_vpp_config()
4936
4937 l3o_222 = VppGbpSubnet(
4938 self, rd1, "10.222.0.0", 24,
4939 # note: this a "regular" l3out subnet (not connected)
4940 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4941 sclass=4222)
4942 l3o_222.add_vpp_config()
4943
4944 #
4945 # ping between hosts in local and remote external subnets
4946 # dropped without a contract
4947 #
4948 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4949 Dot1Q(vlan=100) /
4950 IP(src="10.220.0.1", dst="10.222.0.1") /
4951 UDP(sport=1234, dport=1234) /
4952 Raw('\xa5' * 100))
4953
4954 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
4955
4956 #
4957 # Add contracts ext-nets for 220 -> 222
4958 #
4959 c4 = VppGbpContract(
4960 self, 55, 4220, 4222, acl_index,
4961 [VppGbpContractRule(
4962 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4963 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4964 []),
4965 VppGbpContractRule(
4966 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4967 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4968 [])],
4969 [ETH_P_IP, ETH_P_IPV6])
4970 c4.add_vpp_config()
4971
4972 #
4973 # ping from host in local to remote external subnets
4974 #
4975 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4976 Dot1Q(vlan=100) /
4977 IP(src="10.220.0.1", dst="10.222.0.1") /
4978 UDP(sport=1234, dport=1234) /
4979 Raw('\xa5' * 100))
4980
4981 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
4982
4983 for rx in rxs:
4984 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4985 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4986 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4987 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4988 self.assertEqual(rx[VXLAN].vni, 445)
4989 self.assertTrue(rx[VXLAN].flags.G)
4990 self.assertTrue(rx[VXLAN].flags.Instance)
4991 # the sclass of the ext-net the packet came from
4992 self.assertEqual(rx[VXLAN].gpid, 4220)
4993 # policy was applied to the original IP packet
4994 self.assertTrue(rx[VXLAN].gpflags.A)
4995 # since it's an external host the reciever should not learn it
4996 self.assertTrue(rx[VXLAN].gpflags.D)
4997 inner = rx[VXLAN].payload
4998 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
4999 self.assertEqual(inner[IP].src, "10.220.0.1")
5000 self.assertEqual(inner[IP].dst, "10.222.0.1")
5001
5002 #
5003 # ping from host in remote to local external subnets
5004 # there's no contract for this, but the A bit is set.
5005 #
5006 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5007 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5008 UDP(sport=1234, dport=48879) /
5009 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5010 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5011 IP(src="10.222.0.1", dst="10.220.0.1") /
5012 UDP(sport=1234, dport=1234) /
5013 Raw('\xa5' * 100))
5014
5015 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
5016 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
5017
5018 #
5019 # ping from host in remote to remote external subnets
5020 # this is dropped by reflection check.
5021 #
5022 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5023 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5024 UDP(sport=1234, dport=48879) /
5025 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5026 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5027 IP(src="10.222.0.1", dst="10.222.0.2") /
5028 UDP(sport=1234, dport=1234) /
5029 Raw('\xa5' * 100))
5030
5031 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
5032
5033 #
5034 # cleanup
5035 #
5036 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
5037 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
5038 self.pg7.unconfig_ip4()
Neale Rannsb6a47952018-11-21 05:44:35 -08005039
Neale Rannsbc27d1b2018-02-05 01:13:38 -08005040
5041if __name__ == '__main__':
5042 unittest.main(testRunner=VppTestRunner)