blob: f6bded6bc901c879e0870b89fef7fa976c242c78 [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 Ranns6d1ba562019-07-10 01:14:58 -070038def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None,
39 tep=None, sclass=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070040 if ip:
41 vip = VppIpAddress(ip)
42 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010043 vmac = MACAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070044
45 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070046
Neale Rannsc0a93142018-09-05 15:42:26 -070047 for ep in eps:
Neale Ranns3eea9de2019-06-21 02:09:25 -070048 if tep:
49 src = VppIpAddress(tep[0])
50 dst = VppIpAddress(tep[1])
51 if src != ep.endpoint.tun.src or dst != ep.endpoint.tun.dst:
52 continue
Neale Ranns93cc3ee2018-10-10 07:22:51 -070053 if sw_if_index:
54 if ep.endpoint.sw_if_index != sw_if_index:
55 continue
Neale Ranns6d1ba562019-07-10 01:14:58 -070056 if sclass:
57 if ep.endpoint.sclass != sclass:
58 continue
Neale Ranns93cc3ee2018-10-10 07:22:51 -070059 if ip:
60 for eip in ep.endpoint.ips:
61 if vip == eip:
62 return True
63 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +010064 if vmac.packed == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070065 return True
Neale Ranns3eea9de2019-06-21 02:09:25 -070066
Neale Rannsc0a93142018-09-05 15:42:26 -070067 return False
68
69
Neale Ranns93cc3ee2018-10-10 07:22:51 -070070def find_gbp_vxlan(test, vni):
71 ts = test.vapi.gbp_vxlan_tunnel_dump()
72 for t in ts:
73 if t.tunnel.vni == vni:
74 return True
75 return False
76
77
Neale Rannsbc27d1b2018-02-05 01:13:38 -080078class VppGbpEndpoint(VppObject):
79 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020080 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080081 """
82
Neale Ranns25b04942018-04-04 09:34:50 -070083 @property
Neale Ranns93cc3ee2018-10-10 07:22:51 -070084 def mac(self):
Ole Troan8006c6a2018-12-17 12:02:26 +010085 return str(self.vmac)
Neale Ranns25b04942018-04-04 09:34:50 -070086
87 @property
Neale Rannsc0a93142018-09-05 15:42:26 -070088 def ip4(self):
89 return self._ip4
90
91 @property
92 def fip4(self):
93 return self._fip4
94
95 @property
96 def ip6(self):
97 return self._ip6
98
99 @property
100 def fip6(self):
101 return self._fip6
102
103 @property
104 def ips(self):
105 return [self.ip4, self.ip6]
106
107 @property
108 def fips(self):
109 return [self.fip4, self.fip6]
110
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700111 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
112 flags=0,
113 tun_src="0.0.0.0",
114 tun_dst="0.0.0.0",
115 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800116 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700117 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800118 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700119 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700120
121 self._ip4 = VppIpAddress(ip4)
122 self._fip4 = VppIpAddress(fip4)
123 self._ip6 = VppIpAddress(ip6)
124 self._fip6 = VppIpAddress(fip6)
125
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700126 if mac:
Ole Troan8006c6a2018-12-17 12:02:26 +0100127 self.vmac = MACAddress(self.itf.remote_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700128 else:
Ole Troan8006c6a2018-12-17 12:02:26 +0100129 self.vmac = MACAddress("00:00:00:00:00:00")
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700130
131 self.flags = flags
132 self.tun_src = VppIpAddress(tun_src)
133 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800134
135 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700136 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700137 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700138 [self.ip4.encode(), self.ip6.encode()],
Ole Troan8006c6a2018-12-17 12:02:26 +0100139 self.vmac.packed,
Neale Ranns4ba67722019-02-28 11:11:39 +0000140 self.epg.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700141 self.flags,
142 self.tun_src.encode(),
143 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700144 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800145 self._test.registry.register(self, self._test.logger)
146
147 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700148 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800149
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800150 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700151 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
152 self.itf.sw_if_index,
153 self.ip4.address,
Neale Ranns4ba67722019-02-28 11:11:39 +0000154 self.epg.sclass)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800155
156 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700157 return find_gbp_endpoint(self._test,
158 self.itf.sw_if_index,
159 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700160
161
162class VppGbpRecirc(VppObject):
163 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200164 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700165 """
166
167 def __init__(self, test, epg, recirc, is_ext=False):
168 self._test = test
169 self.recirc = recirc
170 self.epg = epg
171 self.is_ext = is_ext
172
173 def add_vpp_config(self):
174 self._test.vapi.gbp_recirc_add_del(
175 1,
176 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000177 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700178 self.is_ext)
179 self._test.registry.register(self, self._test.logger)
180
181 def remove_vpp_config(self):
182 self._test.vapi.gbp_recirc_add_del(
183 0,
184 self.recirc.sw_if_index,
Neale Ranns4ba67722019-02-28 11:11:39 +0000185 self.epg.sclass,
Neale Ranns25b04942018-04-04 09:34:50 -0700186 self.is_ext)
187
Neale Ranns25b04942018-04-04 09:34:50 -0700188 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700189 return "gbp-recirc:[%d]" % (self.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700190
191 def query_vpp_config(self):
192 rs = self._test.vapi.gbp_recirc_dump()
193 for r in rs:
194 if r.recirc.sw_if_index == self.recirc.sw_if_index:
195 return True
196 return False
197
198
Neale Rannsb6a47952018-11-21 05:44:35 -0800199class VppGbpExtItf(VppObject):
200 """
201 GBP ExtItfulation Interface
202 """
203
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200204 def __init__(self, test, itf, bd, rd, anon=False):
Neale Rannsb6a47952018-11-21 05:44:35 -0800205 self._test = test
206 self.itf = itf
207 self.bd = bd
208 self.rd = rd
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200209 self.flags = 1 if anon else 0
Neale Rannsb6a47952018-11-21 05:44:35 -0800210
211 def add_vpp_config(self):
212 self._test.vapi.gbp_ext_itf_add_del(
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200213 1, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
Neale Rannsb6a47952018-11-21 05:44:35 -0800214 self._test.registry.register(self, self._test.logger)
215
216 def remove_vpp_config(self):
217 self._test.vapi.gbp_ext_itf_add_del(
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200218 0, self.itf.sw_if_index, self.bd.bd_id, self.rd.rd_id, self.flags)
Neale Rannsb6a47952018-11-21 05:44:35 -0800219
Neale Rannsb6a47952018-11-21 05:44:35 -0800220 def object_id(self):
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200221 return "gbp-ext-itf:[%d]%s" % (self.itf.sw_if_index,
222 " [anon]" if self.flags else "")
Neale Rannsb6a47952018-11-21 05:44:35 -0800223
224 def query_vpp_config(self):
225 rs = self._test.vapi.gbp_ext_itf_dump()
226 for r in rs:
227 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
228 return True
229 return False
230
231
Neale Ranns25b04942018-04-04 09:34:50 -0700232class VppGbpSubnet(VppObject):
233 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200234 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700235 """
Filip Vargaf4749ca2019-04-25 14:55:32 +0200236
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700237 def __init__(self, test, rd, address, address_len,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700238 type, sw_if_index=None, sclass=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700239 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700240 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200241 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700242 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700243 self.sw_if_index = sw_if_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700244 self.sclass = sclass
Neale Ranns25b04942018-04-04 09:34:50 -0700245
246 def add_vpp_config(self):
247 self._test.vapi.gbp_subnet_add_del(
248 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700249 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200250 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700251 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700252 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700253 sclass=self.sclass if self.sclass else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700254 self._test.registry.register(self, self._test.logger)
255
256 def remove_vpp_config(self):
257 self._test.vapi.gbp_subnet_add_del(
258 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700259 self.rd_id,
260 self.prefix.encode(),
261 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700262
Neale Ranns25b04942018-04-04 09:34:50 -0700263 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700264 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700265
266 def query_vpp_config(self):
267 ss = self._test.vapi.gbp_subnet_dump()
268 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700269 if s.subnet.rd_id == self.rd_id and \
Filip Vargaf4749ca2019-04-25 14:55:32 +0200270 s.subnet.type == self.type and \
271 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700272 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700273 return False
274
275
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800276class VppGbpEndpointRetention(object):
277 def __init__(self, remote_ep_timeout=0xffffffff):
278 self.remote_ep_timeout = remote_ep_timeout
279
280 def encode(self):
281 return {'remote_ep_timeout': self.remote_ep_timeout}
282
283
Neale Ranns25b04942018-04-04 09:34:50 -0700284class VppGbpEndpointGroup(VppObject):
285 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200286 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700287 """
288
Neale Ranns4ba67722019-02-28 11:11:39 +0000289 def __init__(self, test, vnid, sclass, rd, bd, uplink,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800290 bvi, bvi_ip4, bvi_ip6=None,
291 retention=VppGbpEndpointRetention()):
Neale Ranns25b04942018-04-04 09:34:50 -0700292 self._test = test
293 self.uplink = uplink
294 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700295 self.bvi_ip4 = VppIpAddress(bvi_ip4)
296 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns4ba67722019-02-28 11:11:39 +0000297 self.vnid = vnid
Neale Ranns25b04942018-04-04 09:34:50 -0700298 self.bd = bd
299 self.rd = rd
Neale Ranns879d11c2019-01-21 23:34:18 -0800300 self.sclass = sclass
301 if 0 == self.sclass:
302 self.sclass = 0xffff
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800303 self.retention = retention
Neale Ranns25b04942018-04-04 09:34:50 -0700304
305 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700306 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns4ba67722019-02-28 11:11:39 +0000307 self.vnid,
Neale Ranns879d11c2019-01-21 23:34:18 -0800308 self.sclass,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700309 self.bd.bd.bd_id,
310 self.rd.rd_id,
Neale Ranns32f6d8e2019-03-05 04:22:08 -0800311 self.uplink.sw_if_index if self.uplink else INDEX_INVALID,
312 self.retention.encode())
Neale Ranns25b04942018-04-04 09:34:50 -0700313 self._test.registry.register(self, self._test.logger)
314
315 def remove_vpp_config(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000316 self._test.vapi.gbp_endpoint_group_del(self.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -0700317
Neale Ranns25b04942018-04-04 09:34:50 -0700318 def object_id(self):
Neale Ranns4ba67722019-02-28 11:11:39 +0000319 return "gbp-endpoint-group:[%d]" % (self.vnid)
Neale Ranns25b04942018-04-04 09:34:50 -0700320
321 def query_vpp_config(self):
322 epgs = self._test.vapi.gbp_endpoint_group_dump()
323 for epg in epgs:
Neale Ranns4ba67722019-02-28 11:11:39 +0000324 if epg.epg.vnid == self.vnid:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800325 return True
326 return False
327
328
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700329class VppGbpBridgeDomain(VppObject):
330 """
331 GBP Bridge Domain
332 """
333
Neale Ranns160c9232019-06-19 06:25:56 -0700334 def __init__(self, test, bd, rd, bvi, uu_fwd=None,
Neale Ranns69a85b52019-06-14 07:49:50 +0000335 bm_flood=None, learn=True,
336 uu_drop=False, bm_drop=False,
337 ucast_arp=False):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700338 self._test = test
339 self.bvi = bvi
Neale Ranns879d11c2019-01-21 23:34:18 -0800340 self.uu_fwd = uu_fwd
341 self.bm_flood = bm_flood
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700342 self.bd = bd
Neale Ranns160c9232019-06-19 06:25:56 -0700343 self.rd = rd
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700344
Neale Rannsc29c0af2018-11-07 04:21:12 -0800345 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
Neale Ranns69a85b52019-06-14 07:49:50 +0000346
347 self.flags = e.GBP_BD_API_FLAG_NONE
348 if not learn:
349 self.flags |= e.GBP_BD_API_FLAG_DO_NOT_LEARN
350 if uu_drop:
351 self.flags |= e.GBP_BD_API_FLAG_UU_FWD_DROP
352 if bm_drop:
353 self.flags |= e.GBP_BD_API_FLAG_MCAST_DROP
354 if ucast_arp:
355 self.flags |= e.GBP_BD_API_FLAG_UCAST_ARP
Neale Rannsc29c0af2018-11-07 04:21:12 -0800356
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700357 def add_vpp_config(self):
358 self._test.vapi.gbp_bridge_domain_add(
359 self.bd.bd_id,
Neale Ranns160c9232019-06-19 06:25:56 -0700360 self.rd.rd_id,
Neale Ranns69a85b52019-06-14 07:49:50 +0000361 self.flags,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700362 self.bvi.sw_if_index,
Neale Ranns879d11c2019-01-21 23:34:18 -0800363 self.uu_fwd.sw_if_index if self.uu_fwd else INDEX_INVALID,
364 self.bm_flood.sw_if_index if self.bm_flood else INDEX_INVALID)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700365 self._test.registry.register(self, self._test.logger)
366
367 def remove_vpp_config(self):
368 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
369
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700370 def object_id(self):
371 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
372
373 def query_vpp_config(self):
374 bds = self._test.vapi.gbp_bridge_domain_dump()
375 for bd in bds:
376 if bd.bd.bd_id == self.bd.bd_id:
377 return True
378 return False
379
380
381class VppGbpRouteDomain(VppObject):
382 """
383 GBP Route Domain
384 """
385
Neale Ranns160c9232019-06-19 06:25:56 -0700386 def __init__(self, test, rd_id, scope, t4, t6, ip4_uu=None, ip6_uu=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700387 self._test = test
388 self.rd_id = rd_id
Neale Ranns160c9232019-06-19 06:25:56 -0700389 self.scope = scope
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700390 self.t4 = t4
391 self.t6 = t6
392 self.ip4_uu = ip4_uu
393 self.ip6_uu = ip6_uu
394
395 def add_vpp_config(self):
396 self._test.vapi.gbp_route_domain_add(
397 self.rd_id,
Neale Ranns160c9232019-06-19 06:25:56 -0700398 self.scope,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700399 self.t4.table_id,
400 self.t6.table_id,
401 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
402 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
403 self._test.registry.register(self, self._test.logger)
404
405 def remove_vpp_config(self):
406 self._test.vapi.gbp_route_domain_del(self.rd_id)
407
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700408 def object_id(self):
409 return "gbp-route-domain:[%d]" % (self.rd_id)
410
411 def query_vpp_config(self):
412 rds = self._test.vapi.gbp_route_domain_dump()
413 for rd in rds:
414 if rd.rd.rd_id == self.rd_id:
415 return True
416 return False
417
418
Neale Ranns13a08cc2018-11-07 09:25:54 -0800419class VppGbpContractNextHop():
420 def __init__(self, mac, bd, ip, rd):
421 self.mac = mac
422 self.ip = ip
423 self.bd = bd
424 self.rd = rd
425
426 def encode(self):
427 return {'ip': self.ip.encode(),
Ole Troan8006c6a2018-12-17 12:02:26 +0100428 'mac': self.mac.packed,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800429 'bd_id': self.bd.bd.bd_id,
430 'rd_id': self.rd.rd_id}
431
432
433class VppGbpContractRule():
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400434 def __init__(self, action, hash_mode, nhs=None):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800435 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100436 self.hash_mode = hash_mode
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400437 self.nhs = [] if nhs is None else nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800438
439 def encode(self):
440 nhs = []
441 for nh in self.nhs:
442 nhs.append(nh.encode())
443 while len(nhs) < 8:
444 nhs.append({})
445 return {'action': self.action,
446 'nh_set': {
447 'hash_mode': self.hash_mode,
448 'n_nhs': len(self.nhs),
449 'nhs': nhs}}
450
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400451 def __repr__(self):
452 return '<VppGbpContractRule action=%s, hash_mode=%s>' % (
453 self.action, self.hash_mode)
454
Neale Ranns13a08cc2018-11-07 09:25:54 -0800455
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800456class VppGbpContract(VppObject):
457 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200458 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800459 """
460
Neale Ranns160c9232019-06-19 06:25:56 -0700461 def __init__(self, test, scope, sclass, dclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800462 rules, allowed_ethertypes):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800463 self._test = test
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400464 if not isinstance(rules, list):
465 raise ValueError("'rules' must be a list.")
466 if not isinstance(allowed_ethertypes, list):
467 raise ValueError("'allowed_ethertypes' must be a list.")
Neale Ranns160c9232019-06-19 06:25:56 -0700468 self.scope = scope
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800469 self.acl_index = acl_index
Neale Ranns4dd4cf42019-03-27 05:06:47 -0700470 self.sclass = sclass
471 self.dclass = dclass
Neale Ranns13a08cc2018-11-07 09:25:54 -0800472 self.rules = rules
Neale Ranns1c17e2e2018-12-20 12:03:59 -0800473 self.allowed_ethertypes = allowed_ethertypes
Neale Rannsfa0ac2c2019-03-12 04:34:53 -0700474 while (len(self.allowed_ethertypes) < 16):
475 self.allowed_ethertypes.append(0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800476
477 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800478 rules = []
479 for r in self.rules:
480 rules.append(r.encode())
Neale Ranns796c84b2019-03-28 07:56:23 -0700481 r = self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400482 is_add=1,
483 contract={
484 'acl_index': self.acl_index,
Neale Ranns160c9232019-06-19 06:25:56 -0700485 'scope': self.scope,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400486 'sclass': self.sclass,
487 'dclass': self.dclass,
488 'n_rules': len(rules),
489 'rules': rules,
490 'n_ether_types': len(self.allowed_ethertypes),
491 'allowed_ethertypes': self.allowed_ethertypes})
Neale Ranns796c84b2019-03-28 07:56:23 -0700492 self.stats_index = r.stats_index
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800493 self._test.registry.register(self, self._test.logger)
494
495 def remove_vpp_config(self):
496 self._test.vapi.gbp_contract_add_del(
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400497 is_add=0,
498 contract={
499 'acl_index': self.acl_index,
Neale Ranns160c9232019-06-19 06:25:56 -0700500 'scope': self.scope,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400501 'sclass': self.sclass,
502 'dclass': self.dclass,
503 'n_rules': 0,
504 'rules': [],
505 'n_ether_types': len(self.allowed_ethertypes),
Neale Ranns160c9232019-06-19 06:25:56 -0700506 'allowed_ethertypes': self.allowed_ethertypes})
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800507
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800508 def object_id(self):
Neale Ranns160c9232019-06-19 06:25:56 -0700509 return "gbp-contract:[%d:%d:%d:%d]" % (self.scope,
510 self.sclass,
511 self.dclass,
512 self.acl_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800513
514 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700515 cs = self._test.vapi.gbp_contract_dump()
516 for c in cs:
Neale Ranns160c9232019-06-19 06:25:56 -0700517 if c.contract.scope == self.scope \
518 and c.contract.sclass == self.sclass \
519 and c.contract.dclass == self.dclass:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800520 return True
521 return False
522
Neale Ranns796c84b2019-03-28 07:56:23 -0700523 def get_drop_stats(self):
524 c = self._test.statistics.get_counter("/net/gbp/contract/drop")
525 return c[0][self.stats_index]
526
527 def get_permit_stats(self):
528 c = self._test.statistics.get_counter("/net/gbp/contract/permit")
529 return c[0][self.stats_index]
530
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800531
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700532class VppGbpVxlanTunnel(VppInterface):
533 """
534 GBP VXLAN tunnel
535 """
536
Neale Ranns8da9fc62019-03-04 14:08:11 -0800537 def __init__(self, test, vni, bd_rd_id, mode, src):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700538 super(VppGbpVxlanTunnel, self).__init__(test)
539 self._test = test
540 self.vni = vni
541 self.bd_rd_id = bd_rd_id
542 self.mode = mode
Neale Ranns8da9fc62019-03-04 14:08:11 -0800543 self.src = src
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700544
545 def add_vpp_config(self):
546 r = self._test.vapi.gbp_vxlan_tunnel_add(
547 self.vni,
548 self.bd_rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -0800549 self.mode,
550 self.src)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700551 self.set_sw_if_index(r.sw_if_index)
552 self._test.registry.register(self, self._test.logger)
553
554 def remove_vpp_config(self):
555 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
556
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700557 def object_id(self):
Neale Ranns8da9fc62019-03-04 14:08:11 -0800558 return "gbp-vxlan:%d" % (self.sw_if_index)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700559
560 def query_vpp_config(self):
561 return find_gbp_vxlan(self._test, self.vni)
562
563
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200564class VppGbpAcl(VppObject):
565 """
566 GBP Acl
567 """
568
569 def __init__(self, test):
570 self._test = test
571 self.acl_index = 4294967295
572
573 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800574 s_prefix=0, s_ip=b'\x00\x00\x00\x00', sport_from=0,
575 sport_to=65535, d_prefix=0, d_ip=b'\x00\x00\x00\x00',
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200576 dport_from=0, dport_to=65535):
577 if proto == -1 or proto == 0:
578 sport_to = 0
579 dport_to = sport_to
580 elif proto == 1 or proto == 58:
581 sport_to = 255
582 dport_to = sport_to
583 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
584 'srcport_or_icmptype_first': sport_from,
585 'srcport_or_icmptype_last': sport_to,
586 'src_ip_prefix_len': s_prefix,
587 'src_ip_addr': s_ip,
588 'dstport_or_icmpcode_first': dport_from,
589 'dstport_or_icmpcode_last': dport_to,
590 'dst_ip_prefix_len': d_prefix,
591 'dst_ip_addr': d_ip})
592 return rule
593
594 def add_vpp_config(self, rules):
595
Paul Vinciguerra1b534f52019-06-15 20:31:31 -0400596 reply = self._test.vapi.acl_add_replace(acl_index=self.acl_index,
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200597 r=rules,
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800598 tag=b'GBPTest')
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200599 self.acl_index = reply.acl_index
600 return self.acl_index
601
602 def remove_vpp_config(self):
603 self._test.vapi.acl_del(self.acl_index)
604
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200605 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700606 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200607
608 def query_vpp_config(self):
609 cs = self._test.vapi.acl_dump()
610 for c in cs:
611 if c.acl_index == self.acl_index:
612 return True
613 return False
614
615
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800616class TestGBP(VppTestCase):
617 """ GBP Test Case """
618
Filip Vargadd1e3e72019-04-15 18:52:43 +0200619 @property
620 def config_flags(self):
621 return VppEnum.vl_api_nat_config_flags_t
622
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700623 @classmethod
624 def setUpClass(cls):
625 super(TestGBP, cls).setUpClass()
626
627 @classmethod
628 def tearDownClass(cls):
629 super(TestGBP, cls).tearDownClass()
630
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800631 def setUp(self):
632 super(TestGBP, self).setUp()
633
Neale Ranns25b04942018-04-04 09:34:50 -0700634 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700635 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700636
Ole Troan8006c6a2018-12-17 12:02:26 +0100637 self.router_mac = MACAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800638
639 for i in self.pg_interfaces:
640 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700641 for i in self.lo_interfaces:
642 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800643
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200644 self.vlan_100 = VppDot1QSubint(self, self.pg0, 100)
645 self.vlan_100.admin_up()
646 self.vlan_101 = VppDot1QSubint(self, self.pg0, 101)
647 self.vlan_101.admin_up()
648 self.vlan_102 = VppDot1QSubint(self, self.pg0, 102)
649 self.vlan_102.admin_up()
650
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800651 def tearDown(self):
652 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700653 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800654 super(TestGBP, self).tearDown()
Benoît Ganneba6abfa2019-07-01 17:10:41 +0200655 self.vlan_102.remove_vpp_config()
656 self.vlan_101.remove_vpp_config()
657 self.vlan_100.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800658
Neale Ranns25b04942018-04-04 09:34:50 -0700659 def send_and_expect_bridged(self, src, tx, dst):
660 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800661
Neale Ranns25b04942018-04-04 09:34:50 -0700662 for r in rx:
663 self.assertEqual(r[Ether].src, tx[0][Ether].src)
664 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
665 self.assertEqual(r[IP].src, tx[0][IP].src)
666 self.assertEqual(r[IP].dst, tx[0][IP].dst)
667 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800668
Neale Ranns25b04942018-04-04 09:34:50 -0700669 def send_and_expect_bridged6(self, src, tx, dst):
670 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800671
Neale Ranns25b04942018-04-04 09:34:50 -0700672 for r in rx:
673 self.assertEqual(r[Ether].src, tx[0][Ether].src)
674 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
675 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
676 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
677 return rx
678
679 def send_and_expect_routed(self, src, tx, dst, src_mac):
680 rx = self.send_and_expect(src, tx, dst)
681
682 for r in rx:
683 self.assertEqual(r[Ether].src, src_mac)
684 self.assertEqual(r[Ether].dst, dst.remote_mac)
685 self.assertEqual(r[IP].src, tx[0][IP].src)
686 self.assertEqual(r[IP].dst, tx[0][IP].dst)
687 return rx
688
Neale Ranns69a85b52019-06-14 07:49:50 +0000689 def send_and_expect_routed6(self, src, tx, dst, src_mac):
690 rx = self.send_and_expect(src, tx, dst)
691
692 for r in rx:
693 self.assertEqual(r[Ether].src, src_mac)
694 self.assertEqual(r[Ether].dst, dst.remote_mac)
695 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
696 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
697 return rx
698
Neale Ranns25b04942018-04-04 09:34:50 -0700699 def send_and_expect_natted(self, src, tx, dst, src_ip):
700 rx = self.send_and_expect(src, tx, dst)
701
702 for r in rx:
703 self.assertEqual(r[Ether].src, tx[0][Ether].src)
704 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
705 self.assertEqual(r[IP].src, src_ip)
706 self.assertEqual(r[IP].dst, tx[0][IP].dst)
707 return rx
708
Neale Ranns4a6d0232018-04-24 07:45:33 -0700709 def send_and_expect_natted6(self, src, tx, dst, src_ip):
710 rx = self.send_and_expect(src, tx, dst)
711
712 for r in rx:
713 self.assertEqual(r[Ether].src, tx[0][Ether].src)
714 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
715 self.assertEqual(r[IPv6].src, src_ip)
716 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
717 return rx
718
Neale Ranns25b04942018-04-04 09:34:50 -0700719 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
720 rx = self.send_and_expect(src, tx, dst)
721
722 for r in rx:
723 self.assertEqual(r[Ether].src, tx[0][Ether].src)
724 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
725 self.assertEqual(r[IP].dst, dst_ip)
726 self.assertEqual(r[IP].src, tx[0][IP].src)
727 return rx
728
Neale Ranns4a6d0232018-04-24 07:45:33 -0700729 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
730 rx = self.send_and_expect(src, tx, dst)
731
732 for r in rx:
733 self.assertEqual(r[Ether].src, tx[0][Ether].src)
734 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
735 self.assertEqual(r[IPv6].dst, dst_ip)
736 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
737 return rx
738
Neale Ranns25b04942018-04-04 09:34:50 -0700739 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
740 rx = self.send_and_expect(src, tx, dst)
741
742 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100743 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -0700744 self.assertEqual(r[Ether].dst, dst.remote_mac)
745 self.assertEqual(r[IP].dst, dst_ip)
746 self.assertEqual(r[IP].src, src_ip)
747 return rx
748
Neale Ranns4a6d0232018-04-24 07:45:33 -0700749 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
750 rx = self.send_and_expect(src, tx, dst)
751
752 for r in rx:
Ole Troan8006c6a2018-12-17 12:02:26 +0100753 self.assertEqual(r[Ether].src, str(self.router_mac))
Neale Ranns4a6d0232018-04-24 07:45:33 -0700754 self.assertEqual(r[Ether].dst, dst.remote_mac)
755 self.assertEqual(r[IPv6].dst, dst_ip)
756 self.assertEqual(r[IPv6].src, src_ip)
757 return rx
758
Mohsin Kazmife52dea2019-04-18 15:54:58 +0200759 def send_and_expect_no_arp(self, src, tx, dst):
760 self.pg_send(src, tx)
761 dst.get_capture(0, timeout=1)
762 dst.assert_nothing_captured(remark="")
763 timeout = 0.1
764
765 def send_and_expect_arp(self, src, tx, dst):
766 rx = self.send_and_expect(src, tx, dst)
767
768 for r in rx:
769 self.assertEqual(r[Ether].src, tx[0][Ether].src)
770 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
771 self.assertEqual(r[ARP].psrc, tx[0][ARP].psrc)
772 self.assertEqual(r[ARP].pdst, tx[0][ARP].pdst)
773 self.assertEqual(r[ARP].hwsrc, tx[0][ARP].hwsrc)
774 self.assertEqual(r[ARP].hwdst, tx[0][ARP].hwdst)
775 return rx
776
Neale Ranns25b04942018-04-04 09:34:50 -0700777 def test_gbp(self):
778 """ Group Based Policy """
779
Neale Rannsb6a47952018-11-21 05:44:35 -0800780 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
781
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800782 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700783 # Route Domains
784 #
785 gt4 = VppIpTable(self, 0)
786 gt4.add_vpp_config()
787 gt6 = VppIpTable(self, 0, is_ip6=True)
788 gt6.add_vpp_config()
789 nt4 = VppIpTable(self, 20)
790 nt4.add_vpp_config()
791 nt6 = VppIpTable(self, 20, is_ip6=True)
792 nt6.add_vpp_config()
793
Neale Ranns160c9232019-06-19 06:25:56 -0700794 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
795 rd20 = VppGbpRouteDomain(self, 20, 420, nt4, nt6, None, None)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700796
797 rd0.add_vpp_config()
798 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700799
800 #
Neale Ranns160c9232019-06-19 06:25:56 -0700801 # Bridge Domains
802 #
803 bd1 = VppBridgeDomain(self, 1)
804 bd2 = VppBridgeDomain(self, 2)
805 bd20 = VppBridgeDomain(self, 20)
806
807 bd1.add_vpp_config()
808 bd2.add_vpp_config()
809 bd20.add_vpp_config()
810
811 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
812 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
813 gbd20 = VppGbpBridgeDomain(self, bd20, rd20, self.loop2)
814
815 gbd1.add_vpp_config()
816 gbd2.add_vpp_config()
817 gbd20.add_vpp_config()
818
819 #
Neale Ranns25b04942018-04-04 09:34:50 -0700820 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700821 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
822 #
Neale Ranns4ba67722019-02-28 11:11:39 +0000823 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
824 self.pg4, self.loop0,
825 "10.0.0.128", "2001:10::128"),
826 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
827 self.pg5, self.loop0,
828 "10.0.1.128", "2001:10:1::128"),
829 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
830 self.pg6, self.loop1,
831 "10.0.2.128", "2001:10:2::128"),
832 VppGbpEndpointGroup(self, 333, 1333, rd20, gbd20,
833 self.pg7, self.loop2,
834 "11.0.0.128", "3001::128"),
835 VppGbpEndpointGroup(self, 444, 1444, rd20, gbd20,
836 self.pg8, self.loop2,
837 "11.0.0.129", "3001::129")]
838 recircs = [VppGbpRecirc(self, epgs[0], self.loop3),
839 VppGbpRecirc(self, epgs[1], self.loop4),
840 VppGbpRecirc(self, epgs[2], self.loop5),
841 VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True),
842 VppGbpRecirc(self, epgs[4], self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700843
844 epg_nat = epgs[3]
845 recirc_nat = recircs[3]
846
847 #
848 # 4 end-points, 2 in the same subnet, 3 in the same BD
849 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700850 eps = [VppGbpEndpoint(self, self.pg0,
851 epgs[0], recircs[0],
852 "10.0.0.1", "11.0.0.1",
853 "2001:10::1", "3001::1"),
854 VppGbpEndpoint(self, self.pg1,
855 epgs[0], recircs[0],
856 "10.0.0.2", "11.0.0.2",
857 "2001:10::2", "3001::2"),
858 VppGbpEndpoint(self, self.pg2,
859 epgs[1], recircs[1],
860 "10.0.1.1", "11.0.0.3",
861 "2001:10:1::1", "3001::3"),
862 VppGbpEndpoint(self, self.pg3,
863 epgs[2], recircs[2],
864 "10.0.2.1", "11.0.0.4",
865 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700866
867 #
868 # Config related to each of the EPGs
869 #
870 for epg in epgs:
871 # IP config on the BVI interfaces
872 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700873 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
874 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
875 self.vapi.sw_interface_set_mac_address(
876 epg.bvi.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +0100877 self.router_mac.packed)
Neale Ranns25b04942018-04-04 09:34:50 -0700878
879 # The BVIs are NAT inside interfaces
Filip Vargadd1e3e72019-04-15 18:52:43 +0200880 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +0200881 self.vapi.nat44_interface_add_del_feature(
882 sw_if_index=epg.bvi.sw_if_index,
883 flags=flags, is_add=1)
884 self.vapi.nat66_add_del_interface(
885 is_add=1, flags=flags,
886 sw_if_index=epg.bvi.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700887
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700888 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
889 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
890 if_ip4.add_vpp_config()
891 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700892
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700893 # EPG uplink interfaces in the RD
894 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
895 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700896
897 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700898 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100899 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -0700900 epg.bvi_ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700901 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
Ole Troan8006c6a2018-12-17 12:02:26 +0100902 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -0700903 epg.bvi_ip6.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700904 epg.bd_arp_ip4.add_vpp_config()
905 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700906
907 # EPG in VPP
908 epg.add_vpp_config()
909
910 for recirc in recircs:
911 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700912 VppIpInterfaceBind(self, recirc.recirc,
913 recirc.epg.rd.t4).add_vpp_config()
914 VppIpInterfaceBind(self, recirc.recirc,
915 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700916
Neale Ranns4a6d0232018-04-24 07:45:33 -0700917 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200918 sw_if_index=recirc.recirc.sw_if_index, is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700919 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +0200920 is_add=1,
921 sw_if_index=recirc.recirc.sw_if_index)
Neale Ranns25b04942018-04-04 09:34:50 -0700922
923 recirc.add_vpp_config()
924
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700925 for recirc in recircs:
926 self.assertTrue(find_bridge_domain_port(self,
927 recirc.epg.bd.bd.bd_id,
928 recirc.recirc.sw_if_index))
929
Neale Ranns25b04942018-04-04 09:34:50 -0700930 for ep in eps:
931 self.pg_enable_capture(self.pg_interfaces)
932 self.pg_start()
933 #
934 # routes to the endpoints. We need these since there are no
935 # adj-fibs due to the fact the the BVI address has /32 and
936 # the subnet is not attached.
937 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700938 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700939 # Add static mappings for each EP from the 10/8 to 11/8 network
940 if ip.af == AF_INET:
Filip Vargadd1e3e72019-04-15 18:52:43 +0200941 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +0200942 self.vapi.nat44_add_del_static_mapping(
943 is_add=1,
944 local_ip_address=ip.bytes,
945 external_ip_address=fip.bytes,
946 external_sw_if_index=0xFFFFFFFF,
947 vrf_id=0,
948 flags=flags)
Neale Rannsc0a93142018-09-05 15:42:26 -0700949 else:
Filip Vargaf4749ca2019-04-25 14:55:32 +0200950 self.vapi.nat66_add_del_static_mapping(
951 local_ip_address=ip.bytes,
952 external_ip_address=fip.bytes,
953 vrf_id=0, is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700954
Neale Ranns25b04942018-04-04 09:34:50 -0700955 # VPP EP create ...
956 ep.add_vpp_config()
957
Neale Rannsc0a93142018-09-05 15:42:26 -0700958 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700959
Neale Rannsc0a93142018-09-05 15:42:26 -0700960 # ... results in a Gratuitous ARP/ND on the EPG's uplink
961 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
962
963 for ii, ip in enumerate(ep.ips):
964 p = rx[ii]
965
966 if ip.is_ip6:
967 self.assertTrue(p.haslayer(ICMPv6ND_NA))
968 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
969 else:
970 self.assertTrue(p.haslayer(ARP))
971 self.assertEqual(p[ARP].psrc, ip.address)
972 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700973
974 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700975 for fip in ep.fips:
Neale Rannsbc764c82019-06-19 07:07:13 -0700976 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac,
977 fip.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700978 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700979
Neale Rannsc0a93142018-09-05 15:42:26 -0700980 # floating IPs route via EPG recirc
Neale Ranns097fa662018-05-01 05:17:55 -0700981 r = VppIpRoute(
982 self, fip.address, fip.length,
983 [VppRoutePath(fip.address,
984 ep.recirc.recirc.sw_if_index,
985 type=FibPathType.FIB_PATH_TYPE_DVR,
986 proto=fip.dpo_proto)],
987 table_id=20)
Neale Rannsc0a93142018-09-05 15:42:26 -0700988 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700989
990 # L2 FIB entries in the NAT EPG BD to bridge the packets from
991 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700992 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
993 ep.recirc.recirc, bvi_mac=0)
994 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700995
996 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700997 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700998 #
999 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
1000 src=self.pg0.remote_mac) /
1001 ARP(op="who-has",
1002 hwdst="ff:ff:ff:ff:ff:ff",
1003 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001004 pdst="10.0.0.88",
1005 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -07001006
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001007 self.vapi.cli("clear trace")
1008 self.pg0.add_stream(pkt_arp)
1009
1010 self.pg_enable_capture(self.pg_interfaces)
1011 self.pg_start()
1012
1013 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -07001014
1015 #
1016 # ARP/ND packets get a response
1017 #
1018 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
1019 src=self.pg0.remote_mac) /
1020 ARP(op="who-has",
1021 hwdst="ff:ff:ff:ff:ff:ff",
1022 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001023 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -07001024 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -07001025
1026 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
1027
Neale Rannsc0a93142018-09-05 15:42:26 -07001028 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -07001029 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001030 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
1031 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001032 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -07001033 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001034 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
1035 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
1036
1037 #
1038 # broadcast packets are flooded
1039 #
1040 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
1041 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001042 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001043 UDP(sport=1234, dport=1234) /
1044 Raw('\xa5' * 100))
1045
1046 self.vapi.cli("clear trace")
1047 self.pg0.add_stream(pkt_bcast)
1048
1049 self.pg_enable_capture(self.pg_interfaces)
1050 self.pg_start()
1051
1052 rxd = eps[1].itf.get_capture(1)
1053 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1054 rxd = epgs[0].uplink.get_capture(1)
1055 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
1056
1057 #
1058 # packets to non-local L3 destinations dropped
1059 #
1060 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001061 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001062 IP(src=eps[0].ip4.address,
1063 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001064 UDP(sport=1234, dport=1234) /
1065 Raw('\xa5' * 100))
1066 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001067 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001068 IP(src=eps[0].ip4.address,
1069 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001070 UDP(sport=1234, dport=1234) /
1071 Raw('\xa5' * 100))
1072
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001073 self.send_and_assert_no_replies(self.pg0,
1074 pkt_intra_epg_220_ip4 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001075
1076 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001077 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001078 IPv6(src=eps[0].ip6.address,
1079 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001080 UDP(sport=1234, dport=1234) /
1081 Raw('\xa5' * 100))
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001082 self.send_and_assert_no_replies(self.pg0,
1083 pkt_inter_epg_222_ip6 * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001084
1085 #
1086 # Add the subnet routes
1087 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001088 s41 = VppGbpSubnet(
1089 self, rd0, "10.0.0.0", 24,
1090 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1091 s42 = VppGbpSubnet(
1092 self, rd0, "10.0.1.0", 24,
1093 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1094 s43 = VppGbpSubnet(
1095 self, rd0, "10.0.2.0", 24,
1096 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1097 s61 = VppGbpSubnet(
1098 self, rd0, "2001:10::1", 64,
1099 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1100 s62 = VppGbpSubnet(
1101 self, rd0, "2001:10:1::1", 64,
1102 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1103 s63 = VppGbpSubnet(
1104 self, rd0, "2001:10:2::1", 64,
1105 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001106 s41.add_vpp_config()
1107 s42.add_vpp_config()
1108 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001109 s61.add_vpp_config()
1110 s62.add_vpp_config()
1111 s63.add_vpp_config()
1112
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001113 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001114 pkt_intra_epg_220_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001115 eps[0].epg.uplink)
1116 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001117 pkt_inter_epg_222_ip4 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001118 eps[0].epg.uplink)
1119 self.send_and_expect_bridged6(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001120 pkt_inter_epg_222_ip6 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001121 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001122
1123 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1124 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1125 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1126 self.logger.info(self.vapi.cli("sh gbp recirc"))
1127 self.logger.info(self.vapi.cli("sh int"))
1128 self.logger.info(self.vapi.cli("sh int addr"))
1129 self.logger.info(self.vapi.cli("sh int feat loop6"))
1130 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1131 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001132 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001133
1134 #
1135 # Packet destined to unknown unicast is sent on the epg uplink ...
1136 #
1137 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1138 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001139 IP(src=eps[0].ip4.address,
1140 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001141 UDP(sport=1234, dport=1234) /
1142 Raw('\xa5' * 100))
1143
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001144 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001145 pkt_intra_epg_220_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001146 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001147 # ... and nowhere else
1148 self.pg1.get_capture(0, timeout=0.1)
1149 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1150
1151 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1152 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001153 IP(src=eps[0].ip4.address,
1154 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001155 UDP(sport=1234, dport=1234) /
1156 Raw('\xa5' * 100))
1157
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001158 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001159 pkt_intra_epg_221_to_uplink * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001160 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001161
1162 #
1163 # Packets from the uplink are forwarded in the absence of a contract
1164 #
1165 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1166 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001167 IP(src=eps[0].ip4.address,
1168 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001169 UDP(sport=1234, dport=1234) /
1170 Raw('\xa5' * 100))
1171
1172 self.send_and_expect_bridged(self.pg4,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001173 pkt_intra_epg_220_from_uplink * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001174 self.pg0)
1175
1176 #
1177 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001178 # can communicate
1179 #
1180 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001181 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001182 IP(src=eps[0].ip4.address,
1183 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001184 UDP(sport=1234, dport=1234) /
1185 Raw('\xa5' * 100))
1186
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001187 self.send_and_expect_bridged(self.pg0,
1188 pkt_intra_epg * NUM_PKTS,
1189 self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001190
1191 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001192 # in the absence of policy, endpoints in the different EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001193 # cannot communicate
1194 #
1195 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001196 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001197 IP(src=eps[0].ip4.address,
1198 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001199 UDP(sport=1234, dport=1234) /
1200 Raw('\xa5' * 100))
1201 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001202 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001203 IP(src=eps[2].ip4.address,
1204 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001205 UDP(sport=1234, dport=1234) /
1206 Raw('\xa5' * 100))
1207 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001208 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001209 IP(src=eps[0].ip4.address,
1210 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001211 UDP(sport=1234, dport=1234) /
1212 Raw('\xa5' * 100))
1213
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001214 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001215 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001216 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001217 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001218
1219 #
1220 # A uni-directional contract from EPG 220 -> 221
1221 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001222 acl = VppGbpAcl(self)
1223 rule = acl.create_rule(permit_deny=1, proto=17)
1224 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1225 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001226 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001227 self, 400, epgs[0].sclass, epgs[1].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001228 [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,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001231 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001232 VppGbpContractRule(
1233 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001234 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001235 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001236 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001237 c1.add_vpp_config()
1238
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001239 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001240 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001241 eps[2].itf)
1242 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001243 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001244
1245 #
1246 # contract for the return direction
1247 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001248 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001249 self, 400, epgs[1].sclass, epgs[0].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001250 [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,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001253 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001254 VppGbpContractRule(
1255 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001256 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001257 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001258 [ETH_P_IP, ETH_P_IPV6])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001259 c2.add_vpp_config()
1260
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001261 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001262 pkt_inter_epg_220_to_221 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001263 eps[2].itf)
1264 self.send_and_expect_bridged(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001265 pkt_inter_epg_221_to_220 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001266 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001267
Neale Ranns796c84b2019-03-28 07:56:23 -07001268 ds = c2.get_drop_stats()
1269 self.assertEqual(ds['packets'], 0)
1270 ps = c2.get_permit_stats()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001271 self.assertEqual(ps['packets'], NUM_PKTS)
Neale Ranns796c84b2019-03-28 07:56:23 -07001272
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001273 #
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001274 # the contract does not allow non-IP
1275 #
1276 pkt_non_ip_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
1277 dst=self.pg2.remote_mac) /
1278 ARP())
1279 self.send_and_assert_no_replies(eps[0].itf,
1280 pkt_non_ip_inter_epg_220_to_221 * 17)
1281
1282 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001283 # check that inter group is still disabled for the groups
1284 # not in the contract.
1285 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001286 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001287 pkt_inter_epg_220_to_222 * NUM_PKTS)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001288
Neale Ranns25b04942018-04-04 09:34:50 -07001289 #
1290 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1291 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001292 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001293 self, 400, epgs[0].sclass, epgs[2].sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001294 [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,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001297 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001298 VppGbpContractRule(
1299 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001300 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001301 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001302 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001303 c3.add_vpp_config()
1304
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001305 self.logger.info(self.vapi.cli("sh gbp contract"))
1306
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001307 self.send_and_expect_routed(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001308 pkt_inter_epg_220_to_222 * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001309 eps[3].itf,
Ole Troan8006c6a2018-12-17 12:02:26 +01001310 str(self.router_mac))
Neale Ranns25b04942018-04-04 09:34:50 -07001311
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001312 #
1313 # remove both contracts, traffic stops in both directions
1314 #
1315 c2.remove_vpp_config()
1316 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001317 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001318 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001319
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001320 self.send_and_assert_no_replies(eps[2].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001321 pkt_inter_epg_221_to_220 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001322 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001323 pkt_inter_epg_220_to_221 * NUM_PKTS)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001324 self.send_and_expect_bridged(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001325 pkt_intra_epg * NUM_PKTS,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001326 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001327
1328 #
Neale Ranns25b04942018-04-04 09:34:50 -07001329 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001330 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001331
Neale Ranns25b04942018-04-04 09:34:50 -07001332 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001333 se1 = VppGbpSubnet(
1334 self, rd0, "0.0.0.0", 0,
1335 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1336 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001337 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001338 se2 = VppGbpSubnet(
1339 self, rd0, "11.0.0.0", 8,
1340 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1341 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001342 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001343 se16 = VppGbpSubnet(
1344 self, rd0, "::", 0,
1345 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1346 sw_if_index=recirc_nat.recirc.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001347 sclass=epg_nat.sclass)
Neale Ranns25b04942018-04-04 09:34:50 -07001348 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001349 se3 = VppGbpSubnet(
1350 self, rd20, "0.0.0.0", 0,
1351 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1352 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001353 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001354 se36 = VppGbpSubnet(
1355 self, rd20, "::", 0,
1356 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1357 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001358 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001359 se4 = VppGbpSubnet(
1360 self, rd20, "11.0.0.0", 8,
1361 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1362 sw_if_index=epg_nat.uplink.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07001363 sclass=epg_nat.sclass)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001364 se1.add_vpp_config()
1365 se2.add_vpp_config()
1366 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001367 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001368 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001369 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001370
Neale Ranns25b04942018-04-04 09:34:50 -07001371 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1372 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001373 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1374 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001375 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001376
Neale Ranns4a6d0232018-04-24 07:45:33 -07001377 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001378 # From an EP to an outside address: IN2OUT
Neale Ranns4a6d0232018-04-24 07:45:33 -07001379 #
Neale Ranns25b04942018-04-04 09:34:50 -07001380 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001381 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001382 IP(src=eps[0].ip4.address,
1383 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001384 UDP(sport=1234, dport=1234) /
1385 Raw('\xa5' * 100))
1386
1387 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001388 self.send_and_assert_no_replies(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001389 pkt_inter_epg_220_to_global * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001390
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001391 acl2 = VppGbpAcl(self)
1392 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1393 sport_to=1234, dport_from=1234, dport_to=1234)
1394 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1395 sport_from=1234, sport_to=1234,
1396 dport_from=1234, dport_to=1234)
1397
1398 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001399 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001400 self, 400, epgs[0].sclass, epgs[3].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001401 [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,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001404 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001405 VppGbpContractRule(
1406 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001407 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001408 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001409 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001410 c4.add_vpp_config()
1411
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001412 self.send_and_expect_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001413 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns25b04942018-04-04 09:34:50 -07001414 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001415 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001416
Neale Ranns4a6d0232018-04-24 07:45:33 -07001417 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001418 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001419 IPv6(src=eps[0].ip6.address,
1420 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001421 UDP(sport=1234, dport=1234) /
1422 Raw('\xa5' * 100))
1423
1424 self.send_and_expect_natted6(self.pg0,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001425 pkt_inter_epg_220_to_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001426 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001427 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001428
1429 #
1430 # From a global address to an EP: OUT2IN
1431 #
Ole Troan8006c6a2018-12-17 12:02:26 +01001432 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns25b04942018-04-04 09:34:50 -07001433 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001434 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001435 src="1.1.1.1") /
1436 UDP(sport=1234, dport=1234) /
1437 Raw('\xa5' * 100))
1438
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001439 self.send_and_assert_no_replies(
1440 self.pg7, pkt_inter_epg_220_from_global * NUM_PKTS)
Neale Ranns25b04942018-04-04 09:34:50 -07001441
Neale Ranns13a08cc2018-11-07 09:25:54 -08001442 c5 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001443 self, 400, epgs[3].sclass, epgs[0].sclass, acl_index2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001444 [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,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001447 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02001448 VppGbpContractRule(
1449 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001450 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02001451 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001452 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns25b04942018-04-04 09:34:50 -07001453 c5.add_vpp_config()
1454
1455 self.send_and_expect_unnatted(self.pg7,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001456 pkt_inter_epg_220_from_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001457 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001458 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001459
Ole Troan8006c6a2018-12-17 12:02:26 +01001460 pkt_inter_epg_220_from_global = (Ether(src=str(self.router_mac),
Neale Ranns4a6d0232018-04-24 07:45:33 -07001461 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001462 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001463 src="6001::1") /
1464 UDP(sport=1234, dport=1234) /
1465 Raw('\xa5' * 100))
1466
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001467 self.send_and_expect_unnatted6(
1468 self.pg7,
1469 pkt_inter_epg_220_from_global * NUM_PKTS,
1470 eps[0].itf,
1471 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001472
1473 #
1474 # From a local VM to another local VM using resp. public addresses:
1475 # IN2OUT2IN
1476 #
Neale Ranns25b04942018-04-04 09:34:50 -07001477 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001478 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001479 IP(src=eps[0].ip4.address,
1480 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001481 UDP(sport=1234, dport=1234) /
1482 Raw('\xa5' * 100))
1483
Neale Ranns4a6d0232018-04-24 07:45:33 -07001484 self.send_and_expect_double_natted(eps[0].itf,
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001485 pkt_intra_epg_220_global * NUM_PKTS,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001486 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001487 eps[0].fip4.address,
1488 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001489
Neale Rannsc0a93142018-09-05 15:42:26 -07001490 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Ole Troan8006c6a2018-12-17 12:02:26 +01001491 dst=str(self.router_mac)) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001492 IPv6(src=eps[0].ip6.address,
1493 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001494 UDP(sport=1234, dport=1234) /
1495 Raw('\xa5' * 100))
1496
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001497 self.send_and_expect_double_natted6(
1498 eps[0].itf,
1499 pkt_intra_epg_220_global * NUM_PKTS,
1500 eps[1].itf,
1501 eps[0].fip6.address,
1502 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001503
1504 #
Neale Ranns25b04942018-04-04 09:34:50 -07001505 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001506 #
Neale Ranns25b04942018-04-04 09:34:50 -07001507 for ep in eps:
1508 # del static mappings for each EP from the 10/8 to 11/8 network
Filip Vargadd1e3e72019-04-15 18:52:43 +02001509 flags = self.config_flags.NAT_IS_ADDR_ONLY
Filip Vargaf4749ca2019-04-25 14:55:32 +02001510 self.vapi.nat44_add_del_static_mapping(
1511 is_add=0,
1512 local_ip_address=ep.ip4.bytes,
1513 external_ip_address=ep.fip4.bytes,
1514 external_sw_if_index=0xFFFFFFFF,
1515 vrf_id=0,
1516 flags=flags)
1517 self.vapi.nat66_add_del_static_mapping(
1518 local_ip_address=ep.ip6.bytes,
1519 external_ip_address=ep.fip6.bytes,
1520 vrf_id=0, is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001521
Neale Ranns25b04942018-04-04 09:34:50 -07001522 for epg in epgs:
1523 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001524 if epg != epgs[0] and epg != epgs[3]:
Filip Vargadd1e3e72019-04-15 18:52:43 +02001525 flags = self.config_flags.NAT_IS_INSIDE
Filip Vargaf4749ca2019-04-25 14:55:32 +02001526 self.vapi.nat44_interface_add_del_feature(
1527 sw_if_index=epg.bvi.sw_if_index,
1528 flags=flags,
1529 is_add=0)
1530 self.vapi.nat66_add_del_interface(
1531 is_add=0, flags=flags,
1532 sw_if_index=epg.bvi.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001533
Neale Ranns25b04942018-04-04 09:34:50 -07001534 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001535 self.vapi.nat44_interface_add_del_feature(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001536 sw_if_index=recirc.recirc.sw_if_index,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001537 is_add=0)
1538 self.vapi.nat66_add_del_interface(
Filip Vargaf4749ca2019-04-25 14:55:32 +02001539 is_add=0,
1540 sw_if_index=recirc.recirc.sw_if_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001541
Neale Ranns774356a2018-11-29 12:02:16 +00001542 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
Neale Ranns3eea9de2019-06-21 02:09:25 -07001543 tep=None, n_tries=100, s_time=1):
Neale Ranns774356a2018-11-29 12:02:16 +00001544 while (n_tries):
Neale Ranns3eea9de2019-06-21 02:09:25 -07001545 if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep):
Neale Ranns774356a2018-11-29 12:02:16 +00001546 return True
1547 n_tries = n_tries - 1
1548 self.sleep(s_time)
1549 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1550 return False
1551
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001552 def test_gbp_learn_l2(self):
1553 """ GBP L2 Endpoint Learning """
1554
Neale Ranns69a85b52019-06-14 07:49:50 +00001555 drop_no_contract = self.statistics.get_err_counter(
1556 '/err/gbp-policy-port/drop-no-contract')
1557 allow_intra_class = self.statistics.get_err_counter(
1558 '/err/gbp-policy-port/allow-intra-sclass')
Neale Ranns796c84b2019-03-28 07:56:23 -07001559
Neale Rannsb6a47952018-11-21 05:44:35 -08001560 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001561 learnt = [{'mac': '00:00:11:11:11:01',
1562 'ip': '10.0.0.1',
1563 'ip6': '2001:10::2'},
1564 {'mac': '00:00:11:11:11:02',
1565 'ip': '10.0.0.2',
1566 'ip6': '2001:10::3'}]
1567
1568 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001569 # IP tables
1570 #
1571 gt4 = VppIpTable(self, 1)
1572 gt4.add_vpp_config()
1573 gt6 = VppIpTable(self, 1, is_ip6=True)
1574 gt6.add_vpp_config()
1575
Neale Ranns160c9232019-06-19 06:25:56 -07001576 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001577 rd1.add_vpp_config()
1578
1579 #
1580 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1581 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1582 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1583 #
1584 self.pg2.config_ip4()
1585 self.pg2.resolve_arp()
1586 self.pg2.generate_remote_hosts(4)
1587 self.pg2.configure_ipv4_neighbors()
1588 self.pg3.config_ip4()
1589 self.pg3.resolve_arp()
1590 self.pg4.config_ip4()
1591 self.pg4.resolve_arp()
1592
1593 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001594 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1595 #
1596 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1597 "239.1.1.1", 88,
1598 mcast_itf=self.pg4)
1599 tun_bm.add_vpp_config()
1600
1601 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001602 # a GBP bridge domain with a BVI and a UU-flood interface
1603 #
1604 bd1 = VppBridgeDomain(self, 1)
1605 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07001606 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
1607 self.pg3, tun_bm)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001608 gbd1.add_vpp_config()
1609
1610 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1611 self.logger.info(self.vapi.cli("sh gbp bridge"))
1612
1613 # ... and has a /32 applied
1614 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1615 ip_addr.add_vpp_config()
1616
1617 #
1618 # The Endpoint-group in which we are learning endpoints
1619 #
Neale Ranns879d11c2019-01-21 23:34:18 -08001620 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001621 None, self.loop0,
1622 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001623 "2001:10::128",
1624 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001625 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08001626 epg_330 = VppGbpEndpointGroup(self, 330, 113, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001627 None, self.loop1,
1628 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08001629 "2001:11::128",
1630 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001631 epg_330.add_vpp_config()
1632
1633 #
1634 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001635 # learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001636 #
1637 vx_tun_l2_1 = VppGbpVxlanTunnel(
1638 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08001639 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
1640 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001641 vx_tun_l2_1.add_vpp_config()
1642
1643 #
1644 # A static endpoint that the learnt endpoints are trying to
1645 # talk to
1646 #
1647 ep = VppGbpEndpoint(self, self.pg0,
1648 epg_220, None,
1649 "10.0.0.127", "11.0.0.127",
1650 "2001:10::1", "3001::1")
1651 ep.add_vpp_config()
1652
1653 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1654
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001655 # a packet with an sclass from an unknown EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001656 p = (Ether(src=self.pg2.remote_mac,
1657 dst=self.pg2.local_mac) /
1658 IP(src=self.pg2.remote_hosts[0].ip4,
1659 dst=self.pg2.local_ip4) /
1660 UDP(sport=1234, dport=48879) /
1661 VXLAN(vni=99, gpid=88, flags=0x88) /
1662 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1663 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1664 UDP(sport=1234, dport=1234) /
1665 Raw('\xa5' * 100))
1666
1667 self.send_and_assert_no_replies(self.pg2, p)
1668
Neale Ranns796c84b2019-03-28 07:56:23 -07001669 self.logger.info(self.vapi.cli("sh error"))
Neale Ranns69a85b52019-06-14 07:49:50 +00001670 self.assert_error_counter_equal(
1671 '/err/gbp-policy-port/drop-no-contract',
1672 drop_no_contract + 1)
Neale Ranns796c84b2019-03-28 07:56:23 -07001673
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001674 #
1675 # we should not have learnt a new tunnel endpoint, since
1676 # the EPG was not learnt.
1677 #
1678 self.assertEqual(INDEX_INVALID,
1679 find_vxlan_gbp_tunnel(self,
1680 self.pg2.local_ip4,
1681 self.pg2.remote_hosts[0].ip4,
1682 99))
1683
Neale Ranns69a85b52019-06-14 07:49:50 +00001684 # ep is not learnt, because the EPG is unknown
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001685 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1686
Neale Ranns8da9fc62019-03-04 14:08:11 -08001687 #
1688 # Learn new EPs from IP packets
1689 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001690 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001691 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001692 # arriving on an unknown TEP
1693 p = (Ether(src=self.pg2.remote_mac,
1694 dst=self.pg2.local_mac) /
1695 IP(src=self.pg2.remote_hosts[1].ip4,
1696 dst=self.pg2.local_ip4) /
1697 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001698 VXLAN(vni=99, gpid=112, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001699 Ether(src=l['mac'], dst=ep.mac) /
1700 IP(src=l['ip'], dst=ep.ip4.address) /
1701 UDP(sport=1234, dport=1234) /
1702 Raw('\xa5' * 100))
1703
1704 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1705
1706 # the new TEP
1707 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1708 self,
1709 self.pg2.local_ip4,
1710 self.pg2.remote_hosts[1].ip4,
1711 99)
1712 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1713
1714 #
1715 # the EP is learnt via the learnt TEP
1716 # both from its MAC and its IP
1717 #
1718 self.assertTrue(find_gbp_endpoint(self,
1719 vx_tun_l2_1.sw_if_index,
1720 mac=l['mac']))
1721 self.assertTrue(find_gbp_endpoint(self,
1722 vx_tun_l2_1.sw_if_index,
1723 ip=l['ip']))
1724
Neale Ranns69a85b52019-06-14 07:49:50 +00001725 self.assert_error_counter_equal(
1726 '/err/gbp-policy-port/allow-intra-sclass',
1727 allow_intra_class + 2)
Neale Ranns796c84b2019-03-28 07:56:23 -07001728
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001729 self.logger.info(self.vapi.cli("show gbp endpoint"))
1730 self.logger.info(self.vapi.cli("show gbp vxlan"))
Neale Ranns8da9fc62019-03-04 14:08:11 -08001731 self.logger.info(self.vapi.cli("show ip mfib"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001732
1733 #
1734 # If we sleep for the threshold time, the learnt endpoints should
1735 # age out
1736 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001737 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001738 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1739 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001740
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001741 #
Neale Ranns8da9fc62019-03-04 14:08:11 -08001742 # Learn new EPs from GARP packets received on the BD's mcast tunnel
1743 #
1744 for ii, l in enumerate(learnt):
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001745 # add some junk in the reserved field of the vxlan-header
1746 # next to the VNI. we should accept since reserved bits are
1747 # ignored on rx.
Neale Ranns8da9fc62019-03-04 14:08:11 -08001748 p = (Ether(src=self.pg2.remote_mac,
1749 dst=self.pg2.local_mac) /
1750 IP(src=self.pg2.remote_hosts[1].ip4,
1751 dst="239.1.1.1") /
1752 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001753 VXLAN(vni=88, reserved2=0x80, gpid=112, flags=0x88) /
Neale Ranns8da9fc62019-03-04 14:08:11 -08001754 Ether(src=l['mac'], dst="ff:ff:ff:ff:ff:ff") /
1755 ARP(op="who-has",
1756 psrc=l['ip'], pdst=l['ip'],
1757 hwsrc=l['mac'], hwdst="ff:ff:ff:ff:ff:ff"))
1758
1759 rx = self.send_and_expect(self.pg4, [p], self.pg0)
1760
1761 # the new TEP
1762 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1763 self,
1764 self.pg2.local_ip4,
1765 self.pg2.remote_hosts[1].ip4,
1766 99)
1767 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1768
1769 #
1770 # the EP is learnt via the learnt TEP
1771 # both from its MAC and its IP
1772 #
1773 self.assertTrue(find_gbp_endpoint(self,
1774 vx_tun_l2_1.sw_if_index,
1775 mac=l['mac']))
1776 self.assertTrue(find_gbp_endpoint(self,
1777 vx_tun_l2_1.sw_if_index,
1778 ip=l['ip']))
1779
1780 #
1781 # wait for the learnt endpoints to age out
1782 #
1783 for l in learnt:
1784 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1785 mac=l['mac'])
1786
1787 #
1788 # Learn new EPs from L2 packets
1789 #
1790 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001791 # a packet with an sclass from a known EPG
Neale Ranns8da9fc62019-03-04 14:08:11 -08001792 # arriving on an unknown TEP
1793 p = (Ether(src=self.pg2.remote_mac,
1794 dst=self.pg2.local_mac) /
1795 IP(src=self.pg2.remote_hosts[1].ip4,
1796 dst=self.pg2.local_ip4) /
1797 UDP(sport=1234, dport=48879) /
1798 VXLAN(vni=99, gpid=112, flags=0x88) /
1799 Ether(src=l['mac'], dst=ep.mac) /
1800 Raw('\xa5' * 100))
1801
1802 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1803
1804 # the new TEP
1805 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1806 self,
1807 self.pg2.local_ip4,
1808 self.pg2.remote_hosts[1].ip4,
1809 99)
1810 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1811
1812 #
1813 # the EP is learnt via the learnt TEP
1814 # both from its MAC and its IP
1815 #
1816 self.assertTrue(find_gbp_endpoint(self,
1817 vx_tun_l2_1.sw_if_index,
1818 mac=l['mac']))
1819
1820 self.logger.info(self.vapi.cli("show gbp endpoint"))
1821 self.logger.info(self.vapi.cli("show gbp vxlan"))
1822 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1823
1824 #
1825 # wait for the learnt endpoints to age out
1826 #
1827 for l in learnt:
1828 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1829 mac=l['mac'])
1830
1831 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001832 # repeat. the do not learn bit is set so the EPs are not learnt
1833 #
1834 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001835 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001836 p = (Ether(src=self.pg2.remote_mac,
1837 dst=self.pg2.local_mac) /
1838 IP(src=self.pg2.remote_hosts[1].ip4,
1839 dst=self.pg2.local_ip4) /
1840 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001841 VXLAN(vni=99, gpid=112, flags=0x88, gpflags="D") /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001842 Ether(src=l['mac'], dst=ep.mac) /
1843 IP(src=l['ip'], dst=ep.ip4.address) /
1844 UDP(sport=1234, dport=1234) /
1845 Raw('\xa5' * 100))
1846
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001847 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001848
1849 for l in learnt:
1850 self.assertFalse(find_gbp_endpoint(self,
1851 vx_tun_l2_1.sw_if_index,
1852 mac=l['mac']))
1853
1854 #
1855 # repeat
1856 #
1857 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001858 # a packet with an sclass from a known EPG
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001859 # set a reserved bit in addition to the G and I
1860 # reserved bits should not be checked on rx.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001861 p = (Ether(src=self.pg2.remote_mac,
1862 dst=self.pg2.local_mac) /
1863 IP(src=self.pg2.remote_hosts[1].ip4,
1864 dst=self.pg2.local_ip4) /
1865 UDP(sport=1234, dport=48879) /
Neale Ranns81cfa9c2019-07-04 14:12:50 +00001866 VXLAN(vni=99, gpid=112, flags=0xc8) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001867 Ether(src=l['mac'], dst=ep.mac) /
1868 IP(src=l['ip'], dst=ep.ip4.address) /
1869 UDP(sport=1234, dport=1234) /
1870 Raw('\xa5' * 100))
1871
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001872 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001873
1874 self.assertTrue(find_gbp_endpoint(self,
1875 vx_tun_l2_1.sw_if_index,
1876 mac=l['mac']))
1877
1878 #
1879 # Static EP replies to dynamics
1880 #
1881 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1882 for l in learnt:
1883 p = (Ether(src=ep.mac, dst=l['mac']) /
1884 IP(dst=l['ip'], src=ep.ip4.address) /
1885 UDP(sport=1234, dport=1234) /
1886 Raw('\xa5' * 100))
1887
1888 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1889
1890 for rx in rxs:
1891 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1892 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1893 self.assertEqual(rx[UDP].dport, 48879)
1894 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08001895 self.assertEqual(rx[VXLAN].gpid, 112)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001896 self.assertEqual(rx[VXLAN].vni, 99)
1897 self.assertTrue(rx[VXLAN].flags.G)
1898 self.assertTrue(rx[VXLAN].flags.Instance)
1899 self.assertTrue(rx[VXLAN].gpflags.A)
1900 self.assertFalse(rx[VXLAN].gpflags.D)
1901
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001902 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001903 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1904 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001905
1906 #
1907 # repeat in the other EPG
1908 # there's no contract between 220 and 330, but the A-bit is set
1909 # so the packet is cleared for delivery
1910 #
1911 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001912 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001913 p = (Ether(src=self.pg2.remote_mac,
1914 dst=self.pg2.local_mac) /
1915 IP(src=self.pg2.remote_hosts[1].ip4,
1916 dst=self.pg2.local_ip4) /
1917 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001918 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001919 Ether(src=l['mac'], dst=ep.mac) /
1920 IP(src=l['ip'], dst=ep.ip4.address) /
1921 UDP(sport=1234, dport=1234) /
1922 Raw('\xa5' * 100))
1923
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001924 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Mohsin Kazmie60dfd72019-04-16 15:15:07 +02001925
1926 self.assertTrue(find_gbp_endpoint(self,
1927 vx_tun_l2_1.sw_if_index,
1928 mac=l['mac']))
1929
1930 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001931 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001932 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001933 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001934 p = (Ether(src=ep.mac, dst=l['mac']) /
1935 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1936 UDP(sport=1234, dport=1234) /
1937 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001938
Neale Ranns13a08cc2018-11-07 09:25:54 -08001939 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001940
1941 #
1942 # refresh the entries after the check for no replies above
1943 #
1944 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001945 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001946 p = (Ether(src=self.pg2.remote_mac,
1947 dst=self.pg2.local_mac) /
1948 IP(src=self.pg2.remote_hosts[1].ip4,
1949 dst=self.pg2.local_ip4) /
1950 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08001951 VXLAN(vni=99, gpid=113, flags=0x88, gpflags='A') /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001952 Ether(src=l['mac'], dst=ep.mac) /
1953 IP(src=l['ip'], dst=ep.ip4.address) /
1954 UDP(sport=1234, dport=1234) /
1955 Raw('\xa5' * 100))
1956
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001957 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001958
1959 self.assertTrue(find_gbp_endpoint(self,
1960 vx_tun_l2_1.sw_if_index,
1961 mac=l['mac']))
1962
1963 #
1964 # Add the contract so they can talk
1965 #
1966 acl = VppGbpAcl(self)
1967 rule = acl.create_rule(permit_deny=1, proto=17)
1968 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1969 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001970 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07001971 self, 401, epg_220.sclass, epg_330.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001972 [VppGbpContractRule(
1973 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04001974 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08001975 []),
Neale Rannse28c87c2019-07-05 00:53:45 -07001976 VppGbpContractRule(
1977 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1978 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
1979 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08001980 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001981 c1.add_vpp_config()
1982
1983 for l in learnt:
1984 p = (Ether(src=ep.mac, dst=l['mac']) /
1985 IP(dst=l['ip'], src=ep.ip4.address) /
1986 UDP(sport=1234, dport=1234) /
1987 Raw('\xa5' * 100))
1988
1989 self.send_and_expect(self.pg0, [p], self.pg2)
1990
1991 #
1992 # send UU packets from the local EP
1993 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001994 self.logger.info(self.vapi.cli("sh gbp bridge"))
Neale Rannse28c87c2019-07-05 00:53:45 -07001995 self.logger.info(self.vapi.cli("sh bridge-domain 1 detail"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001996 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1997 IP(dst="10.0.0.133", src=ep.ip4.address) /
1998 UDP(sport=1234, dport=1234) /
1999 Raw('\xa5' * 100))
Neale Ranns879d11c2019-01-21 23:34:18 -08002000 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_fwd)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002001
2002 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2003
2004 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2005 IP(dst="10.0.0.133", src=ep.ip4.address) /
2006 UDP(sport=1234, dport=1234) /
2007 Raw('\xa5' * 100))
2008 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
2009
Neale Ranns879d11c2019-01-21 23:34:18 -08002010 for rx in rxs:
2011 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2012 self.assertEqual(rx[IP].dst, "239.1.1.1")
2013 self.assertEqual(rx[UDP].dport, 48879)
2014 # the UDP source port is a random value for hashing
2015 self.assertEqual(rx[VXLAN].gpid, 112)
2016 self.assertEqual(rx[VXLAN].vni, 88)
2017 self.assertTrue(rx[VXLAN].flags.G)
2018 self.assertTrue(rx[VXLAN].flags.Instance)
2019 self.assertFalse(rx[VXLAN].gpflags.A)
2020 self.assertFalse(rx[VXLAN].gpflags.D)
2021
Neale Rannse28c87c2019-07-05 00:53:45 -07002022 acl = VppGbpAcl(self)
2023 rule = acl.create_rule(permit_deny=1, proto=17)
2024 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2025 acl_index = acl.add_vpp_config([rule, rule2])
2026 c2 = VppGbpContract(
2027 self, 401, epg_330.sclass, epg_220.sclass, acl_index,
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 VppGbpContractRule(
2033 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2034 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2035 [])],
2036 [ETH_P_IP, ETH_P_IPV6])
2037 c2.add_vpp_config()
2038
2039 for l in learnt:
2040 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2041 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002042 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002043 # Check v6 Endpoints learning
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002044 #
2045 for l in learnt:
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002046 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002047 p = (Ether(src=self.pg2.remote_mac,
2048 dst=self.pg2.local_mac) /
2049 IP(src=self.pg2.remote_hosts[1].ip4,
2050 dst=self.pg2.local_ip4) /
2051 UDP(sport=1234, dport=48879) /
Neale Rannse28c87c2019-07-05 00:53:45 -07002052 VXLAN(vni=99, gpid=113, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002053 Ether(src=l['mac'], dst=ep.mac) /
2054 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2055 UDP(sport=1234, dport=1234) /
2056 Raw('\xa5' * 100))
2057
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002058 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Rannse28c87c2019-07-05 00:53:45 -07002059 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002060
Neale Rannse28c87c2019-07-05 00:53:45 -07002061 self.assertTrue(find_gbp_endpoint(
2062 self,
2063 vx_tun_l2_1.sw_if_index,
2064 ip=l['ip6'],
2065 tep=[self.pg2.local_ip4,
2066 self.pg2.remote_hosts[1].ip4]))
2067
2068 self.logger.info(self.vapi.cli("sh int"))
2069 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
2070 self.logger.info(self.vapi.cli("sh gbp vxlan"))
2071 self.logger.info(self.vapi.cli("sh gbp endpoint"))
2072 self.logger.info(self.vapi.cli("sh gbp interface"))
2073
2074 #
2075 # EP moves to a different TEP
2076 #
2077 for l in learnt:
2078 # a packet with an sclass from a known EPG
2079 p = (Ether(src=self.pg2.remote_mac,
2080 dst=self.pg2.local_mac) /
2081 IP(src=self.pg2.remote_hosts[2].ip4,
2082 dst=self.pg2.local_ip4) /
2083 UDP(sport=1234, dport=48879) /
2084 VXLAN(vni=99, gpid=113, flags=0x88) /
2085 Ether(src=l['mac'], dst=ep.mac) /
2086 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2087 UDP(sport=1234, dport=1234) /
2088 Raw('\xa5' * 100))
2089
2090 rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
2091 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
2092
2093 self.assertTrue(find_gbp_endpoint(
2094 self,
2095 vx_tun_l2_1.sw_if_index,
Neale Ranns6d1ba562019-07-10 01:14:58 -07002096 sclass=113,
Neale Rannse28c87c2019-07-05 00:53:45 -07002097 mac=l['mac'],
2098 tep=[self.pg2.local_ip4,
2099 self.pg2.remote_hosts[2].ip4]))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002100
2101 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002102 # v6 remote EP reachability
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002103 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002104 for l in learnt:
2105 p = (Ether(src=ep.mac, dst=l['mac']) /
2106 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2107 UDP(sport=1234, dport=1234) /
2108 Raw('\xa5' * 100))
2109
2110 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
2111
2112 for rx in rxs:
2113 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Rannse28c87c2019-07-05 00:53:45 -07002114 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns69a85b52019-06-14 07:49:50 +00002115 self.assertEqual(rx[UDP].dport, 48879)
2116 # the UDP source port is a random value for hashing
2117 self.assertEqual(rx[VXLAN].gpid, 112)
2118 self.assertEqual(rx[VXLAN].vni, 99)
2119 self.assertTrue(rx[VXLAN].flags.G)
2120 self.assertTrue(rx[VXLAN].flags.Instance)
2121 self.assertTrue(rx[VXLAN].gpflags.A)
2122 self.assertFalse(rx[VXLAN].gpflags.D)
2123 self.assertEqual(rx[IPv6].dst, l['ip6'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002124
2125 #
Neale Ranns6d1ba562019-07-10 01:14:58 -07002126 # EP changes sclass
2127 #
2128 for l in learnt:
2129 # a packet with an sclass from a known EPG
2130 p = (Ether(src=self.pg2.remote_mac,
2131 dst=self.pg2.local_mac) /
2132 IP(src=self.pg2.remote_hosts[2].ip4,
2133 dst=self.pg2.local_ip4) /
2134 UDP(sport=1234, dport=48879) /
2135 VXLAN(vni=99, gpid=112, flags=0x88) /
2136 Ether(src=l['mac'], dst=ep.mac) /
2137 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2138 UDP(sport=1234, dport=1234) /
2139 Raw('\xa5' * 100))
2140
2141 rx = self.send_and_expect(self.pg2, p * 1, self.pg0)
2142 rx = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
2143
2144 self.assertTrue(find_gbp_endpoint(
2145 self,
2146 vx_tun_l2_1.sw_if_index,
2147 mac=l['mac'],
2148 sclass=112,
2149 tep=[self.pg2.local_ip4,
2150 self.pg2.remote_hosts[2].ip4]))
2151
2152 #
2153 # check reachability and contract intra-epg
2154 #
2155 allow_intra_class = self.statistics.get_err_counter(
2156 '/err/gbp-policy-mac/allow-intra-sclass')
2157
2158 for l in learnt:
2159 p = (Ether(src=ep.mac, dst=l['mac']) /
2160 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2161 UDP(sport=1234, dport=1234) /
2162 Raw('\xa5' * 100))
2163
2164 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
2165
2166 for rx in rxs:
2167 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2168 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
2169 self.assertEqual(rx[UDP].dport, 48879)
2170 self.assertEqual(rx[VXLAN].gpid, 112)
2171 self.assertEqual(rx[VXLAN].vni, 99)
2172 self.assertTrue(rx[VXLAN].flags.G)
2173 self.assertTrue(rx[VXLAN].flags.Instance)
2174 self.assertTrue(rx[VXLAN].gpflags.A)
2175 self.assertFalse(rx[VXLAN].gpflags.D)
2176 self.assertEqual(rx[IPv6].dst, l['ip6'])
2177
2178 allow_intra_class += NUM_PKTS
2179
2180 self.assert_error_counter_equal(
2181 '/err/gbp-policy-mac/allow-intra-sclass',
2182 allow_intra_class)
2183
2184 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002185 # clean up
2186 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002187 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002188 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
2189 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002190 self.pg2.unconfig_ip4()
2191 self.pg3.unconfig_ip4()
2192 self.pg4.unconfig_ip4()
2193
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002194 def test_gbp_contract(self):
Neale Ranns69a85b52019-06-14 07:49:50 +00002195 """ GBP Contracts """
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002196
2197 #
Neale Ranns160c9232019-06-19 06:25:56 -07002198 # Route Domains
2199 #
2200 gt4 = VppIpTable(self, 0)
2201 gt4.add_vpp_config()
2202 gt6 = VppIpTable(self, 0, is_ip6=True)
2203 gt6.add_vpp_config()
2204
2205 rd0 = VppGbpRouteDomain(self, 0, 400, gt4, gt6, None, None)
2206
2207 rd0.add_vpp_config()
2208
2209 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002210 # Bridge Domains
2211 #
2212 bd1 = VppBridgeDomain(self, 1, arp_term=0)
2213 bd2 = VppBridgeDomain(self, 2, arp_term=0)
2214
2215 bd1.add_vpp_config()
2216 bd2.add_vpp_config()
2217
Neale Ranns160c9232019-06-19 06:25:56 -07002218 gbd1 = VppGbpBridgeDomain(self, bd1, rd0, self.loop0)
2219 gbd2 = VppGbpBridgeDomain(self, bd2, rd0, self.loop1)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002220
2221 gbd1.add_vpp_config()
2222 gbd2.add_vpp_config()
2223
2224 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002225 # 3 EPGs, 2 of which share a BD.
2226 #
2227 epgs = [VppGbpEndpointGroup(self, 220, 1220, rd0, gbd1,
2228 None, self.loop0,
2229 "10.0.0.128", "2001:10::128"),
2230 VppGbpEndpointGroup(self, 221, 1221, rd0, gbd1,
2231 None, self.loop0,
2232 "10.0.1.128", "2001:10:1::128"),
2233 VppGbpEndpointGroup(self, 222, 1222, rd0, gbd2,
2234 None, self.loop1,
2235 "10.0.2.128", "2001:10:2::128")]
2236 #
2237 # 4 end-points, 2 in the same subnet, 3 in the same BD
2238 #
2239 eps = [VppGbpEndpoint(self, self.pg0,
2240 epgs[0], None,
2241 "10.0.0.1", "11.0.0.1",
2242 "2001:10::1", "3001::1"),
2243 VppGbpEndpoint(self, self.pg1,
2244 epgs[0], None,
2245 "10.0.0.2", "11.0.0.2",
2246 "2001:10::2", "3001::2"),
2247 VppGbpEndpoint(self, self.pg2,
2248 epgs[1], None,
2249 "10.0.1.1", "11.0.0.3",
2250 "2001:10:1::1", "3001::3"),
2251 VppGbpEndpoint(self, self.pg3,
2252 epgs[2], None,
2253 "10.0.2.1", "11.0.0.4",
2254 "2001:10:2::1", "3001::4")]
2255
2256 #
2257 # Config related to each of the EPGs
2258 #
2259 for epg in epgs:
2260 # IP config on the BVI interfaces
2261 if epg != epgs[1]:
2262 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
2263 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
2264 self.vapi.sw_interface_set_mac_address(
2265 epg.bvi.sw_if_index,
2266 self.router_mac.packed)
2267
2268 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
2269 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
2270 if_ip4.add_vpp_config()
2271 if_ip6.add_vpp_config()
2272
2273 # add the BD ARP termination entry for BVI IP
2274 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
2275 str(self.router_mac),
Neale Rannsbc764c82019-06-19 07:07:13 -07002276 epg.bvi_ip4.address)
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002277 epg.bd_arp_ip4.add_vpp_config()
2278
2279 # EPG in VPP
2280 epg.add_vpp_config()
2281
2282 #
2283 # config ep
2284 #
2285 for ep in eps:
2286 ep.add_vpp_config()
2287
2288 self.logger.info(self.vapi.cli("show gbp endpoint"))
2289 self.logger.info(self.vapi.cli("show interface"))
2290 self.logger.info(self.vapi.cli("show br"))
2291
2292 #
2293 # Intra epg allowed without contract
2294 #
2295 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2296 dst=self.pg1.remote_mac) /
2297 IP(src=eps[0].ip4.address,
2298 dst=eps[1].ip4.address) /
2299 UDP(sport=1234, dport=1234) /
2300 Raw('\xa5' * 100))
2301
2302 self.send_and_expect_bridged(self.pg0,
2303 pkt_intra_epg_220_to_220 * 65,
2304 self.pg1)
2305
Neale Ranns69a85b52019-06-14 07:49:50 +00002306 pkt_intra_epg_220_to_220 = (Ether(src=self.pg0.remote_mac,
2307 dst=self.pg1.remote_mac) /
2308 IPv6(src=eps[0].ip6.address,
2309 dst=eps[1].ip6.address) /
2310 UDP(sport=1234, dport=1234) /
2311 Raw('\xa5' * 100))
2312
2313 self.send_and_expect_bridged6(self.pg0,
2314 pkt_intra_epg_220_to_220 * 65,
2315 self.pg1)
2316
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002317 #
2318 # Inter epg denied without contract
2319 #
2320 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
2321 dst=self.pg2.remote_mac) /
2322 IP(src=eps[0].ip4.address,
2323 dst=eps[2].ip4.address) /
2324 UDP(sport=1234, dport=1234) /
2325 Raw('\xa5' * 100))
2326
2327 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_220_to_221)
2328
2329 #
2330 # A uni-directional contract from EPG 220 -> 221
2331 #
2332 acl = VppGbpAcl(self)
2333 rule = acl.create_rule(permit_deny=1, proto=17)
2334 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
Neale Ranns69a85b52019-06-14 07:49:50 +00002335 rule3 = acl.create_rule(permit_deny=1, proto=1)
2336 acl_index = acl.add_vpp_config([rule, rule2, rule3])
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002337 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002338 self, 400, epgs[0].sclass, epgs[1].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002339 [VppGbpContractRule(
2340 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002341 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002342 []),
2343 VppGbpContractRule(
2344 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002345 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns69a85b52019-06-14 07:49:50 +00002346 []),
2347 VppGbpContractRule(
2348 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2349 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002350 [])],
2351 [ETH_P_IP, ETH_P_IPV6])
2352 c1.add_vpp_config()
2353
2354 self.send_and_expect_bridged(eps[0].itf,
2355 pkt_inter_epg_220_to_221 * 65,
2356 eps[2].itf)
2357
2358 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
2359 dst=str(self.router_mac)) /
2360 IP(src=eps[0].ip4.address,
2361 dst=eps[3].ip4.address) /
2362 UDP(sport=1234, dport=1234) /
2363 Raw('\xa5' * 100))
2364 self.send_and_assert_no_replies(eps[0].itf,
2365 pkt_inter_epg_220_to_222 * 65)
2366
2367 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002368 # ping router IP in different BD
2369 #
2370 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2371 dst=str(self.router_mac)) /
2372 IP(src=eps[0].ip4.address,
2373 dst=epgs[1].bvi_ip4.address) /
2374 ICMP(type='echo-request'))
2375
2376 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2377
2378 pkt_router_ping_220_to_221 = (Ether(src=self.pg0.remote_mac,
2379 dst=str(self.router_mac)) /
2380 IPv6(src=eps[0].ip6.address,
2381 dst=epgs[1].bvi_ip6.address) /
2382 ICMPv6EchoRequest())
2383
2384 self.send_and_expect(self.pg0, [pkt_router_ping_220_to_221], self.pg0)
2385
2386 #
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002387 # contract for the return direction
2388 #
2389 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002390 self, 400, epgs[1].sclass, epgs[0].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002391 [VppGbpContractRule(
2392 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002393 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002394 []),
2395 VppGbpContractRule(
2396 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002397 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002398 [])],
2399 [ETH_P_IP, ETH_P_IPV6])
2400 c2.add_vpp_config()
2401
2402 self.send_and_expect_bridged(eps[0].itf,
2403 pkt_inter_epg_220_to_221 * 65,
2404 eps[2].itf)
2405 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2406 dst=self.pg0.remote_mac) /
2407 IP(src=eps[2].ip4.address,
2408 dst=eps[0].ip4.address) /
2409 UDP(sport=1234, dport=1234) /
2410 Raw('\xa5' * 100))
2411 self.send_and_expect_bridged(eps[2].itf,
2412 pkt_inter_epg_221_to_220 * 65,
2413 eps[0].itf)
Neale Ranns69a85b52019-06-14 07:49:50 +00002414 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2415 dst=str(self.router_mac)) /
2416 IP(src=eps[2].ip4.address,
2417 dst=eps[0].ip4.address) /
2418 UDP(sport=1234, dport=1234) /
2419 Raw('\xa5' * 100))
2420 self.send_and_expect_routed(eps[2].itf,
2421 pkt_inter_epg_221_to_220 * 65,
2422 eps[0].itf,
2423 str(self.router_mac))
2424 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
2425 dst=str(self.router_mac)) /
2426 IPv6(src=eps[2].ip6.address,
2427 dst=eps[0].ip6.address) /
2428 UDP(sport=1234, dport=1234) /
2429 Raw('\xa5' * 100))
2430 self.send_and_expect_routed6(eps[2].itf,
2431 pkt_inter_epg_221_to_220 * 65,
2432 eps[0].itf,
2433 str(self.router_mac))
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002434
2435 #
2436 # contract between 220 and 222 uni-direction
2437 #
2438 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07002439 self, 400, epgs[0].sclass, epgs[2].sclass, acl_index,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002440 [VppGbpContractRule(
2441 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002442 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002443 []),
2444 VppGbpContractRule(
2445 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04002446 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Mohsin Kazmife52dea2019-04-18 15:54:58 +02002447 [])],
2448 [ETH_P_IP, ETH_P_IPV6])
2449 c3.add_vpp_config()
2450
2451 self.send_and_expect(eps[0].itf,
2452 pkt_inter_epg_220_to_222 * 65,
2453 eps[3].itf)
2454
2455 c3.remove_vpp_config()
2456 c1.remove_vpp_config()
2457 c2.remove_vpp_config()
2458 acl.remove_vpp_config()
2459
Neale Ranns69a85b52019-06-14 07:49:50 +00002460 def test_gbp_bd_drop_flags(self):
2461 """ GBP BD drop flags """
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002462
2463 #
2464 # IP tables
2465 #
2466 gt4 = VppIpTable(self, 1)
2467 gt4.add_vpp_config()
2468 gt6 = VppIpTable(self, 1, is_ip6=True)
2469 gt6.add_vpp_config()
2470
Neale Ranns160c9232019-06-19 06:25:56 -07002471 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002472 rd1.add_vpp_config()
2473
2474 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002475 # a GBP bridge domain with a BVI only
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002476 #
2477 bd1 = VppBridgeDomain(self, 1)
2478 bd1.add_vpp_config()
2479
Neale Ranns69a85b52019-06-14 07:49:50 +00002480 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2481 None, None,
2482 uu_drop=True, bm_drop=True)
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002483 gbd1.add_vpp_config()
2484
2485 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2486 self.logger.info(self.vapi.cli("sh gbp bridge"))
2487
2488 # ... and has a /32 applied
2489 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2490 ip_addr.add_vpp_config()
2491
2492 #
2493 # The Endpoint-group
2494 #
2495 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2496 None, self.loop0,
2497 "10.0.0.128",
2498 "2001:10::128",
2499 VppGbpEndpointRetention(2))
2500 epg_220.add_vpp_config()
2501
2502 ep = VppGbpEndpoint(self, self.pg0,
2503 epg_220, None,
2504 "10.0.0.127", "11.0.0.127",
2505 "2001:10::1", "3001::1")
2506 ep.add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00002507
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002508 #
2509 # send UU/BM packet from the local EP with UU drop and BM drop enabled
2510 # in bd
2511 #
2512 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2513 self.logger.info(self.vapi.cli("sh gbp bridge"))
2514 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
2515 IP(dst="10.0.0.133", src=ep.ip4.address) /
2516 UDP(sport=1234, dport=1234) /
2517 Raw('\xa5' * 100))
2518 self.send_and_assert_no_replies(ep.itf, [p_uu])
2519
2520 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2521 IP(dst="10.0.0.133", src=ep.ip4.address) /
2522 UDP(sport=1234, dport=1234) /
2523 Raw('\xa5' * 100))
2524 self.send_and_assert_no_replies(ep.itf, [p_bm])
2525
2526 self.pg3.unconfig_ip4()
Mohsin Kazmi7363d472019-04-04 13:22:15 +02002527
2528 self.logger.info(self.vapi.cli("sh int"))
2529
Neale Ranns69a85b52019-06-14 07:49:50 +00002530 def test_gbp_bd_arp_flags(self):
2531 """ GBP BD arp flags """
2532
2533 #
2534 # IP tables
2535 #
2536 gt4 = VppIpTable(self, 1)
2537 gt4.add_vpp_config()
2538 gt6 = VppIpTable(self, 1, is_ip6=True)
2539 gt6.add_vpp_config()
2540
2541 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
2542 rd1.add_vpp_config()
2543
2544 #
2545 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
2546 #
2547 self.pg4.config_ip4()
2548 self.pg4.resolve_arp()
2549
2550 #
2551 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
2552 #
2553 tun_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2554 "239.1.1.1", 88,
2555 mcast_itf=self.pg4)
2556 tun_uu.add_vpp_config()
2557
2558 #
2559 # a GBP bridge domain with a BVI and a UU-flood interface
2560 #
2561 bd1 = VppBridgeDomain(self, 1)
2562 bd1.add_vpp_config()
2563
2564 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0,
2565 tun_uu, None,
2566 ucast_arp=True)
2567 gbd1.add_vpp_config()
2568
2569 # ... and has a /32 applied
2570 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2571 ip_addr.add_vpp_config()
2572
2573 #
2574 # The Endpoint-group
2575 #
2576 epg_220 = VppGbpEndpointGroup(self, 220, 112, rd1, gbd1,
2577 None, self.loop0,
2578 "10.0.0.128",
2579 "2001:10::128",
2580 VppGbpEndpointRetention(2))
2581 epg_220.add_vpp_config()
2582
2583 ep = VppGbpEndpoint(self, self.pg0,
2584 epg_220, None,
2585 "10.0.0.127", "11.0.0.127",
2586 "2001:10::1", "3001::1")
2587 ep.add_vpp_config()
2588
2589 #
2590 # send ARP packet from the local EP expect it on the uu interface
2591 #
2592 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2593 self.logger.info(self.vapi.cli("sh gbp bridge"))
2594 p_arp = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
2595 ARP(op="who-has",
2596 psrc=ep.ip4.address, pdst="10.0.0.99",
2597 hwsrc=ep.mac,
2598 hwdst="ff:ff:ff:ff:ff:ff"))
2599 self.send_and_expect(ep.itf, [p_arp], self.pg4)
2600
2601 self.pg4.unconfig_ip4()
2602
Neale Rannsc29c0af2018-11-07 04:21:12 -08002603 def test_gbp_learn_vlan_l2(self):
2604 """ GBP L2 Endpoint w/ VLANs"""
2605
Neale Rannsb6a47952018-11-21 05:44:35 -08002606 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08002607 learnt = [{'mac': '00:00:11:11:11:01',
2608 'ip': '10.0.0.1',
2609 'ip6': '2001:10::2'},
2610 {'mac': '00:00:11:11:11:02',
2611 'ip': '10.0.0.2',
2612 'ip6': '2001:10::3'}]
2613
2614 #
Neale Rannsc29c0af2018-11-07 04:21:12 -08002615 # IP tables
2616 #
2617 gt4 = VppIpTable(self, 1)
2618 gt4.add_vpp_config()
2619 gt6 = VppIpTable(self, 1, is_ip6=True)
2620 gt6.add_vpp_config()
2621
Neale Ranns160c9232019-06-19 06:25:56 -07002622 rd1 = VppGbpRouteDomain(self, 1, 401, gt4, gt6)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002623 rd1.add_vpp_config()
2624
2625 #
2626 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
2627 #
2628 self.pg2.config_ip4()
2629 self.pg2.resolve_arp()
2630 self.pg2.generate_remote_hosts(4)
2631 self.pg2.configure_ipv4_neighbors()
2632 self.pg3.config_ip4()
2633 self.pg3.resolve_arp()
2634
2635 #
2636 # The EP will be on a vlan sub-interface
2637 #
2638 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
2639 vlan_11.admin_up()
Ole Troana5b2eec2019-03-11 19:23:25 +01002640 self.vapi.l2_interface_vlan_tag_rewrite(
2641 sw_if_index=vlan_11.sw_if_index, vtr_op=L2_VTR_OP.L2_POP_1,
2642 push_dot1q=11)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002643
2644 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
2645 self.pg3.remote_ip4, 116)
2646 bd_uu_fwd.add_vpp_config()
2647
2648 #
2649 # a GBP bridge domain with a BVI and a UU-flood interface
2650 # The BD is marked as do not learn, so no endpoints are ever
2651 # learnt in this BD.
2652 #
2653 bd1 = VppBridgeDomain(self, 1)
2654 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002655 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, bd_uu_fwd,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002656 learn=False)
2657 gbd1.add_vpp_config()
2658
2659 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2660 self.logger.info(self.vapi.cli("sh gbp bridge"))
2661
2662 # ... and has a /32 applied
2663 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2664 ip_addr.add_vpp_config()
2665
2666 #
2667 # The Endpoint-group in which we are learning endpoints
2668 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002669 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Rannsc29c0af2018-11-07 04:21:12 -08002670 None, self.loop0,
2671 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002672 "2001:10::128",
2673 VppGbpEndpointRetention(2))
Neale Rannsc29c0af2018-11-07 04:21:12 -08002674 epg_220.add_vpp_config()
2675
2676 #
2677 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002678 # learning enabled
Neale Rannsc29c0af2018-11-07 04:21:12 -08002679 #
2680 vx_tun_l2_1 = VppGbpVxlanTunnel(
2681 self, 99, bd1.bd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002682 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2,
2683 self.pg2.local_ip4)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002684 vx_tun_l2_1.add_vpp_config()
2685
2686 #
2687 # A static endpoint that the learnt endpoints are trying to
2688 # talk to
2689 #
2690 ep = VppGbpEndpoint(self, vlan_11,
2691 epg_220, None,
2692 "10.0.0.127", "11.0.0.127",
2693 "2001:10::1", "3001::1")
2694 ep.add_vpp_config()
2695
2696 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
2697
2698 #
2699 # Send to the static EP
2700 #
2701 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002702 # a packet with an sclass from a known EPG
Neale Rannsc29c0af2018-11-07 04:21:12 -08002703 # arriving on an unknown TEP
2704 p = (Ether(src=self.pg2.remote_mac,
2705 dst=self.pg2.local_mac) /
2706 IP(src=self.pg2.remote_hosts[1].ip4,
2707 dst=self.pg2.local_ip4) /
2708 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002709 VXLAN(vni=99, gpid=441, flags=0x88) /
Neale Rannsc29c0af2018-11-07 04:21:12 -08002710 Ether(src=l['mac'], dst=ep.mac) /
2711 IP(src=l['ip'], dst=ep.ip4.address) /
2712 UDP(sport=1234, dport=1234) /
2713 Raw('\xa5' * 100))
2714
2715 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
2716
2717 #
2718 # packet to EP has the EP's vlan tag
2719 #
2720 for rx in rxs:
2721 self.assertEqual(rx[Dot1Q].vlan, 11)
2722
2723 #
2724 # the EP is not learnt since the BD setting prevents it
2725 # also no TEP too
2726 #
2727 self.assertFalse(find_gbp_endpoint(self,
2728 vx_tun_l2_1.sw_if_index,
2729 mac=l['mac']))
2730 self.assertEqual(INDEX_INVALID,
2731 find_vxlan_gbp_tunnel(
2732 self,
2733 self.pg2.local_ip4,
2734 self.pg2.remote_hosts[1].ip4,
2735 99))
2736
2737 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
2738
2739 #
2740 # static to remotes
2741 # we didn't learn the remotes so they are sent to the UU-fwd
2742 #
2743 for l in learnt:
2744 p = (Ether(src=ep.mac, dst=l['mac']) /
2745 Dot1Q(vlan=11) /
2746 IP(dst=l['ip'], src=ep.ip4.address) /
2747 UDP(sport=1234, dport=1234) /
2748 Raw('\xa5' * 100))
2749
2750 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
2751
2752 for rx in rxs:
2753 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
2754 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
2755 self.assertEqual(rx[UDP].dport, 48879)
2756 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002757 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Rannsc29c0af2018-11-07 04:21:12 -08002758 self.assertEqual(rx[VXLAN].vni, 116)
2759 self.assertTrue(rx[VXLAN].flags.G)
2760 self.assertTrue(rx[VXLAN].flags.Instance)
2761 self.assertFalse(rx[VXLAN].gpflags.A)
2762 self.assertFalse(rx[VXLAN].gpflags.D)
2763
2764 self.pg2.unconfig_ip4()
2765 self.pg3.unconfig_ip4()
2766
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002767 def test_gbp_learn_l3(self):
2768 """ GBP L3 Endpoint Learning """
2769
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04002770 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08002771
Neale Rannsb6a47952018-11-21 05:44:35 -08002772 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002773 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2774 routed_src_mac = "00:22:bd:f8:19:ff"
2775
2776 learnt = [{'mac': '00:00:11:11:11:02',
2777 'ip': '10.0.1.2',
2778 'ip6': '2001:10::2'},
2779 {'mac': '00:00:11:11:11:03',
2780 'ip': '10.0.1.3',
2781 'ip6': '2001:10::3'}]
2782
2783 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002784 # IP tables
2785 #
2786 t4 = VppIpTable(self, 1)
2787 t4.add_vpp_config()
2788 t6 = VppIpTable(self, 1, True)
2789 t6.add_vpp_config()
2790
2791 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2792 self.pg4.remote_ip4, 114)
2793 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2794 self.pg4.remote_ip4, 116)
2795 tun_ip4_uu.add_vpp_config()
2796 tun_ip6_uu.add_vpp_config()
2797
Neale Ranns160c9232019-06-19 06:25:56 -07002798 rd1 = VppGbpRouteDomain(self, 2, 401, t4, t6, tun_ip4_uu, tun_ip6_uu)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002799 rd1.add_vpp_config()
2800
Ole Troan8006c6a2018-12-17 12:02:26 +01002801 self.loop0.set_mac(self.router_mac)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002802
2803 #
2804 # Bind the BVI to the RD
2805 #
2806 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2807 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2808
2809 #
2810 # Pg2 hosts the vxlan tunnel
2811 # hosts on pg2 to act as TEPs
2812 # pg3 is BD uu-fwd
2813 # pg4 is RD uu-fwd
2814 #
2815 self.pg2.config_ip4()
2816 self.pg2.resolve_arp()
2817 self.pg2.generate_remote_hosts(4)
2818 self.pg2.configure_ipv4_neighbors()
2819 self.pg3.config_ip4()
2820 self.pg3.resolve_arp()
2821 self.pg4.config_ip4()
2822 self.pg4.resolve_arp()
2823
2824 #
2825 # a GBP bridge domain with a BVI and a UU-flood interface
2826 #
2827 bd1 = VppBridgeDomain(self, 1)
2828 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07002829 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, self.pg3)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002830 gbd1.add_vpp_config()
2831
2832 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2833 self.logger.info(self.vapi.cli("sh gbp bridge"))
2834 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002835
2836 # ... and has a /32 and /128 applied
2837 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2838 ip4_addr.add_vpp_config()
2839 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2840 ip6_addr.add_vpp_config()
2841
2842 #
2843 # The Endpoint-group in which we are learning endpoints
2844 #
Neale Ranns879d11c2019-01-21 23:34:18 -08002845 epg_220 = VppGbpEndpointGroup(self, 220, 441, rd1, gbd1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002846 None, self.loop0,
2847 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08002848 "2001:10::128",
2849 VppGbpEndpointRetention(2))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002850 epg_220.add_vpp_config()
2851
2852 #
Neale Ranns69a85b52019-06-14 07:49:50 +00002853 # The VXLAN GBP tunnel is in L3 mode with learning enabled
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002854 #
2855 vx_tun_l3 = VppGbpVxlanTunnel(
2856 self, 101, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08002857 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
2858 self.pg2.local_ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002859 vx_tun_l3.add_vpp_config()
2860
2861 #
2862 # A static endpoint that the learnt endpoints are trying to
2863 # talk to
2864 #
2865 ep = VppGbpEndpoint(self, self.pg0,
2866 epg_220, None,
2867 "10.0.0.127", "11.0.0.127",
2868 "2001:10::1", "3001::1")
2869 ep.add_vpp_config()
2870
2871 #
2872 # learn some remote IPv4 EPs
2873 #
2874 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002875 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002876 # arriving on an unknown TEP
2877 p = (Ether(src=self.pg2.remote_mac,
2878 dst=self.pg2.local_mac) /
2879 IP(src=self.pg2.remote_hosts[1].ip4,
2880 dst=self.pg2.local_ip4) /
2881 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002882 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002883 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2884 IP(src=l['ip'], dst=ep.ip4.address) /
2885 UDP(sport=1234, dport=1234) /
2886 Raw('\xa5' * 100))
2887
2888 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2889
2890 # the new TEP
2891 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2892 self,
2893 self.pg2.local_ip4,
2894 self.pg2.remote_hosts[1].ip4,
2895 vx_tun_l3.vni)
2896 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2897
2898 # endpoint learnt via the parent GBP-vxlan interface
2899 self.assertTrue(find_gbp_endpoint(self,
2900 vx_tun_l3._sw_if_index,
2901 ip=l['ip']))
2902
2903 #
2904 # Static IPv4 EP replies to learnt
2905 #
2906 for l in learnt:
2907 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2908 IP(dst=l['ip'], src=ep.ip4.address) /
2909 UDP(sport=1234, dport=1234) /
2910 Raw('\xa5' * 100))
2911
Filip Vargaf4749ca2019-04-25 14:55:32 +02002912 rxs = self.send_and_expect(self.pg0, p * 1, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002913
2914 for rx in rxs:
2915 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2916 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2917 self.assertEqual(rx[UDP].dport, 48879)
2918 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002919 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002920 self.assertEqual(rx[VXLAN].vni, 101)
2921 self.assertTrue(rx[VXLAN].flags.G)
2922 self.assertTrue(rx[VXLAN].flags.Instance)
2923 self.assertTrue(rx[VXLAN].gpflags.A)
2924 self.assertFalse(rx[VXLAN].gpflags.D)
2925
2926 inner = rx[VXLAN].payload
2927
2928 self.assertEqual(inner[Ether].src, routed_src_mac)
2929 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2930 self.assertEqual(inner[IP].src, ep.ip4.address)
2931 self.assertEqual(inner[IP].dst, l['ip'])
2932
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002933 for l in learnt:
2934 self.assertFalse(find_gbp_endpoint(self,
2935 tep1_sw_if_index,
2936 ip=l['ip']))
2937
2938 #
2939 # learn some remote IPv6 EPs
2940 #
2941 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002942 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002943 # arriving on an unknown TEP
2944 p = (Ether(src=self.pg2.remote_mac,
2945 dst=self.pg2.local_mac) /
2946 IP(src=self.pg2.remote_hosts[1].ip4,
2947 dst=self.pg2.local_ip4) /
2948 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08002949 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002950 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2951 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2952 UDP(sport=1234, dport=1234) /
2953 Raw('\xa5' * 100))
2954
2955 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2956
2957 # the new TEP
2958 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2959 self,
2960 self.pg2.local_ip4,
2961 self.pg2.remote_hosts[1].ip4,
2962 vx_tun_l3.vni)
2963 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2964
2965 self.logger.info(self.vapi.cli("show gbp bridge"))
2966 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2967 self.logger.info(self.vapi.cli("show gbp vxlan"))
2968 self.logger.info(self.vapi.cli("show int addr"))
2969
2970 # endpoint learnt via the TEP
2971 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2972
2973 self.logger.info(self.vapi.cli("show gbp endpoint"))
2974 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2975
2976 #
2977 # Static EP replies to learnt
2978 #
2979 for l in learnt:
2980 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2981 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2982 UDP(sport=1234, dport=1234) /
2983 Raw('\xa5' * 100))
2984
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002985 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002986
2987 for rx in rxs:
2988 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2989 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2990 self.assertEqual(rx[UDP].dport, 48879)
2991 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08002992 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002993 self.assertEqual(rx[VXLAN].vni, 101)
2994 self.assertTrue(rx[VXLAN].flags.G)
2995 self.assertTrue(rx[VXLAN].flags.Instance)
2996 self.assertTrue(rx[VXLAN].gpflags.A)
2997 self.assertFalse(rx[VXLAN].gpflags.D)
2998
2999 inner = rx[VXLAN].payload
3000
3001 self.assertEqual(inner[Ether].src, routed_src_mac)
3002 self.assertEqual(inner[Ether].dst, routed_dst_mac)
3003 self.assertEqual(inner[IPv6].src, ep.ip6.address)
3004 self.assertEqual(inner[IPv6].dst, l['ip6'])
3005
3006 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003007 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00003008 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003009
3010 #
3011 # Static sends to unknown EP with no route
3012 #
3013 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3014 IP(dst="10.0.0.99", src=ep.ip4.address) /
3015 UDP(sport=1234, dport=1234) /
3016 Raw('\xa5' * 100))
3017
3018 self.send_and_assert_no_replies(self.pg0, [p])
3019
3020 #
3021 # Add a route to static EP's v4 and v6 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003022 #
3023 se_10_24 = VppGbpSubnet(
3024 self, rd1, "10.0.0.0", 24,
3025 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
3026 se_10_24.add_vpp_config()
3027
Neale Ranns69a85b52019-06-14 07:49:50 +00003028 #
3029 # static pings router
3030 #
3031 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3032 IP(dst=epg_220.bvi_ip4.address, src=ep.ip4.address) /
3033 UDP(sport=1234, dport=1234) /
3034 Raw('\xa5' * 100))
3035
3036 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
3037
3038 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3039 IPv6(dst=epg_220.bvi_ip6.address, src=ep.ip6.address) /
3040 UDP(sport=1234, dport=1234) /
3041 Raw('\xa5' * 100))
3042
3043 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
3044
3045 #
3046 # packets to address in the subnet are sent on the uu-fwd
3047 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003048 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3049 IP(dst="10.0.0.99", src=ep.ip4.address) /
3050 UDP(sport=1234, dport=1234) /
3051 Raw('\xa5' * 100))
3052
3053 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
3054 for rx in rxs:
3055 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
3056 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
3057 self.assertEqual(rx[UDP].dport, 48879)
3058 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003059 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003060 self.assertEqual(rx[VXLAN].vni, 114)
3061 self.assertTrue(rx[VXLAN].flags.G)
3062 self.assertTrue(rx[VXLAN].flags.Instance)
3063 # policy is not applied to packets sent to the uu-fwd interfaces
3064 self.assertFalse(rx[VXLAN].gpflags.A)
3065 self.assertFalse(rx[VXLAN].gpflags.D)
3066
3067 #
3068 # learn some remote IPv4 EPs
3069 #
3070 for ii, l in enumerate(learnt):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003071 # a packet with an sclass from a known EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003072 # arriving on an unknown TEP
3073 p = (Ether(src=self.pg2.remote_mac,
3074 dst=self.pg2.local_mac) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003075 IP(src=self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003076 dst=self.pg2.local_ip4) /
3077 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003078 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003079 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3080 IP(src=l['ip'], dst=ep.ip4.address) /
3081 UDP(sport=1234, dport=1234) /
3082 Raw('\xa5' * 100))
3083
3084 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3085
3086 # the new TEP
3087 tep1_sw_if_index = find_vxlan_gbp_tunnel(
3088 self,
3089 self.pg2.local_ip4,
Neale Ranns879d11c2019-01-21 23:34:18 -08003090 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003091 vx_tun_l3.vni)
3092 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
3093
3094 # endpoint learnt via the parent GBP-vxlan interface
3095 self.assertTrue(find_gbp_endpoint(self,
3096 vx_tun_l3._sw_if_index,
3097 ip=l['ip']))
3098
3099 #
3100 # Add a remote endpoint from the API
3101 #
3102 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
3103 epg_220, None,
3104 "10.0.0.88", "11.0.0.88",
3105 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08003106 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003107 self.pg2.local_ip4,
Neale Ranns3eea9de2019-06-21 02:09:25 -07003108 self.pg2.remote_hosts[2].ip4,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003109 mac=None)
3110 rep_88.add_vpp_config()
3111
3112 #
3113 # Add a remote endpoint from the API that matches an existing one
Neale Ranns3eea9de2019-06-21 02:09:25 -07003114 # this is a lower priority, hence the packet is sent to the DP leanrt
3115 # TEP
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003116 #
3117 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
3118 epg_220, None,
3119 learnt[0]['ip'], "11.0.0.101",
3120 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08003121 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003122 self.pg2.local_ip4,
3123 self.pg2.remote_hosts[1].ip4,
3124 mac=None)
3125 rep_2.add_vpp_config()
3126
3127 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003128 # Add a route to the learned EP's v4 subnet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003129 # packets should be send on the v4/v6 uu=fwd interface resp.
3130 #
3131 se_10_1_24 = VppGbpSubnet(
3132 self, rd1, "10.0.1.0", 24,
3133 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
3134 se_10_1_24.add_vpp_config()
3135
3136 self.logger.info(self.vapi.cli("show gbp endpoint"))
3137
3138 ips = ["10.0.0.88", learnt[0]['ip']]
3139 for ip in ips:
3140 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3141 IP(dst=ip, src=ep.ip4.address) /
3142 UDP(sport=1234, dport=1234) /
3143 Raw('\xa5' * 100))
3144
Paul Vinciguerra4271c972019-05-14 13:25:49 -04003145 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003146
3147 for rx in rxs:
3148 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
Neale Ranns3eea9de2019-06-21 02:09:25 -07003149 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003150 self.assertEqual(rx[UDP].dport, 48879)
3151 # the UDP source port is a random value for hashing
Neale Ranns879d11c2019-01-21 23:34:18 -08003152 self.assertEqual(rx[VXLAN].gpid, 441)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003153 self.assertEqual(rx[VXLAN].vni, 101)
3154 self.assertTrue(rx[VXLAN].flags.G)
3155 self.assertTrue(rx[VXLAN].flags.Instance)
3156 self.assertTrue(rx[VXLAN].gpflags.A)
3157 self.assertFalse(rx[VXLAN].gpflags.D)
3158
3159 inner = rx[VXLAN].payload
3160
3161 self.assertEqual(inner[Ether].src, routed_src_mac)
3162 self.assertEqual(inner[Ether].dst, routed_dst_mac)
3163 self.assertEqual(inner[IP].src, ep.ip4.address)
3164 self.assertEqual(inner[IP].dst, ip)
3165
3166 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003167 # remove the API remote EPs, only API sourced is gone, the DP
3168 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003169 #
3170 rep_88.remove_vpp_config()
3171 rep_2.remove_vpp_config()
3172
Neale Ranns00a469d2018-12-20 06:12:19 -08003173 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
3174
3175 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3176 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
3177 UDP(sport=1234, dport=1234) /
3178 Raw('\xa5' * 100))
3179 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003180
Neale Ranns13a08cc2018-11-07 09:25:54 -08003181 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003182
Neale Ranns13a08cc2018-11-07 09:25:54 -08003183 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3184 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
3185 UDP(sport=1234, dport=1234) /
3186 Raw('\xa5' * 100))
3187 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003188
Neale Ranns13a08cc2018-11-07 09:25:54 -08003189 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003190 # to appease the testcase we cannot have the registered EP still
Neale Ranns13a08cc2018-11-07 09:25:54 -08003191 # present (because it's DP learnt) when the TC ends so wait until
3192 # it is removed
3193 #
Neale Ranns00a469d2018-12-20 06:12:19 -08003194 self.wait_for_ep_timeout(ip=rep_88.ip4.address)
3195 self.wait_for_ep_timeout(ip=rep_2.ip4.address)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003196
3197 #
Neale Ranns3eea9de2019-06-21 02:09:25 -07003198 # Same as above, learn a remote EP via CP and DP
3199 # this time remove the DP one first. expect the CP data to remain
3200 #
3201 rep_3 = VppGbpEndpoint(self, vx_tun_l3,
3202 epg_220, None,
3203 "10.0.1.4", "11.0.0.103",
3204 "2001::10:3", "3001::103",
3205 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3206 self.pg2.local_ip4,
3207 self.pg2.remote_hosts[1].ip4,
3208 mac=None)
3209 rep_3.add_vpp_config()
3210
3211 p = (Ether(src=self.pg2.remote_mac,
3212 dst=self.pg2.local_mac) /
3213 IP(src=self.pg2.remote_hosts[2].ip4,
3214 dst=self.pg2.local_ip4) /
3215 UDP(sport=1234, dport=48879) /
3216 VXLAN(vni=101, gpid=441, flags=0x88) /
3217 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3218 IP(src="10.0.1.4", dst=ep.ip4.address) /
3219 UDP(sport=1234, dport=1234) /
3220 Raw('\xa5' * 100))
3221 rxs = self.send_and_expect(self.pg2, p * NUM_PKTS, self.pg0)
3222
3223 self.assertTrue(find_gbp_endpoint(self,
3224 vx_tun_l3._sw_if_index,
3225 ip=rep_3.ip4.address,
3226 tep=[self.pg2.local_ip4,
3227 self.pg2.remote_hosts[2].ip4]))
3228
3229 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
3230 IP(dst="10.0.1.4", src=ep.ip4.address) /
3231 UDP(sport=1234, dport=1234) /
3232 Raw('\xa5' * 100))
3233 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3234
3235 # host 2 is the DP learned TEP
3236 for rx in rxs:
3237 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3238 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[2].ip4)
3239
3240 self.wait_for_ep_timeout(ip=rep_3.ip4.address,
3241 tep=[self.pg2.local_ip4,
3242 self.pg2.remote_hosts[2].ip4])
3243
3244 rxs = self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg2)
3245
3246 # host 1 is the CP learned TEP
3247 for rx in rxs:
3248 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
3249 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
3250
3251 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003252 # shutdown with learnt endpoint present
3253 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003254 p = (Ether(src=self.pg2.remote_mac,
3255 dst=self.pg2.local_mac) /
3256 IP(src=self.pg2.remote_hosts[1].ip4,
3257 dst=self.pg2.local_ip4) /
3258 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003259 VXLAN(vni=101, gpid=441, flags=0x88) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003260 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
3261 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
3262 UDP(sport=1234, dport=1234) /
3263 Raw('\xa5' * 100))
3264
3265 rx = self.send_and_expect(self.pg2, [p], self.pg0)
3266
3267 # endpoint learnt via the parent GBP-vxlan interface
3268 self.assertTrue(find_gbp_endpoint(self,
3269 vx_tun_l3._sw_if_index,
3270 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07003271
3272 #
3273 # TODO
3274 # remote endpoint becomes local
3275 #
3276 self.pg2.unconfig_ip4()
3277 self.pg3.unconfig_ip4()
3278 self.pg4.unconfig_ip4()
3279
Neale Ranns13a08cc2018-11-07 09:25:54 -08003280 def test_gbp_redirect(self):
3281 """ GBP Endpoint Redirect """
3282
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04003283 self.vapi.cli("set logging class gbp level debug")
Neale Ranns13a08cc2018-11-07 09:25:54 -08003284
Neale Rannsb6a47952018-11-21 05:44:35 -08003285 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08003286 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3287 routed_src_mac = "00:22:bd:f8:19:ff"
3288
3289 learnt = [{'mac': '00:00:11:11:11:02',
3290 'ip': '10.0.1.2',
3291 'ip6': '2001:10::2'},
3292 {'mac': '00:00:11:11:11:03',
3293 'ip': '10.0.1.3',
3294 'ip6': '2001:10::3'}]
3295
3296 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003297 # IP tables
3298 #
3299 t4 = VppIpTable(self, 1)
3300 t4.add_vpp_config()
3301 t6 = VppIpTable(self, 1, True)
3302 t6.add_vpp_config()
3303
Neale Ranns160c9232019-06-19 06:25:56 -07003304 rd1 = VppGbpRouteDomain(self, 2, 402, t4, t6)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003305 rd1.add_vpp_config()
3306
Ole Troan8006c6a2018-12-17 12:02:26 +01003307 self.loop0.set_mac(self.router_mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003308
3309 #
3310 # Bind the BVI to the RD
3311 #
3312 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3313 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3314
3315 #
3316 # Pg7 hosts a BD's UU-fwd
3317 #
3318 self.pg7.config_ip4()
3319 self.pg7.resolve_arp()
3320
3321 #
3322 # a GBP bridge domains for the EPs
3323 #
3324 bd1 = VppBridgeDomain(self, 1)
3325 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003326 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003327 gbd1.add_vpp_config()
3328
3329 bd2 = VppBridgeDomain(self, 2)
3330 bd2.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003331 gbd2 = VppGbpBridgeDomain(self, bd2, rd1, self.loop1)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003332 gbd2.add_vpp_config()
3333
3334 # ... and has a /32 and /128 applied
3335 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
3336 ip4_addr.add_vpp_config()
3337 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
3338 ip6_addr.add_vpp_config()
3339 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
3340 ip4_addr.add_vpp_config()
3341 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
3342 ip6_addr.add_vpp_config()
3343
3344 #
3345 # The Endpoint-groups in which we are learning endpoints
3346 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003347 epg_220 = VppGbpEndpointGroup(self, 220, 440, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003348 None, gbd1.bvi,
3349 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003350 "2001:10::128",
3351 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003352 epg_220.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003353 epg_221 = VppGbpEndpointGroup(self, 221, 441, rd1, gbd2,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003354 None, gbd2.bvi,
3355 "10.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003356 "2001:11::128",
3357 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003358 epg_221.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003359 epg_222 = VppGbpEndpointGroup(self, 222, 442, rd1, gbd1,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003360 None, gbd1.bvi,
3361 "10.0.2.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003362 "2001:12::128",
3363 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003364 epg_222.add_vpp_config()
3365
3366 #
3367 # a GBP bridge domains for the SEPs
3368 #
3369 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3370 self.pg7.remote_ip4, 116)
3371 bd_uu1.add_vpp_config()
3372 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3373 self.pg7.remote_ip4, 117)
3374 bd_uu2.add_vpp_config()
3375
3376 bd3 = VppBridgeDomain(self, 3)
3377 bd3.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003378 gbd3 = VppGbpBridgeDomain(self, bd3, rd1, self.loop2,
3379 bd_uu1, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003380 gbd3.add_vpp_config()
3381 bd4 = VppBridgeDomain(self, 4)
3382 bd4.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003383 gbd4 = VppGbpBridgeDomain(self, bd4, rd1, self.loop3,
3384 bd_uu2, learn=False)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003385 gbd4.add_vpp_config()
3386
3387 #
3388 # EPGs in which the service endpoints exist
3389 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003390 epg_320 = VppGbpEndpointGroup(self, 320, 550, rd1, gbd3,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003391 None, gbd1.bvi,
3392 "12.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003393 "4001:10::128",
3394 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003395 epg_320.add_vpp_config()
Neale Ranns879d11c2019-01-21 23:34:18 -08003396 epg_321 = VppGbpEndpointGroup(self, 321, 551, rd1, gbd4,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003397 None, gbd2.bvi,
3398 "12.0.1.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003399 "4001:11::128",
3400 VppGbpEndpointRetention(2))
Neale Ranns13a08cc2018-11-07 09:25:54 -08003401 epg_321.add_vpp_config()
3402
3403 #
3404 # three local endpoints
3405 #
3406 ep1 = VppGbpEndpoint(self, self.pg0,
3407 epg_220, None,
3408 "10.0.0.1", "11.0.0.1",
3409 "2001:10::1", "3001:10::1")
3410 ep1.add_vpp_config()
3411 ep2 = VppGbpEndpoint(self, self.pg1,
3412 epg_221, None,
3413 "10.0.1.1", "11.0.1.1",
3414 "2001:11::1", "3001:11::1")
3415 ep2.add_vpp_config()
3416 ep3 = VppGbpEndpoint(self, self.pg2,
3417 epg_222, None,
3418 "10.0.2.2", "11.0.2.2",
3419 "2001:12::1", "3001:12::1")
3420 ep3.add_vpp_config()
3421
3422 #
3423 # service endpoints
3424 #
3425 sep1 = VppGbpEndpoint(self, self.pg3,
3426 epg_320, None,
3427 "12.0.0.1", "13.0.0.1",
3428 "4001:10::1", "5001:10::1")
3429 sep1.add_vpp_config()
3430 sep2 = VppGbpEndpoint(self, self.pg4,
3431 epg_320, None,
3432 "12.0.0.2", "13.0.0.2",
3433 "4001:10::2", "5001:10::2")
3434 sep2.add_vpp_config()
3435 sep3 = VppGbpEndpoint(self, self.pg5,
3436 epg_321, None,
3437 "12.0.1.1", "13.0.1.1",
3438 "4001:11::1", "5001:11::1")
3439 sep3.add_vpp_config()
3440 # this EP is not installed immediately
3441 sep4 = VppGbpEndpoint(self, self.pg6,
3442 epg_321, None,
3443 "12.0.1.2", "13.0.1.2",
3444 "4001:11::2", "5001:11::2")
3445
3446 #
3447 # an L2 switch packet between local EPs in different EPGs
3448 # different dest ports on each so the are LB hashed differently
3449 #
3450 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
3451 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
3452 UDP(sport=1234, dport=1234) /
3453 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003454 (Ether(src=ep3.mac, dst=ep1.mac) /
3455 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
3456 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003457 Raw('\xa5' * 100))]
3458 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
3459 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
3460 UDP(sport=1234, dport=1234) /
3461 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003462 (Ether(src=ep3.mac, dst=ep1.mac) /
3463 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003464 UDP(sport=1234, dport=1230) /
3465 Raw('\xa5' * 100))]
3466
3467 # should be dropped since no contract yet
3468 self.send_and_assert_no_replies(self.pg0, [p4[0]])
3469 self.send_and_assert_no_replies(self.pg0, [p6[0]])
3470
3471 #
3472 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
3473 # one of the next-hops is via an EP that is not known
3474 #
3475 acl = VppGbpAcl(self)
3476 rule4 = acl.create_rule(permit_deny=1, proto=17)
3477 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3478 acl_index = acl.add_vpp_config([rule4, rule6])
3479
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003480 #
3481 # test the src-ip hash mode
3482 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08003483 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003484 self, 402, epg_220.sclass, epg_222.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003485 [VppGbpContractRule(
3486 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003487 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003488 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3489 sep1.ip4, sep1.epg.rd),
3490 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3491 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003492 VppGbpContractRule(
3493 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3494 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3495 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3496 sep3.ip6, sep3.epg.rd),
3497 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3498 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003499 [ETH_P_IP, ETH_P_IPV6])
Neale Ranns13a08cc2018-11-07 09:25:54 -08003500 c1.add_vpp_config()
3501
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003502 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003503 self, 402, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003504 [VppGbpContractRule(
3505 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3506 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3507 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3508 sep1.ip4, sep1.epg.rd),
3509 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3510 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003511 VppGbpContractRule(
3512 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3513 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
3514 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3515 sep3.ip6, sep3.epg.rd),
3516 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3517 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003518 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003519 c2.add_vpp_config()
3520
Neale Ranns13a08cc2018-11-07 09:25:54 -08003521 #
3522 # send again with the contract preset, now packets arrive
3523 # at SEP1 or SEP2 depending on the hashing
3524 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003525 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003526
3527 for rx in rxs:
3528 self.assertEqual(rx[Ether].src, routed_src_mac)
3529 self.assertEqual(rx[Ether].dst, sep1.mac)
3530 self.assertEqual(rx[IP].src, ep1.ip4.address)
3531 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3532
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003533 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
3534
3535 for rx in rxs:
3536 self.assertEqual(rx[Ether].src, routed_src_mac)
3537 self.assertEqual(rx[Ether].dst, sep2.mac)
3538 self.assertEqual(rx[IP].src, ep3.ip4.address)
3539 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3540
Neale Ranns13a08cc2018-11-07 09:25:54 -08003541 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3542
3543 for rx in rxs:
3544 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3545 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3546 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3547 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3548 self.assertEqual(rx[VXLAN].vni, 117)
3549 self.assertTrue(rx[VXLAN].flags.G)
3550 self.assertTrue(rx[VXLAN].flags.Instance)
3551 # redirect policy has been applied
3552 self.assertTrue(rx[VXLAN].gpflags.A)
3553 self.assertFalse(rx[VXLAN].gpflags.D)
3554
3555 inner = rx[VXLAN].payload
3556
3557 self.assertEqual(inner[Ether].src, routed_src_mac)
3558 self.assertEqual(inner[Ether].dst, sep4.mac)
3559 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
3560 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
3561
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003562 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003563
3564 for rx in rxs:
3565 self.assertEqual(rx[Ether].src, routed_src_mac)
3566 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003567 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
3568 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003569
3570 #
3571 # programme the unknown EP
3572 #
3573 sep4.add_vpp_config()
3574
3575 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3576
3577 for rx in rxs:
3578 self.assertEqual(rx[Ether].src, routed_src_mac)
3579 self.assertEqual(rx[Ether].dst, sep4.mac)
3580 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3581 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
3582
3583 #
3584 # and revert back to unprogrammed
3585 #
3586 sep4.remove_vpp_config()
3587
3588 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
3589
3590 for rx in rxs:
3591 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3592 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3593 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3594 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3595 self.assertEqual(rx[VXLAN].vni, 117)
3596 self.assertTrue(rx[VXLAN].flags.G)
3597 self.assertTrue(rx[VXLAN].flags.Instance)
3598 # redirect policy has been applied
3599 self.assertTrue(rx[VXLAN].gpflags.A)
3600 self.assertFalse(rx[VXLAN].gpflags.D)
3601
3602 inner = rx[VXLAN].payload
3603
3604 self.assertEqual(inner[Ether].src, routed_src_mac)
3605 self.assertEqual(inner[Ether].dst, sep4.mac)
3606 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
3607 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
3608
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003609 c1.remove_vpp_config()
3610 c2.remove_vpp_config()
3611
3612 #
3613 # test the symmetric hash mode
3614 #
3615 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003616 self, 402, epg_220.sclass, epg_222.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003617 [VppGbpContractRule(
3618 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3619 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3620 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3621 sep1.ip4, sep1.epg.rd),
3622 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3623 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003624 VppGbpContractRule(
3625 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3626 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3627 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3628 sep3.ip6, sep3.epg.rd),
3629 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3630 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003631 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003632 c1.add_vpp_config()
3633
3634 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003635 self, 402, epg_222.sclass, epg_220.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003636 [VppGbpContractRule(
3637 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3638 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3639 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3640 sep1.ip4, sep1.epg.rd),
3641 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3642 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003643 VppGbpContractRule(
3644 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3645 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3646 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3647 sep3.ip6, sep3.epg.rd),
3648 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3649 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003650 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003651 c2.add_vpp_config()
3652
3653 #
3654 # send again with the contract preset, now packets arrive
3655 # at SEP1 for both directions
3656 #
3657 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3658
3659 for rx in rxs:
3660 self.assertEqual(rx[Ether].src, routed_src_mac)
3661 self.assertEqual(rx[Ether].dst, sep1.mac)
3662 self.assertEqual(rx[IP].src, ep1.ip4.address)
3663 self.assertEqual(rx[IP].dst, ep3.ip4.address)
3664
3665 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
3666
3667 for rx in rxs:
3668 self.assertEqual(rx[Ether].src, routed_src_mac)
3669 self.assertEqual(rx[Ether].dst, sep1.mac)
3670 self.assertEqual(rx[IP].src, ep3.ip4.address)
3671 self.assertEqual(rx[IP].dst, ep1.ip4.address)
3672
Neale Ranns13a08cc2018-11-07 09:25:54 -08003673 #
3674 # programme the unknown EP for the L3 tests
3675 #
3676 sep4.add_vpp_config()
3677
3678 #
3679 # an L3 switch packet between local EPs in different EPGs
3680 # different dest ports on each so the are LB hashed differently
3681 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003682 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003683 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
3684 UDP(sport=1234, dport=1234) /
3685 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003686 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003687 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
3688 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003689 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003690 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003691 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
3692 UDP(sport=1234, dport=1234) /
3693 Raw('\xa5' * 100)),
Ole Troan8006c6a2018-12-17 12:02:26 +01003694 (Ether(src=ep2.mac, dst=str(self.router_mac)) /
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003695 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
3696 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003697 Raw('\xa5' * 100))]
3698
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003699 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003700 self, 402, epg_220.sclass, epg_221.sclass, acl_index,
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003701 [VppGbpContractRule(
3702 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3703 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3704 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3705 sep1.ip4, sep1.epg.rd),
3706 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3707 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003708 VppGbpContractRule(
3709 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3710 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
3711 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3712 sep3.ip6, sep3.epg.rd),
3713 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3714 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003715 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003716 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003717
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003718 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003719
3720 for rx in rxs:
3721 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003722 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003723 self.assertEqual(rx[IP].src, ep1.ip4.address)
3724 self.assertEqual(rx[IP].dst, ep2.ip4.address)
3725
3726 #
3727 # learn a remote EP in EPG 221
3728 #
3729 vx_tun_l3 = VppGbpVxlanTunnel(
3730 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003731 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3732 self.pg2.local_ip4)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003733 vx_tun_l3.add_vpp_config()
3734
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003735 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003736 self, 402, epg_221.sclass, epg_220.sclass, acl_index,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003737 [VppGbpContractRule(
3738 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003739 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08003740 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003741 VppGbpContractRule(
3742 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04003743 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02003744 [])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003745 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003746 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08003747
3748 p = (Ether(src=self.pg7.remote_mac,
3749 dst=self.pg7.local_mac) /
3750 IP(src=self.pg7.remote_ip4,
3751 dst=self.pg7.local_ip4) /
3752 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003753 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003754 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003755 IP(src="10.0.0.88", dst=ep1.ip4.address) /
3756 UDP(sport=1234, dport=1234) /
3757 Raw('\xa5' * 100))
3758
3759 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3760
3761 # endpoint learnt via the parent GBP-vxlan interface
3762 self.assertTrue(find_gbp_endpoint(self,
3763 vx_tun_l3._sw_if_index,
3764 ip="10.0.0.88"))
3765
3766 p = (Ether(src=self.pg7.remote_mac,
3767 dst=self.pg7.local_mac) /
3768 IP(src=self.pg7.remote_ip4,
3769 dst=self.pg7.local_ip4) /
3770 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08003771 VXLAN(vni=444, gpid=441, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01003772 Ether(src="00:22:22:22:22:33", dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003773 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
3774 UDP(sport=1234, dport=1234) /
3775 Raw('\xa5' * 100))
3776
3777 rx = self.send_and_expect(self.pg7, [p], self.pg0)
3778
3779 # endpoint learnt via the parent GBP-vxlan interface
3780 self.assertTrue(find_gbp_endpoint(self,
3781 vx_tun_l3._sw_if_index,
3782 ip="2001:10::88"))
3783
3784 #
3785 # L3 switch from local to remote EP
3786 #
Ole Troan8006c6a2018-12-17 12:02:26 +01003787 p4 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003788 IP(src=ep1.ip4.address, dst="10.0.0.88") /
3789 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003790 Raw('\xa5' * 100))]
Ole Troan8006c6a2018-12-17 12:02:26 +01003791 p6 = [(Ether(src=ep1.mac, dst=str(self.router_mac)) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003792 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
3793 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08003794 Raw('\xa5' * 100))]
3795
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003796 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003797
3798 for rx in rxs:
3799 self.assertEqual(rx[Ether].src, routed_src_mac)
3800 self.assertEqual(rx[Ether].dst, sep1.mac)
3801 self.assertEqual(rx[IP].src, ep1.ip4.address)
3802 self.assertEqual(rx[IP].dst, "10.0.0.88")
3803
3804 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
3805
3806 for rx in rxs:
3807 self.assertEqual(rx[Ether].src, routed_src_mac)
3808 self.assertEqual(rx[Ether].dst, sep4.mac)
3809 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3810 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3811
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003812 #
3813 # test the dst-ip hash mode
3814 #
3815 c5 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07003816 self, 402, epg_220.sclass, epg_221.sclass, acl_index,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003817 [VppGbpContractRule(
3818 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3819 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3820 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
3821 sep1.ip4, sep1.epg.rd),
3822 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
3823 sep2.ip4, sep2.epg.rd)]),
Filip Vargaf4749ca2019-04-25 14:55:32 +02003824 VppGbpContractRule(
3825 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
3826 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
3827 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
3828 sep3.ip6, sep3.epg.rd),
3829 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
3830 sep4.ip6, sep4.epg.rd)])],
Neale Ranns1c17e2e2018-12-20 12:03:59 -08003831 [ETH_P_IP, ETH_P_IPV6])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01003832 c5.add_vpp_config()
3833
3834 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
3835
3836 for rx in rxs:
3837 self.assertEqual(rx[Ether].src, routed_src_mac)
3838 self.assertEqual(rx[Ether].dst, sep1.mac)
3839 self.assertEqual(rx[IP].src, ep1.ip4.address)
3840 self.assertEqual(rx[IP].dst, "10.0.0.88")
3841
3842 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08003843
3844 for rx in rxs:
3845 self.assertEqual(rx[Ether].src, routed_src_mac)
3846 self.assertEqual(rx[Ether].dst, sep3.mac)
3847 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
3848 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3849
Neale Rannsb6a47952018-11-21 05:44:35 -08003850 #
3851 # cleanup
3852 #
3853 self.pg7.unconfig_ip4()
3854
3855 def test_gbp_l3_out(self):
3856 """ GBP L3 Out """
3857
3858 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Paul Vinciguerra9673e3e2019-05-10 20:41:08 -04003859 self.vapi.cli("set logging class gbp level debug")
Neale Rannsb6a47952018-11-21 05:44:35 -08003860
3861 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3862 routed_src_mac = "00:22:bd:f8:19:ff"
3863
3864 #
3865 # IP tables
3866 #
3867 t4 = VppIpTable(self, 1)
3868 t4.add_vpp_config()
3869 t6 = VppIpTable(self, 1, True)
3870 t6.add_vpp_config()
3871
Neale Ranns160c9232019-06-19 06:25:56 -07003872 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
Neale Rannsb6a47952018-11-21 05:44:35 -08003873 rd1.add_vpp_config()
3874
Ole Troan8006c6a2018-12-17 12:02:26 +01003875 self.loop0.set_mac(self.router_mac)
Neale Rannsb6a47952018-11-21 05:44:35 -08003876
3877 #
3878 # Bind the BVI to the RD
3879 #
3880 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3881 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3882
3883 #
3884 # Pg7 hosts a BD's BUM
3885 # Pg1 some other l3 interface
3886 #
3887 self.pg7.config_ip4()
3888 self.pg7.resolve_arp()
3889
3890 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003891 # a multicast vxlan-gbp tunnel for broadcast in the BD
3892 #
3893 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3894 "239.1.1.1", 88,
3895 mcast_itf=self.pg7)
3896 tun_bm.add_vpp_config()
3897
3898 #
Neale Rannsb6a47952018-11-21 05:44:35 -08003899 # a GBP external bridge domains for the EPs
3900 #
3901 bd1 = VppBridgeDomain(self, 1)
3902 bd1.add_vpp_config()
Neale Ranns160c9232019-06-19 06:25:56 -07003903 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, tun_bm)
Neale Rannsb6a47952018-11-21 05:44:35 -08003904 gbd1.add_vpp_config()
3905
3906 #
3907 # The Endpoint-groups in which the external endpoints exist
3908 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003909 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
Neale Rannsb6a47952018-11-21 05:44:35 -08003910 None, gbd1.bvi,
3911 "10.0.0.128",
Neale Ranns32f6d8e2019-03-05 04:22:08 -08003912 "2001:10::128",
3913 VppGbpEndpointRetention(2))
Neale Rannsb6a47952018-11-21 05:44:35 -08003914 epg_220.add_vpp_config()
3915
3916 # the BVIs have the subnets applied ...
3917 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3918 ip4_addr.add_vpp_config()
3919 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3920 ip6_addr.add_vpp_config()
3921
3922 # ... which are L3-out subnets
3923 l3o_1 = VppGbpSubnet(
3924 self, rd1, "10.0.0.0", 24,
3925 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003926 sclass=113)
Neale Rannsb6a47952018-11-21 05:44:35 -08003927 l3o_1.add_vpp_config()
3928
3929 #
3930 # an external interface attached to the outside world and the
3931 # external BD
3932 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003933 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
3934 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
Neale Ranns69a85b52019-06-14 07:49:50 +00003935 vlan_144 = VppDot1QSubint(self, self.pg0, 144)
3936 vlan_144.admin_up()
Benoît Ganne286921e2019-06-05 19:08:40 +02003937 # vlan_102 is not poped
Neale Ranns36abbf12019-03-12 02:34:07 -07003938
Neale Rannsb6a47952018-11-21 05:44:35 -08003939 #
Neale Ranns879d11c2019-01-21 23:34:18 -08003940 # an unicast vxlan-gbp for inter-RD traffic
Neale Rannsb6a47952018-11-21 05:44:35 -08003941 #
3942 vx_tun_l3 = VppGbpVxlanTunnel(
3943 self, 444, rd1.rd_id,
Neale Ranns8da9fc62019-03-04 14:08:11 -08003944 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
3945 self.pg2.local_ip4)
Neale Rannsb6a47952018-11-21 05:44:35 -08003946 vx_tun_l3.add_vpp_config()
3947
3948 #
Neale Ranns36abbf12019-03-12 02:34:07 -07003949 # External Endpoints
3950 #
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003951 eep1 = VppGbpEndpoint(self, self.vlan_100,
Neale Ranns36abbf12019-03-12 02:34:07 -07003952 epg_220, None,
3953 "10.0.0.1", "11.0.0.1",
3954 "2001:10::1", "3001::1",
3955 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3956 eep1.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003957 eep2 = VppGbpEndpoint(self, self.vlan_101,
Neale Ranns36abbf12019-03-12 02:34:07 -07003958 epg_220, None,
3959 "10.0.0.2", "11.0.0.2",
3960 "2001:10::2", "3001::2",
3961 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3962 eep2.add_vpp_config()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003963 eep3 = VppGbpEndpoint(self, self.vlan_102,
Benoît Ganne286921e2019-06-05 19:08:40 +02003964 epg_220, None,
3965 "10.0.0.3", "11.0.0.3",
3966 "2001:10::3", "3001::3",
3967 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3968 eep3.add_vpp_config()
Neale Ranns36abbf12019-03-12 02:34:07 -07003969
3970 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07003971 # A remote external endpoint
Neale Ranns36abbf12019-03-12 02:34:07 -07003972 #
3973 rep = VppGbpEndpoint(self, vx_tun_l3,
3974 epg_220, None,
3975 "10.0.0.101", "11.0.0.101",
3976 "2001:10::101", "3001::101",
3977 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3978 self.pg7.local_ip4,
3979 self.pg7.remote_ip4,
3980 mac=None)
3981 rep.add_vpp_config()
3982
3983 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02003984 # EP1 impersonating EP3 is dropped
3985 #
3986 p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3987 Dot1Q(vlan=100) /
3988 ARP(op="who-has",
Benoît Ganneba6abfa2019-07-01 17:10:41 +02003989 psrc="10.0.0.3", pdst="10.0.0.128",
3990 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Gannec47b97d2019-06-06 17:53:21 +02003991 self.send_and_assert_no_replies(self.pg0, p)
3992
3993 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003994 # ARP packet from External EPs are accepted and replied to
Neale Ranns4c2bff02019-03-14 02:52:27 -07003995 #
3996 p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") /
3997 Dot1Q(vlan=100) /
3998 ARP(op="who-has",
3999 psrc=eep1.ip4.address, pdst="10.0.0.128",
4000 hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff"))
4001 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
4002
4003 #
Benoît Ganne286921e2019-06-05 19:08:40 +02004004 # ARP packet from host in remote subnet are accepted and replied to
4005 #
Benoît Gannec47b97d2019-06-06 17:53:21 +02004006 p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") /
Benoît Ganne286921e2019-06-05 19:08:40 +02004007 Dot1Q(vlan=102) /
4008 ARP(op="who-has",
Benoît Gannec47b97d2019-06-06 17:53:21 +02004009 psrc=eep3.ip4.address, pdst="10.0.0.128",
4010 hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff"))
Benoît Ganne286921e2019-06-05 19:08:40 +02004011 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0)
4012
4013 #
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07004014 # packets destined to unknown addresses in the BVI's subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08004015 # are ARP'd for
4016 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004017 p4 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004018 Dot1Q(vlan=100) /
4019 IP(src="10.0.0.1", dst="10.0.0.88") /
4020 UDP(sport=1234, dport=1234) /
4021 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07004022 p6 = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004023 Dot1Q(vlan=100) /
4024 IPv6(src="2001:10::1", dst="2001:10::88") /
4025 UDP(sport=1234, dport=1234) /
4026 Raw('\xa5' * 100))
4027
4028 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
4029
4030 for rx in rxs:
4031 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4032 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4033 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4034 self.assertEqual(rx[IP].dst, "239.1.1.1")
4035 self.assertEqual(rx[VXLAN].vni, 88)
4036 self.assertTrue(rx[VXLAN].flags.G)
4037 self.assertTrue(rx[VXLAN].flags.Instance)
Neale Ranns45db8852019-01-09 00:04:04 -08004038 # policy was applied to the original IP packet
Neale Ranns879d11c2019-01-21 23:34:18 -08004039 self.assertEqual(rx[VXLAN].gpid, 113)
Neale Ranns45db8852019-01-09 00:04:04 -08004040 self.assertTrue(rx[VXLAN].gpflags.A)
Neale Rannsb6a47952018-11-21 05:44:35 -08004041 self.assertFalse(rx[VXLAN].gpflags.D)
4042
4043 inner = rx[VXLAN].payload
4044
4045 self.assertTrue(inner.haslayer(ARP))
4046
4047 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004048 # remote to external
4049 #
4050 p = (Ether(src=self.pg7.remote_mac,
4051 dst=self.pg7.local_mac) /
4052 IP(src=self.pg7.remote_ip4,
4053 dst=self.pg7.local_ip4) /
4054 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08004055 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01004056 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004057 IP(src="10.0.0.101", dst="10.0.0.1") /
4058 UDP(sport=1234, dport=1234) /
4059 Raw('\xa5' * 100))
4060
4061 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4062
4063 #
Neale Ranns36abbf12019-03-12 02:34:07 -07004064 # local EP pings router
4065 #
4066 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4067 Dot1Q(vlan=100) /
4068 IP(src=eep1.ip4.address, dst="10.0.0.128") /
4069 ICMP(type='echo-request'))
4070
4071 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4072
4073 for rx in rxs:
4074 self.assertEqual(rx[Ether].src, str(self.router_mac))
4075 self.assertEqual(rx[Ether].dst, eep1.mac)
4076 self.assertEqual(rx[Dot1Q].vlan, 100)
4077
4078 #
4079 # local EP pings other local EP
4080 #
4081 p = (Ether(src=eep1.mac, dst=eep2.mac) /
4082 Dot1Q(vlan=100) /
4083 IP(src=eep1.ip4.address, dst=eep2.ip4.address) /
4084 ICMP(type='echo-request'))
4085
4086 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4087
4088 for rx in rxs:
4089 self.assertEqual(rx[Ether].src, eep1.mac)
4090 self.assertEqual(rx[Ether].dst, eep2.mac)
4091 self.assertEqual(rx[Dot1Q].vlan, 101)
4092
4093 #
Benoît Ganne286921e2019-06-05 19:08:40 +02004094 # local EP pings router w/o vlan tag poped
4095 #
4096 p = (Ether(src=eep3.mac, dst=str(self.router_mac)) /
4097 Dot1Q(vlan=102) /
4098 IP(src=eep3.ip4.address, dst="10.0.0.128") /
4099 ICMP(type='echo-request'))
4100
4101 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4102
4103 for rx in rxs:
4104 self.assertEqual(rx[Ether].src, str(self.router_mac))
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004105 self.assertEqual(rx[Ether].dst, self.vlan_102.remote_mac)
Benoît Ganne286921e2019-06-05 19:08:40 +02004106
4107 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004108 # A ip4 subnet reachable through the external EP1
Neale Rannsb6a47952018-11-21 05:44:35 -08004109 #
4110 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
Neale Ranns36abbf12019-03-12 02:34:07 -07004111 [VppRoutePath(eep1.ip4.address,
4112 eep1.epg.bvi.sw_if_index)],
Neale Rannsb6a47952018-11-21 05:44:35 -08004113 table_id=t4.table_id)
4114 ip_220.add_vpp_config()
4115
4116 l3o_220 = VppGbpSubnet(
4117 self, rd1, "10.220.0.0", 24,
4118 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004119 sclass=4220)
Neale Rannsb6a47952018-11-21 05:44:35 -08004120 l3o_220.add_vpp_config()
4121
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004122 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004123 # An ip6 subnet reachable through the external EP1
4124 #
4125 ip6_220 = VppIpRoute(self, "10:220::", 64,
4126 [VppRoutePath(eep1.ip6.address,
4127 eep1.epg.bvi.sw_if_index)],
4128 table_id=t6.table_id)
4129 ip6_220.add_vpp_config()
4130
4131 l3o6_220 = VppGbpSubnet(
4132 self, rd1, "10:220::", 64,
4133 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4134 sclass=4220)
4135 l3o6_220.add_vpp_config()
4136
4137 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004138 # A subnet reachable through the external EP2
4139 #
4140 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
4141 [VppRoutePath(eep2.ip4.address,
4142 eep2.epg.bvi.sw_if_index)],
4143 table_id=t4.table_id)
4144 ip_221.add_vpp_config()
4145
4146 l3o_221 = VppGbpSubnet(
4147 self, rd1, "10.221.0.0", 24,
4148 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4149 sclass=4221)
4150 l3o_221.add_vpp_config()
4151
4152 #
4153 # ping between hosts in remote subnets
4154 # dropped without a contract
4155 #
4156 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4157 Dot1Q(vlan=100) /
4158 IP(src="10.220.0.1", dst="10.221.0.1") /
4159 ICMP(type='echo-request'))
4160
Neale Ranns160c9232019-06-19 06:25:56 -07004161 self.send_and_assert_no_replies(self.pg0, p * 1)
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004162
4163 #
4164 # contract for the external nets to communicate
4165 #
4166 acl = VppGbpAcl(self)
4167 rule4 = acl.create_rule(permit_deny=1, proto=17)
4168 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
4169 acl_index = acl.add_vpp_config([rule4, rule6])
4170
Neale Ranns160c9232019-06-19 06:25:56 -07004171 #
4172 # A contract with the wrong scope is not matched
4173 #
4174 c_44 = VppGbpContract(
4175 self, 44, 4220, 4221, acl_index,
4176 [VppGbpContractRule(
4177 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4178 []),
4179 VppGbpContractRule(
4180 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4181 [])],
4182 [ETH_P_IP, ETH_P_IPV6])
4183 c_44.add_vpp_config()
4184 self.send_and_assert_no_replies(self.pg0, p * 1)
4185
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004186 c1 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004187 self, 55, 4220, 4221, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004188 [VppGbpContractRule(
4189 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004190 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004191 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004192 VppGbpContractRule(
4193 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004194 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004195 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004196 [ETH_P_IP, ETH_P_IPV6])
4197 c1.add_vpp_config()
4198
4199 #
4200 # Contracts allowing ext-net 200 to talk with external EPs
4201 #
4202 c2 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004203 self, 55, 4220, 113, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004204 [VppGbpContractRule(
4205 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004206 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004207 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004208 VppGbpContractRule(
4209 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004210 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004211 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004212 [ETH_P_IP, ETH_P_IPV6])
4213 c2.add_vpp_config()
4214 c3 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004215 self, 55, 113, 4220, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004216 [VppGbpContractRule(
4217 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004218 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004219 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004220 VppGbpContractRule(
4221 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004222 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004223 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004224 [ETH_P_IP, ETH_P_IPV6])
4225 c3.add_vpp_config()
4226
4227 #
4228 # ping between hosts in remote subnets
4229 #
4230 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4231 Dot1Q(vlan=100) /
4232 IP(src="10.220.0.1", dst="10.221.0.1") /
4233 UDP(sport=1234, dport=1234) /
4234 Raw('\xa5' * 100))
4235
4236 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4237
4238 for rx in rxs:
4239 self.assertEqual(rx[Ether].src, str(self.router_mac))
4240 self.assertEqual(rx[Ether].dst, eep2.mac)
4241 self.assertEqual(rx[Dot1Q].vlan, 101)
4242
4243 # we did not learn these external hosts
4244 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
4245 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
4246
4247 #
4248 # from remote external EP to local external EP
4249 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004250 p = (Ether(src=self.pg7.remote_mac,
4251 dst=self.pg7.local_mac) /
4252 IP(src=self.pg7.remote_ip4,
4253 dst=self.pg7.local_ip4) /
4254 UDP(sport=1234, dport=48879) /
Neale Ranns879d11c2019-01-21 23:34:18 -08004255 VXLAN(vni=444, gpid=113, flags=0x88) /
Ole Troan8006c6a2018-12-17 12:02:26 +01004256 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
Neale Rannsb6a47952018-11-21 05:44:35 -08004257 IP(src="10.0.0.101", dst="10.220.0.1") /
4258 UDP(sport=1234, dport=1234) /
4259 Raw('\xa5' * 100))
4260
4261 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4262
4263 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004264 # ping from an external host to the remote external EP
Neale Ranns36abbf12019-03-12 02:34:07 -07004265 #
4266 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4267 Dot1Q(vlan=100) /
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004268 IP(src="10.220.0.1", dst=rep.ip4.address) /
4269 UDP(sport=1234, dport=1234) /
4270 Raw('\xa5' * 100))
Neale Ranns36abbf12019-03-12 02:34:07 -07004271
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004272 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
Neale Ranns36abbf12019-03-12 02:34:07 -07004273
4274 for rx in rxs:
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004275 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4276 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4277 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4278 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4279 self.assertEqual(rx[VXLAN].vni, 444)
4280 self.assertTrue(rx[VXLAN].flags.G)
4281 self.assertTrue(rx[VXLAN].flags.Instance)
4282 # the sclass of the ext-net the packet came from
4283 self.assertEqual(rx[VXLAN].gpid, 4220)
4284 # policy was applied to the original IP packet
4285 self.assertTrue(rx[VXLAN].gpflags.A)
4286 # since it's an external host the reciever should not learn it
4287 self.assertTrue(rx[VXLAN].gpflags.D)
4288 inner = rx[VXLAN].payload
4289 self.assertEqual(inner[IP].src, "10.220.0.1")
4290 self.assertEqual(inner[IP].dst, rep.ip4.address)
4291
4292 #
4293 # An external subnet reachable via the remote external EP
4294 #
4295
4296 #
4297 # first the VXLAN-GBP tunnel over which it is reached
4298 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004299 vx_tun_r1 = VppVxlanGbpTunnel(
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004300 self, self.pg7.local_ip4,
4301 self.pg7.remote_ip4, 445,
4302 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4303 VXLAN_GBP_API_TUNNEL_MODE_L3))
Neale Ranns69a85b52019-06-14 07:49:50 +00004304 vx_tun_r1.add_vpp_config()
4305 VppIpInterfaceBind(self, vx_tun_r1, t4).add_vpp_config()
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004306
4307 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4308
4309 #
4310 # then the special adj to resolve through on that tunnel
4311 #
4312 n1 = VppNeighbor(self,
Neale Ranns69a85b52019-06-14 07:49:50 +00004313 vx_tun_r1.sw_if_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004314 "00:0c:0c:0c:0c:0c",
4315 self.pg7.remote_ip4)
4316 n1.add_vpp_config()
4317
4318 #
4319 # the route via the adj above
4320 #
4321 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
4322 [VppRoutePath(self.pg7.remote_ip4,
Neale Ranns69a85b52019-06-14 07:49:50 +00004323 vx_tun_r1.sw_if_index)],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004324 table_id=t4.table_id)
4325 ip_222.add_vpp_config()
4326
4327 l3o_222 = VppGbpSubnet(
4328 self, rd1, "10.222.0.0", 24,
4329 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4330 sclass=4222)
4331 l3o_222.add_vpp_config()
4332
4333 #
4334 # ping between hosts in local and remote external subnets
4335 # dropped without a contract
4336 #
4337 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4338 Dot1Q(vlan=100) /
4339 IP(src="10.220.0.1", dst="10.222.0.1") /
4340 UDP(sport=1234, dport=1234) /
4341 Raw('\xa5' * 100))
4342
4343 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
4344
4345 #
4346 # Add contracts ext-nets for 220 -> 222
4347 #
4348 c4 = VppGbpContract(
Neale Ranns160c9232019-06-19 06:25:56 -07004349 self, 55, 4220, 4222, acl_index,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004350 [VppGbpContractRule(
4351 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004352 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004353 []),
Filip Vargaf4749ca2019-04-25 14:55:32 +02004354 VppGbpContractRule(
4355 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
Paul Vinciguerra1b534f52019-06-15 20:31:31 -04004356 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Filip Vargaf4749ca2019-04-25 14:55:32 +02004357 [])],
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004358 [ETH_P_IP, ETH_P_IPV6])
4359 c4.add_vpp_config()
4360
4361 #
4362 # ping from host in local to remote external subnets
4363 #
4364 p = (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4365 Dot1Q(vlan=100) /
4366 IP(src="10.220.0.1", dst="10.222.0.1") /
4367 UDP(sport=1234, dport=1234) /
4368 Raw('\xa5' * 100))
4369
4370 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
4371
4372 for rx in rxs:
4373 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4374 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4375 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4376 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4377 self.assertEqual(rx[VXLAN].vni, 445)
4378 self.assertTrue(rx[VXLAN].flags.G)
4379 self.assertTrue(rx[VXLAN].flags.Instance)
4380 # the sclass of the ext-net the packet came from
4381 self.assertEqual(rx[VXLAN].gpid, 4220)
4382 # policy was applied to the original IP packet
4383 self.assertTrue(rx[VXLAN].gpflags.A)
4384 # since it's an external host the reciever should not learn it
4385 self.assertTrue(rx[VXLAN].gpflags.D)
4386 inner = rx[VXLAN].payload
4387 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
4388 self.assertEqual(inner[IP].src, "10.220.0.1")
4389 self.assertEqual(inner[IP].dst, "10.222.0.1")
4390
4391 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004392 # make the external subnet ECMP
4393 #
4394 vx_tun_r2 = VppVxlanGbpTunnel(
4395 self, self.pg7.local_ip4,
4396 self.pg7.remote_ip4, 446,
4397 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4398 VXLAN_GBP_API_TUNNEL_MODE_L3))
4399 vx_tun_r2.add_vpp_config()
4400 VppIpInterfaceBind(self, vx_tun_r2, t4).add_vpp_config()
4401
4402 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4403
4404 n2 = VppNeighbor(self,
4405 vx_tun_r2.sw_if_index,
4406 "00:0c:0c:0c:0c:0c",
4407 self.pg7.remote_ip4)
4408 n2.add_vpp_config()
4409
4410 ip_222.modify([VppRoutePath(self.pg7.remote_ip4,
4411 vx_tun_r1.sw_if_index),
4412 VppRoutePath(self.pg7.remote_ip4,
4413 vx_tun_r2.sw_if_index)])
4414
4415 #
4416 # now expect load-balance
4417 #
4418 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
4419 Dot1Q(vlan=100) /
4420 IP(src="10.220.0.1", dst="10.222.0.1") /
4421 UDP(sport=1234, dport=1234) /
4422 Raw('\xa5' * 100)),
4423 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4424 Dot1Q(vlan=100) /
4425 IP(src="10.220.0.1", dst="10.222.0.1") /
4426 UDP(sport=1222, dport=1235) /
4427 Raw('\xa5' * 100))]
4428
4429 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4430
4431 self.assertEqual(rxs[0][VXLAN].vni, 445)
4432 self.assertEqual(rxs[1][VXLAN].vni, 446)
4433
4434 #
4435 # Same LB test for v6
4436 #
4437 n3 = VppNeighbor(self,
4438 vx_tun_r1.sw_if_index,
4439 "00:0c:0c:0c:0c:0c",
4440 self.pg7.remote_ip6)
4441 n3.add_vpp_config()
4442 n4 = VppNeighbor(self,
4443 vx_tun_r2.sw_if_index,
4444 "00:0c:0c:0c:0c:0c",
4445 self.pg7.remote_ip6)
4446 n4.add_vpp_config()
4447
4448 ip_222_6 = VppIpRoute(self, "10:222::", 64,
4449 [VppRoutePath(self.pg7.remote_ip6,
4450 vx_tun_r1.sw_if_index),
4451 VppRoutePath(self.pg7.remote_ip6,
4452 vx_tun_r2.sw_if_index)],
4453 table_id=t6.table_id)
4454 ip_222_6.add_vpp_config()
4455
4456 l3o_222_6 = VppGbpSubnet(
4457 self, rd1, "10:222::", 64,
4458 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4459 sclass=4222)
4460 l3o_222_6.add_vpp_config()
4461
4462 p = [(Ether(src=eep1.mac, dst=str(self.router_mac)) /
4463 Dot1Q(vlan=100) /
4464 IPv6(src="10:220::1", dst="10:222::1") /
4465 UDP(sport=1234, dport=1234) /
4466 Raw('\xa5' * 100)),
4467 (Ether(src=eep1.mac, dst=str(self.router_mac)) /
4468 Dot1Q(vlan=100) /
4469 IPv6(src="10:220::1", dst="10:222::1") /
4470 UDP(sport=7777, dport=8881) /
4471 Raw('\xa5' * 100))]
4472
4473 self.logger.info(self.vapi.cli("sh ip6 fib 10:222::1"))
4474 rxs = self.send_and_expect(self.pg0, p, self.pg7)
4475
4476 self.assertEqual(rxs[0][VXLAN].vni, 445)
4477 self.assertEqual(rxs[1][VXLAN].vni, 446)
4478
4479 #
Neale Ranns4dd4cf42019-03-27 05:06:47 -07004480 # ping from host in remote to local external subnets
4481 # there's no contract for this, but the A bit is set.
4482 #
4483 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4484 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4485 UDP(sport=1234, dport=48879) /
4486 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4487 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4488 IP(src="10.222.0.1", dst="10.220.0.1") /
4489 UDP(sport=1234, dport=1234) /
4490 Raw('\xa5' * 100))
4491
4492 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
4493 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
Neale Ranns36abbf12019-03-12 02:34:07 -07004494
4495 #
Neale Ranns2b600182019-03-29 05:08:27 -07004496 # ping from host in remote to remote external subnets
4497 # this is dropped by reflection check.
4498 #
4499 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4500 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4501 UDP(sport=1234, dport=48879) /
4502 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4503 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4504 IP(src="10.222.0.1", dst="10.222.0.2") /
4505 UDP(sport=1234, dport=1234) /
4506 Raw('\xa5' * 100))
4507
4508 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
4509
Neale Ranns69a85b52019-06-14 07:49:50 +00004510 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
4511 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
4512 UDP(sport=1234, dport=48879) /
4513 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
4514 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4515 IPv6(src="10:222::1", dst="10:222::2") /
4516 UDP(sport=1234, dport=1234) /
4517 Raw('\xa5' * 100))
4518
4519 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
4520
4521 #
4522 # local EP
4523 #
4524 lep1 = VppGbpEndpoint(self, vlan_144,
4525 epg_220, None,
4526 "10.0.0.44", "11.0.0.44",
4527 "2001:10::44", "3001::44")
4528 lep1.add_vpp_config()
4529
4530 #
4531 # local EP to local ip4 external subnet
4532 #
4533 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4534 Dot1Q(vlan=144) /
4535 IP(src=lep1.ip4.address, dst="10.220.0.1") /
4536 UDP(sport=1234, dport=1234) /
4537 Raw('\xa5' * 100))
4538
4539 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4540
4541 for rx in rxs:
4542 self.assertEqual(rx[Ether].src, str(self.router_mac))
4543 self.assertEqual(rx[Ether].dst, eep1.mac)
4544 self.assertEqual(rx[Dot1Q].vlan, 100)
4545
4546 #
4547 # local EP to local ip6 external subnet
4548 #
4549 p = (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4550 Dot1Q(vlan=144) /
4551 IPv6(src=lep1.ip6.address, dst="10:220::1") /
4552 UDP(sport=1234, dport=1234) /
4553 Raw('\xa5' * 100))
4554
4555 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4556
4557 for rx in rxs:
4558 self.assertEqual(rx[Ether].src, str(self.router_mac))
4559 self.assertEqual(rx[Ether].dst, eep1.mac)
4560 self.assertEqual(rx[Dot1Q].vlan, 100)
4561
4562 #
4563 # ip4 and ip6 subnets that load-balance
4564 #
4565 ip_20 = VppIpRoute(self, "10.20.0.0", 24,
4566 [VppRoutePath(eep1.ip4.address,
4567 eep1.epg.bvi.sw_if_index),
4568 VppRoutePath(eep2.ip4.address,
4569 eep2.epg.bvi.sw_if_index)],
4570 table_id=t4.table_id)
4571 ip_20.add_vpp_config()
4572
4573 l3o_20 = VppGbpSubnet(
4574 self, rd1, "10.20.0.0", 24,
4575 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4576 sclass=4220)
4577 l3o_20.add_vpp_config()
4578
4579 ip6_20 = VppIpRoute(self, "10:20::", 64,
4580 [VppRoutePath(eep1.ip6.address,
4581 eep1.epg.bvi.sw_if_index),
4582 VppRoutePath(eep2.ip6.address,
4583 eep2.epg.bvi.sw_if_index)],
4584 table_id=t6.table_id)
4585 ip6_20.add_vpp_config()
4586
4587 l3o6_20 = VppGbpSubnet(
4588 self, rd1, "10:20::", 64,
4589 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4590 sclass=4220)
4591 l3o6_20.add_vpp_config()
4592
4593 self.logger.info(self.vapi.cli("sh ip fib 10.20.0.1"))
4594 self.logger.info(self.vapi.cli("sh ip6 fib 10:20::1"))
4595
4596 # two ip6 packets whose port are chosen so they load-balance
4597 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
4598 Dot1Q(vlan=144) /
4599 IPv6(src=lep1.ip6.address, dst="10:20::1") /
4600 UDP(sport=1234, dport=1234) /
4601 Raw('\xa5' * 100)),
4602 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4603 Dot1Q(vlan=144) /
4604 IPv6(src=lep1.ip6.address, dst="10:20::1") /
4605 UDP(sport=124, dport=1230) /
4606 Raw('\xa5' * 100))]
4607
4608 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
4609
4610 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
4611 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
4612
4613 # two ip4 packets whose port are chosen so they load-balance
4614 p = [(Ether(src=lep1.mac, dst=str(self.router_mac)) /
4615 Dot1Q(vlan=144) /
4616 IP(src=lep1.ip4.address, dst="10.20.0.1") /
4617 UDP(sport=1235, dport=1235) /
4618 Raw('\xa5' * 100)),
4619 (Ether(src=lep1.mac, dst=str(self.router_mac)) /
4620 Dot1Q(vlan=144) /
4621 IP(src=lep1.ip4.address, dst="10.20.0.1") /
4622 UDP(sport=124, dport=1230) /
4623 Raw('\xa5' * 100))]
4624
4625 rxs = self.send_and_expect(self.pg0, p, self.pg0, 2)
4626
4627 self.assertEqual(rxs[0][Dot1Q].vlan, 101)
4628 self.assertEqual(rxs[1][Dot1Q].vlan, 100)
4629
Neale Ranns2b600182019-03-29 05:08:27 -07004630 #
Neale Rannsb6a47952018-11-21 05:44:35 -08004631 # cleanup
4632 #
Neale Ranns69a85b52019-06-14 07:49:50 +00004633 ip_222.remove_vpp_config()
Neale Rannsb6a47952018-11-21 05:44:35 -08004634 self.pg7.unconfig_ip4()
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004635 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
4636 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
4637
4638 def test_gbp_anon_l3_out(self):
4639 """ GBP Anonymous L3 Out """
4640
4641 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
4642 self.vapi.cli("set logging class gbp level debug")
4643
4644 routed_dst_mac = "00:0c:0c:0c:0c:0c"
4645 routed_src_mac = "00:22:bd:f8:19:ff"
4646
4647 #
4648 # IP tables
4649 #
4650 t4 = VppIpTable(self, 1)
4651 t4.add_vpp_config()
4652 t6 = VppIpTable(self, 1, True)
4653 t6.add_vpp_config()
4654
4655 rd1 = VppGbpRouteDomain(self, 2, 55, t4, t6)
4656 rd1.add_vpp_config()
4657
4658 self.loop0.set_mac(self.router_mac)
4659
4660 #
4661 # Bind the BVI to the RD
4662 #
4663 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
4664 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
4665
4666 #
4667 # Pg7 hosts a BD's BUM
4668 # Pg1 some other l3 interface
4669 #
4670 self.pg7.config_ip4()
4671 self.pg7.resolve_arp()
4672
4673 #
4674 # a GBP external bridge domains for the EPs
4675 #
4676 bd1 = VppBridgeDomain(self, 1)
4677 bd1.add_vpp_config()
4678 gbd1 = VppGbpBridgeDomain(self, bd1, rd1, self.loop0, None, None)
4679 gbd1.add_vpp_config()
4680
4681 #
4682 # The Endpoint-groups in which the external endpoints exist
4683 #
4684 epg_220 = VppGbpEndpointGroup(self, 220, 113, rd1, gbd1,
4685 None, gbd1.bvi,
4686 "10.0.0.128",
4687 "2001:10::128",
4688 VppGbpEndpointRetention(2))
4689 epg_220.add_vpp_config()
4690
4691 # the BVIs have the subnet applied ...
4692 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
4693 ip4_addr.add_vpp_config()
4694
4695 # ... which is an Anonymous L3-out subnets
4696 l3o_1 = VppGbpSubnet(
4697 self, rd1, "10.0.0.0", 24,
4698 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_ANON_L3_OUT,
4699 sclass=113)
4700 l3o_1.add_vpp_config()
4701
4702 #
4703 # an external interface attached to the outside world and the
4704 # external BD
4705 #
4706 VppL2Vtr(self, self.vlan_100, L2_VTR_OP.L2_POP_1).add_vpp_config()
4707 VppL2Vtr(self, self.vlan_101, L2_VTR_OP.L2_POP_1).add_vpp_config()
4708
Benoît Ganneba6abfa2019-07-01 17:10:41 +02004709 #
4710 # vlan_100 and vlan_101 are anonymous l3-out interfaces
4711 #
4712 ext_itf = VppGbpExtItf(self, self.vlan_100, bd1, rd1, anon=True)
4713 ext_itf.add_vpp_config()
4714 ext_itf = VppGbpExtItf(self, self.vlan_101, bd1, rd1, anon=True)
4715 ext_itf.add_vpp_config()
4716
4717 #
4718 # an unicast vxlan-gbp for inter-RD traffic
4719 #
4720 vx_tun_l3 = VppGbpVxlanTunnel(
4721 self, 444, rd1.rd_id,
4722 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3,
4723 self.pg2.local_ip4)
4724 vx_tun_l3.add_vpp_config()
4725
4726 #
4727 # A remote external endpoint
4728 #
4729 rep = VppGbpEndpoint(self, vx_tun_l3,
4730 epg_220, None,
4731 "10.0.0.201", "11.0.0.201",
4732 "2001:10::201", "3001::101",
4733 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
4734 self.pg7.local_ip4,
4735 self.pg7.remote_ip4,
4736 mac=None)
4737 rep.add_vpp_config()
4738
4739 #
4740 # ARP packet from host in external subnet are accepted, flooded and
4741 # replied to. We expect 2 packets:
4742 # - APR request flooded over the other vlan subif
4743 # - ARP reply from BVI
4744 #
4745 p_arp = (Ether(src=self.vlan_100.remote_mac,
4746 dst="ff:ff:ff:ff:ff:ff") /
4747 Dot1Q(vlan=100) /
4748 ARP(op="who-has",
4749 psrc="10.0.0.100",
4750 pdst="10.0.0.128",
4751 hwsrc=self.vlan_100.remote_mac,
4752 hwdst="ff:ff:ff:ff:ff:ff"))
4753 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
4754
4755 p_arp = (Ether(src=self.vlan_101.remote_mac,
4756 dst="ff:ff:ff:ff:ff:ff") /
4757 Dot1Q(vlan=101) /
4758 ARP(op="who-has",
4759 psrc='10.0.0.101',
4760 pdst="10.0.0.128",
4761 hwsrc=self.vlan_101.remote_mac,
4762 hwdst="ff:ff:ff:ff:ff:ff"))
4763 rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0, n_rx=2)
4764
4765 #
4766 # remote to external
4767 #
4768 p = (Ether(src=self.pg7.remote_mac,
4769 dst=self.pg7.local_mac) /
4770 IP(src=self.pg7.remote_ip4,
4771 dst=self.pg7.local_ip4) /
4772 UDP(sport=1234, dport=48879) /
4773 VXLAN(vni=vx_tun_l3.vni, gpid=epg_220.sclass, flags=0x88) /
4774 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4775 IP(src=str(rep.ip4), dst="10.0.0.100") /
4776 UDP(sport=1234, dport=1234) /
4777 Raw('\xa5' * 100))
4778 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4779
4780 #
4781 # local EP pings router
4782 #
4783 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4784 Dot1Q(vlan=100) /
4785 IP(src="10.0.0.100", dst="10.0.0.128") /
4786 ICMP(type='echo-request'))
4787 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4788
4789 for rx in rxs:
4790 self.assertEqual(rx[Ether].src, str(self.router_mac))
4791 self.assertEqual(rx[Ether].dst, self.vlan_100.remote_mac)
4792 self.assertEqual(rx[Dot1Q].vlan, 100)
4793
4794 #
4795 # local EP pings other local EP
4796 #
4797 p = (Ether(src=self.vlan_100.remote_mac,
4798 dst=self.vlan_101.remote_mac) /
4799 Dot1Q(vlan=100) /
4800 IP(src="10.0.0.100", dst="10.0.0.101") /
4801 ICMP(type='echo-request'))
4802 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4803
4804 for rx in rxs:
4805 self.assertEqual(rx[Ether].src, self.vlan_100.remote_mac)
4806 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
4807 self.assertEqual(rx[Dot1Q].vlan, 101)
4808
4809 #
4810 # A subnet reachable through an external router on vlan 100
4811 #
4812 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
4813 [VppRoutePath("10.0.0.100",
4814 epg_220.bvi.sw_if_index)],
4815 table_id=t4.table_id)
4816 ip_220.add_vpp_config()
4817
4818 l3o_220 = VppGbpSubnet(
4819 self, rd1, "10.220.0.0", 24,
4820 # note: this a "regular" L3 out subnet (not connected)
4821 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4822 sclass=4220)
4823 l3o_220.add_vpp_config()
4824
4825 #
4826 # A subnet reachable through an external router on vlan 101
4827 #
4828 ip_221 = VppIpRoute(self, "10.221.0.0", 24,
4829 [VppRoutePath("10.0.0.101",
4830 epg_220.bvi.sw_if_index)],
4831 table_id=t4.table_id)
4832 ip_221.add_vpp_config()
4833
4834 l3o_221 = VppGbpSubnet(
4835 self, rd1, "10.221.0.0", 24,
4836 # note: this a "regular" L3 out subnet (not connected)
4837 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
4838 sclass=4221)
4839 l3o_221.add_vpp_config()
4840
4841 #
4842 # ping between hosts in remote subnets
4843 # dropped without a contract
4844 #
4845 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4846 Dot1Q(vlan=100) /
4847 IP(src="10.220.0.1", dst="10.221.0.1") /
4848 ICMP(type='echo-request'))
4849
4850 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
4851
4852 #
4853 # contract for the external nets to communicate
4854 #
4855 acl = VppGbpAcl(self)
4856 rule4 = acl.create_rule(permit_deny=1, proto=17)
4857 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
4858 acl_index = acl.add_vpp_config([rule4, rule6])
4859
4860 c1 = VppGbpContract(
4861 self, 55, 4220, 4221, acl_index,
4862 [VppGbpContractRule(
4863 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4864 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4865 []),
4866 VppGbpContractRule(
4867 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4868 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4869 [])],
4870 [ETH_P_IP, ETH_P_IPV6])
4871 c1.add_vpp_config()
4872
4873 #
4874 # Contracts allowing ext-net 200 to talk with external EPs
4875 #
4876 c2 = VppGbpContract(
4877 self, 55, 4220, 113, acl_index,
4878 [VppGbpContractRule(
4879 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4880 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4881 []),
4882 VppGbpContractRule(
4883 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4884 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4885 [])],
4886 [ETH_P_IP, ETH_P_IPV6])
4887 c2.add_vpp_config()
4888 c3 = VppGbpContract(
4889 self, 55, 113, 4220, acl_index,
4890 [VppGbpContractRule(
4891 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4892 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4893 []),
4894 VppGbpContractRule(
4895 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
4896 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
4897 [])],
4898 [ETH_P_IP, ETH_P_IPV6])
4899 c3.add_vpp_config()
4900
4901 #
4902 # ping between hosts in remote subnets
4903 #
4904 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4905 Dot1Q(vlan=100) /
4906 IP(src="10.220.0.1", dst="10.221.0.1") /
4907 UDP(sport=1234, dport=1234) /
4908 Raw('\xa5' * 100))
4909
4910 rxs = self.send_and_expect(self.pg0, p * 1, self.pg0)
4911
4912 for rx in rxs:
4913 self.assertEqual(rx[Ether].src, str(self.router_mac))
4914 self.assertEqual(rx[Ether].dst, self.vlan_101.remote_mac)
4915 self.assertEqual(rx[Dot1Q].vlan, 101)
4916
4917 # we did not learn these external hosts
4918 self.assertFalse(find_gbp_endpoint(self, ip="10.220.0.1"))
4919 self.assertFalse(find_gbp_endpoint(self, ip="10.221.0.1"))
4920
4921 #
4922 # from remote external EP to local external EP
4923 #
4924 p = (Ether(src=self.pg7.remote_mac,
4925 dst=self.pg7.local_mac) /
4926 IP(src=self.pg7.remote_ip4,
4927 dst=self.pg7.local_ip4) /
4928 UDP(sport=1234, dport=48879) /
4929 VXLAN(vni=444, gpid=113, flags=0x88) /
4930 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
4931 IP(src=rep.ip4.address, dst="10.220.0.1") /
4932 UDP(sport=1234, dport=1234) /
4933 Raw('\xa5' * 100))
4934
4935 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
4936
4937 #
4938 # ping from an external host to the remote external EP
4939 #
4940 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
4941 Dot1Q(vlan=100) /
4942 IP(src="10.220.0.1", dst=rep.ip4.address) /
4943 UDP(sport=1234, dport=1234) /
4944 Raw('\xa5' * 100))
4945
4946 rxs = self.send_and_expect(self.pg0, p * 1, self.pg7)
4947
4948 for rx in rxs:
4949 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
4950 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
4951 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
4952 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
4953 self.assertEqual(rx[VXLAN].vni, 444)
4954 self.assertTrue(rx[VXLAN].flags.G)
4955 self.assertTrue(rx[VXLAN].flags.Instance)
4956 # the sclass of the ext-net the packet came from
4957 self.assertEqual(rx[VXLAN].gpid, 4220)
4958 # policy was applied to the original IP packet
4959 self.assertTrue(rx[VXLAN].gpflags.A)
4960 # since it's an external host the reciever should not learn it
4961 self.assertTrue(rx[VXLAN].gpflags.D)
4962 inner = rx[VXLAN].payload
4963 self.assertEqual(inner[IP].src, "10.220.0.1")
4964 self.assertEqual(inner[IP].dst, rep.ip4.address)
4965
4966 #
4967 # An external subnet reachable via the remote external EP
4968 #
4969
4970 #
4971 # first the VXLAN-GBP tunnel over which it is reached
4972 #
4973 vx_tun_r = VppVxlanGbpTunnel(
4974 self, self.pg7.local_ip4,
4975 self.pg7.remote_ip4, 445,
4976 mode=(VppEnum.vl_api_vxlan_gbp_api_tunnel_mode_t.
4977 VXLAN_GBP_API_TUNNEL_MODE_L3))
4978 vx_tun_r.add_vpp_config()
4979 VppIpInterfaceBind(self, vx_tun_r, t4).add_vpp_config()
4980
4981 self.logger.info(self.vapi.cli("sh vxlan-gbp tunnel"))
4982
4983 #
4984 # then the special adj to resolve through on that tunnel
4985 #
4986 n1 = VppNeighbor(self,
4987 vx_tun_r.sw_if_index,
4988 "00:0c:0c:0c:0c:0c",
4989 self.pg7.remote_ip4)
4990 n1.add_vpp_config()
4991
4992 #
4993 # the route via the adj above
4994 #
4995 ip_222 = VppIpRoute(self, "10.222.0.0", 24,
4996 [VppRoutePath(self.pg7.remote_ip4,
4997 vx_tun_r.sw_if_index)],
4998 table_id=t4.table_id)
4999 ip_222.add_vpp_config()
5000
5001 l3o_222 = VppGbpSubnet(
5002 self, rd1, "10.222.0.0", 24,
5003 # note: this a "regular" l3out subnet (not connected)
5004 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
5005 sclass=4222)
5006 l3o_222.add_vpp_config()
5007
5008 #
5009 # ping between hosts in local and remote external subnets
5010 # dropped without a contract
5011 #
5012 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5013 Dot1Q(vlan=100) /
5014 IP(src="10.220.0.1", dst="10.222.0.1") /
5015 UDP(sport=1234, dport=1234) /
5016 Raw('\xa5' * 100))
5017
5018 rxs = self.send_and_assert_no_replies(self.pg0, p * 1)
5019
5020 #
5021 # Add contracts ext-nets for 220 -> 222
5022 #
5023 c4 = VppGbpContract(
5024 self, 55, 4220, 4222, acl_index,
5025 [VppGbpContractRule(
5026 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5027 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5028 []),
5029 VppGbpContractRule(
5030 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
5031 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
5032 [])],
5033 [ETH_P_IP, ETH_P_IPV6])
5034 c4.add_vpp_config()
5035
5036 #
5037 # ping from host in local to remote external subnets
5038 #
5039 p = (Ether(src=self.vlan_100.remote_mac, dst=str(self.router_mac)) /
5040 Dot1Q(vlan=100) /
5041 IP(src="10.220.0.1", dst="10.222.0.1") /
5042 UDP(sport=1234, dport=1234) /
5043 Raw('\xa5' * 100))
5044
5045 rxs = self.send_and_expect(self.pg0, p * 3, self.pg7)
5046
5047 for rx in rxs:
5048 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
5049 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
5050 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
5051 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
5052 self.assertEqual(rx[VXLAN].vni, 445)
5053 self.assertTrue(rx[VXLAN].flags.G)
5054 self.assertTrue(rx[VXLAN].flags.Instance)
5055 # the sclass of the ext-net the packet came from
5056 self.assertEqual(rx[VXLAN].gpid, 4220)
5057 # policy was applied to the original IP packet
5058 self.assertTrue(rx[VXLAN].gpflags.A)
5059 # since it's an external host the reciever should not learn it
5060 self.assertTrue(rx[VXLAN].gpflags.D)
5061 inner = rx[VXLAN].payload
5062 self.assertEqual(inner[Ether].dst, "00:0c:0c:0c:0c:0c")
5063 self.assertEqual(inner[IP].src, "10.220.0.1")
5064 self.assertEqual(inner[IP].dst, "10.222.0.1")
5065
5066 #
5067 # ping from host in remote to local external subnets
5068 # there's no contract for this, but the A bit is set.
5069 #
5070 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5071 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5072 UDP(sport=1234, dport=48879) /
5073 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5074 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5075 IP(src="10.222.0.1", dst="10.220.0.1") /
5076 UDP(sport=1234, dport=1234) /
5077 Raw('\xa5' * 100))
5078
5079 rxs = self.send_and_expect(self.pg7, p * 3, self.pg0)
5080 self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1"))
5081
5082 #
5083 # ping from host in remote to remote external subnets
5084 # this is dropped by reflection check.
5085 #
5086 p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) /
5087 IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) /
5088 UDP(sport=1234, dport=48879) /
5089 VXLAN(vni=445, gpid=4222, flags=0x88, gpflags='A') /
5090 Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) /
5091 IP(src="10.222.0.1", dst="10.222.0.2") /
5092 UDP(sport=1234, dport=1234) /
5093 Raw('\xa5' * 100))
5094
5095 rxs = self.send_and_assert_no_replies(self.pg7, p * 3)
5096
5097 #
5098 # cleanup
5099 #
5100 self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED)
5101 self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED)
5102 self.pg7.unconfig_ip4()
Neale Rannsb6a47952018-11-21 05:44:35 -08005103
Neale Rannsbc27d1b2018-02-05 01:13:38 -08005104
5105if __name__ == '__main__':
5106 unittest.main(testRunner=VppTestRunner)