blob: 2cceba6b906e8ca8db8cc4d9705451ee3c3af5e9 [file] [log] [blame]
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001#!/usr/bin/env python
2
3import unittest
Neale Rannsbc27d1b2018-02-05 01:13:38 -08004
5from framework import VppTestCase, VppTestRunner
6from vpp_object import VppObject
Neale Ranns25b04942018-04-04 09:34:50 -07007from vpp_neighbor import VppNeighbor
Neale Ranns93cc3ee2018-10-10 07:22:51 -07008from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, \
9 VppIpInterfaceAddress, VppIpInterfaceBind, find_route
10from vpp_l2 import VppBridgeDomain, VppBridgeDomainPort, \
11 VppBridgeDomainArpEntry, VppL2FibEntry, find_bridge_domain_port
12from vpp_vxlan_gbp_tunnel import *
Neale Rannsc29c0af2018-11-07 04:21:12 -080013from vpp_sub_interface import VppDot1QSubint
Neale Rannsc0a93142018-09-05 15:42:26 -070014
15from vpp_ip import *
16from vpp_mac import *
Neale Rannsb4743802018-09-05 09:13:57 -070017from vpp_papi_provider import L2_PORT_TYPE
Neale Ranns93cc3ee2018-10-10 07:22:51 -070018from vpp_papi import VppEnum
Neale Rannsbc27d1b2018-02-05 01:13:38 -080019
20from scapy.packet import Raw
Neale Rannsc29c0af2018-11-07 04:21:12 -080021from scapy.layers.l2 import Ether, ARP, Dot1Q
Neale Rannsbc27d1b2018-02-05 01:13:38 -080022from scapy.layers.inet import IP, UDP
Neale Ranns25b04942018-04-04 09:34:50 -070023from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6NDOptSrcLLAddr, \
Klement Sekerab9ef2732018-06-24 22:49:33 +020024 ICMPv6ND_NA
Neale Ranns25b04942018-04-04 09:34:50 -070025from scapy.utils6 import in6_getnsma, in6_getnsmac
Neale Ranns93cc3ee2018-10-10 07:22:51 -070026from scapy.layers.vxlan import VXLAN
Neale Rannsbc27d1b2018-02-05 01:13:38 -080027
28from socket import AF_INET, AF_INET6
Neale Ranns25b04942018-04-04 09:34:50 -070029from scapy.utils import inet_pton, inet_ntop
Klement Sekerab9ef2732018-06-24 22:49:33 +020030from util import mactobinary
Neale Rannsc29c0af2018-11-07 04:21:12 -080031from vpp_papi_provider import L2_VTR_OP
Neale Rannsbc27d1b2018-02-05 01:13:38 -080032
33
Neale Ranns93cc3ee2018-10-10 07:22:51 -070034def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None):
35 if ip:
36 vip = VppIpAddress(ip)
37 if mac:
38 vmac = VppMacAddress(mac)
Neale Rannsc0a93142018-09-05 15:42:26 -070039
40 eps = test.vapi.gbp_endpoint_dump()
Neale Ranns93cc3ee2018-10-10 07:22:51 -070041
Neale Rannsc0a93142018-09-05 15:42:26 -070042 for ep in eps:
Neale Ranns93cc3ee2018-10-10 07:22:51 -070043 if sw_if_index:
44 if ep.endpoint.sw_if_index != sw_if_index:
45 continue
46 if ip:
47 for eip in ep.endpoint.ips:
48 if vip == eip:
49 return True
50 if mac:
51 if vmac == ep.endpoint.mac:
Neale Rannsc0a93142018-09-05 15:42:26 -070052 return True
53 return False
54
55
Neale Ranns93cc3ee2018-10-10 07:22:51 -070056def find_gbp_vxlan(test, vni):
57 ts = test.vapi.gbp_vxlan_tunnel_dump()
58 for t in ts:
59 if t.tunnel.vni == vni:
60 return True
61 return False
62
63
Neale Rannsbc27d1b2018-02-05 01:13:38 -080064class VppGbpEndpoint(VppObject):
65 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +020066 GBP Endpoint
Neale Rannsbc27d1b2018-02-05 01:13:38 -080067 """
68
Neale Ranns25b04942018-04-04 09:34:50 -070069 @property
70 def bin_mac(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -070071 return self.vmac.bytes
72
73 @property
74 def mac(self):
75 return self.vmac.address
Neale Ranns25b04942018-04-04 09:34:50 -070076
77 @property
78 def mac(self):
79 return self.itf.remote_mac
80
Neale Rannsc0a93142018-09-05 15:42:26 -070081 @property
82 def ip4(self):
83 return self._ip4
84
85 @property
86 def fip4(self):
87 return self._fip4
88
89 @property
90 def ip6(self):
91 return self._ip6
92
93 @property
94 def fip6(self):
95 return self._fip6
96
97 @property
98 def ips(self):
99 return [self.ip4, self.ip6]
100
101 @property
102 def fips(self):
103 return [self.fip4, self.fip6]
104
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700105 def __init__(self, test, itf, epg, recirc, ip4, fip4, ip6, fip6,
106 flags=0,
107 tun_src="0.0.0.0",
108 tun_dst="0.0.0.0",
109 mac=True):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800110 self._test = test
Neale Ranns25b04942018-04-04 09:34:50 -0700111 self.itf = itf
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800112 self.epg = epg
Neale Ranns25b04942018-04-04 09:34:50 -0700113 self.recirc = recirc
Neale Rannsc0a93142018-09-05 15:42:26 -0700114
115 self._ip4 = VppIpAddress(ip4)
116 self._fip4 = VppIpAddress(fip4)
117 self._ip6 = VppIpAddress(ip6)
118 self._fip6 = VppIpAddress(fip6)
119
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700120 if mac:
121 self.vmac = VppMacAddress(self.itf.remote_mac)
122 else:
123 self.vmac = VppMacAddress("00:00:00:00:00:00")
124
125 self.flags = flags
126 self.tun_src = VppIpAddress(tun_src)
127 self.tun_dst = VppIpAddress(tun_dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800128
129 def add_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700130 res = self._test.vapi.gbp_endpoint_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700131 self.itf.sw_if_index,
Neale Rannsc0a93142018-09-05 15:42:26 -0700132 [self.ip4.encode(), self.ip6.encode()],
133 self.vmac.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700134 self.epg.epg,
135 self.flags,
136 self.tun_src.encode(),
137 self.tun_dst.encode())
Neale Rannsc0a93142018-09-05 15:42:26 -0700138 self.handle = res.handle
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800139 self._test.registry.register(self, self._test.logger)
140
141 def remove_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700142 self._test.vapi.gbp_endpoint_del(self.handle)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800143
144 def __str__(self):
145 return self.object_id()
146
147 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700148 return "gbp-endpoint:[%d==%d:%s:%d]" % (self.handle,
149 self.itf.sw_if_index,
150 self.ip4.address,
151 self.epg.epg)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800152
153 def query_vpp_config(self):
Neale Rannsc0a93142018-09-05 15:42:26 -0700154 return find_gbp_endpoint(self._test,
155 self.itf.sw_if_index,
156 self.ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700157
158
159class VppGbpRecirc(VppObject):
160 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200161 GBP Recirculation Interface
Neale Ranns25b04942018-04-04 09:34:50 -0700162 """
163
164 def __init__(self, test, epg, recirc, is_ext=False):
165 self._test = test
166 self.recirc = recirc
167 self.epg = epg
168 self.is_ext = is_ext
169
170 def add_vpp_config(self):
171 self._test.vapi.gbp_recirc_add_del(
172 1,
173 self.recirc.sw_if_index,
174 self.epg.epg,
175 self.is_ext)
176 self._test.registry.register(self, self._test.logger)
177
178 def remove_vpp_config(self):
179 self._test.vapi.gbp_recirc_add_del(
180 0,
181 self.recirc.sw_if_index,
182 self.epg.epg,
183 self.is_ext)
184
185 def __str__(self):
186 return self.object_id()
187
188 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
199class VppGbpSubnet(VppObject):
200 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200201 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700202 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700203 def __init__(self, test, rd, address, address_len,
204 type, sw_if_index=None, epg=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700205 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700206 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200207 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700208 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700209 self.sw_if_index = sw_if_index
210 self.epg = epg
211
212 def add_vpp_config(self):
213 self._test.vapi.gbp_subnet_add_del(
214 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700215 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200216 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700217 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700218 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Rannsc0a93142018-09-05 15:42:26 -0700219 epg_id=self.epg if self.epg else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700220 self._test.registry.register(self, self._test.logger)
221
222 def remove_vpp_config(self):
223 self._test.vapi.gbp_subnet_add_del(
224 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700225 self.rd_id,
226 self.prefix.encode(),
227 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700228
229 def __str__(self):
230 return self.object_id()
231
232 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700233 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700234
235 def query_vpp_config(self):
236 ss = self._test.vapi.gbp_subnet_dump()
237 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700238 if s.subnet.rd_id == self.rd_id and \
239 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200240 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700241 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700242 return False
243
244
245class VppGbpEndpointGroup(VppObject):
246 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200247 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700248 """
249
250 def __init__(self, test, epg, rd, bd, uplink,
251 bvi, bvi_ip4, bvi_ip6=None):
252 self._test = test
253 self.uplink = uplink
254 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700255 self.bvi_ip4 = VppIpAddress(bvi_ip4)
256 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns25b04942018-04-04 09:34:50 -0700257 self.epg = epg
258 self.bd = bd
259 self.rd = rd
260
261 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700262 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700263 self.epg,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700264 self.bd.bd.bd_id,
265 self.rd.rd_id,
266 self.uplink.sw_if_index if self.uplink else INDEX_INVALID)
Neale Ranns25b04942018-04-04 09:34:50 -0700267 self._test.registry.register(self, self._test.logger)
268
269 def remove_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700270 self._test.vapi.gbp_endpoint_group_del(
271 self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700272
273 def __str__(self):
274 return self.object_id()
275
276 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700277 return "gbp-endpoint-group:[%d]" % (self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700278
279 def query_vpp_config(self):
280 epgs = self._test.vapi.gbp_endpoint_group_dump()
281 for epg in epgs:
282 if epg.epg.epg_id == self.epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800283 return True
284 return False
285
286
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700287class VppGbpBridgeDomain(VppObject):
288 """
289 GBP Bridge Domain
290 """
291
Neale Rannsc29c0af2018-11-07 04:21:12 -0800292 def __init__(self, test, bd, bvi, uu_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700293 self._test = test
294 self.bvi = bvi
295 self.uu_flood = uu_flood
296 self.bd = bd
297
Neale Rannsc29c0af2018-11-07 04:21:12 -0800298 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
299 if (learn):
300 self.learn = e.GBP_BD_API_FLAG_NONE
301 else:
302 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
303
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700304 def add_vpp_config(self):
305 self._test.vapi.gbp_bridge_domain_add(
306 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800307 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700308 self.bvi.sw_if_index,
309 self.uu_flood.sw_if_index if self.uu_flood else INDEX_INVALID)
310 self._test.registry.register(self, self._test.logger)
311
312 def remove_vpp_config(self):
313 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
314
315 def __str__(self):
316 return self.object_id()
317
318 def object_id(self):
319 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
320
321 def query_vpp_config(self):
322 bds = self._test.vapi.gbp_bridge_domain_dump()
323 for bd in bds:
324 if bd.bd.bd_id == self.bd.bd_id:
325 return True
326 return False
327
328
329class VppGbpRouteDomain(VppObject):
330 """
331 GBP Route Domain
332 """
333
334 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
335 self._test = test
336 self.rd_id = rd_id
337 self.t4 = t4
338 self.t6 = t6
339 self.ip4_uu = ip4_uu
340 self.ip6_uu = ip6_uu
341
342 def add_vpp_config(self):
343 self._test.vapi.gbp_route_domain_add(
344 self.rd_id,
345 self.t4.table_id,
346 self.t6.table_id,
347 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
348 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
349 self._test.registry.register(self, self._test.logger)
350
351 def remove_vpp_config(self):
352 self._test.vapi.gbp_route_domain_del(self.rd_id)
353
354 def __str__(self):
355 return self.object_id()
356
357 def object_id(self):
358 return "gbp-route-domain:[%d]" % (self.rd_id)
359
360 def query_vpp_config(self):
361 rds = self._test.vapi.gbp_route_domain_dump()
362 for rd in rds:
363 if rd.rd.rd_id == self.rd_id:
364 return True
365 return False
366
367
Neale Ranns13a08cc2018-11-07 09:25:54 -0800368class VppGbpContractNextHop():
369 def __init__(self, mac, bd, ip, rd):
370 self.mac = mac
371 self.ip = ip
372 self.bd = bd
373 self.rd = rd
374
375 def encode(self):
376 return {'ip': self.ip.encode(),
377 'mac': self.mac.encode(),
378 'bd_id': self.bd.bd.bd_id,
379 'rd_id': self.rd.rd_id}
380
381
382class VppGbpContractRule():
383 def __init__(self, action, nhs=[]):
384 self.action = action
385 self.nhs = nhs
386 e = VppEnum.vl_api_gbp_hash_mode_t
387 self.hash_mode = e.GBP_API_HASH_MODE_SRC_IP
388
389 def encode(self):
390 nhs = []
391 for nh in self.nhs:
392 nhs.append(nh.encode())
393 while len(nhs) < 8:
394 nhs.append({})
395 return {'action': self.action,
396 'nh_set': {
397 'hash_mode': self.hash_mode,
398 'n_nhs': len(self.nhs),
399 'nhs': nhs}}
400
401
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800402class VppGbpContract(VppObject):
403 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200404 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800405 """
406
Neale Ranns13a08cc2018-11-07 09:25:54 -0800407 def __init__(self, test, src_epg, dst_epg, acl_index, rules=[]):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800408 self._test = test
409 self.acl_index = acl_index
410 self.src_epg = src_epg
411 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800412 self.rules = rules
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800413
414 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800415 rules = []
416 for r in self.rules:
417 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800418 self._test.vapi.gbp_contract_add_del(
419 1,
420 self.src_epg,
421 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800422 self.acl_index,
423 rules)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800424 self._test.registry.register(self, self._test.logger)
425
426 def remove_vpp_config(self):
427 self._test.vapi.gbp_contract_add_del(
428 0,
429 self.src_epg,
430 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800431 self.acl_index,
432 [])
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800433
434 def __str__(self):
435 return self.object_id()
436
437 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700438 return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800439 self.dst_epg,
440 self.acl_index)
441
442 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700443 cs = self._test.vapi.gbp_contract_dump()
444 for c in cs:
445 if c.contract.src_epg == self.src_epg \
446 and c.contract.dst_epg == self.dst_epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800447 return True
448 return False
449
450
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700451class VppGbpVxlanTunnel(VppInterface):
452 """
453 GBP VXLAN tunnel
454 """
455
456 def __init__(self, test, vni, bd_rd_id, mode):
457 super(VppGbpVxlanTunnel, self).__init__(test)
458 self._test = test
459 self.vni = vni
460 self.bd_rd_id = bd_rd_id
461 self.mode = mode
462
463 def add_vpp_config(self):
464 r = self._test.vapi.gbp_vxlan_tunnel_add(
465 self.vni,
466 self.bd_rd_id,
467 self.mode)
468 self.set_sw_if_index(r.sw_if_index)
469 self._test.registry.register(self, self._test.logger)
470
471 def remove_vpp_config(self):
472 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
473
474 def __str__(self):
475 return self.object_id()
476
477 def object_id(self):
478 return "gbp-vxlan:%d" % (self.vni)
479
480 def query_vpp_config(self):
481 return find_gbp_vxlan(self._test, self.vni)
482
483
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200484class VppGbpAcl(VppObject):
485 """
486 GBP Acl
487 """
488
489 def __init__(self, test):
490 self._test = test
491 self.acl_index = 4294967295
492
493 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
494 s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
495 sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
496 dport_from=0, dport_to=65535):
497 if proto == -1 or proto == 0:
498 sport_to = 0
499 dport_to = sport_to
500 elif proto == 1 or proto == 58:
501 sport_to = 255
502 dport_to = sport_to
503 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
504 'srcport_or_icmptype_first': sport_from,
505 'srcport_or_icmptype_last': sport_to,
506 'src_ip_prefix_len': s_prefix,
507 'src_ip_addr': s_ip,
508 'dstport_or_icmpcode_first': dport_from,
509 'dstport_or_icmpcode_last': dport_to,
510 'dst_ip_prefix_len': d_prefix,
511 'dst_ip_addr': d_ip})
512 return rule
513
514 def add_vpp_config(self, rules):
515
516 reply = self._test.vapi.acl_add_replace(self.acl_index,
517 r=rules,
518 tag='GBPTest')
519 self.acl_index = reply.acl_index
520 return self.acl_index
521
522 def remove_vpp_config(self):
523 self._test.vapi.acl_del(self.acl_index)
524
525 def __str__(self):
526 return self.object_id()
527
528 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700529 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200530
531 def query_vpp_config(self):
532 cs = self._test.vapi.acl_dump()
533 for c in cs:
534 if c.acl_index == self.acl_index:
535 return True
536 return False
537
538
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800539class TestGBP(VppTestCase):
540 """ GBP Test Case """
541
542 def setUp(self):
543 super(TestGBP, self).setUp()
544
Neale Ranns25b04942018-04-04 09:34:50 -0700545 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700546 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700547
Neale Ranns4d5b9172018-10-24 02:57:49 -0700548 self.router_mac = VppMacAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800549
550 for i in self.pg_interfaces:
551 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700552 for i in self.lo_interfaces:
553 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800554
555 def tearDown(self):
556 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700557 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800558
559 super(TestGBP, self).tearDown()
560
Neale Ranns25b04942018-04-04 09:34:50 -0700561 def send_and_expect_bridged(self, src, tx, dst):
562 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800563
Neale Ranns25b04942018-04-04 09:34:50 -0700564 for r in rx:
565 self.assertEqual(r[Ether].src, tx[0][Ether].src)
566 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
567 self.assertEqual(r[IP].src, tx[0][IP].src)
568 self.assertEqual(r[IP].dst, tx[0][IP].dst)
569 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800570
Neale Ranns25b04942018-04-04 09:34:50 -0700571 def send_and_expect_bridged6(self, src, tx, dst):
572 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800573
Neale Ranns25b04942018-04-04 09:34:50 -0700574 for r in rx:
575 self.assertEqual(r[Ether].src, tx[0][Ether].src)
576 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
577 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
578 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
579 return rx
580
581 def send_and_expect_routed(self, src, tx, dst, src_mac):
582 rx = self.send_and_expect(src, tx, dst)
583
584 for r in rx:
585 self.assertEqual(r[Ether].src, src_mac)
586 self.assertEqual(r[Ether].dst, dst.remote_mac)
587 self.assertEqual(r[IP].src, tx[0][IP].src)
588 self.assertEqual(r[IP].dst, tx[0][IP].dst)
589 return rx
590
591 def send_and_expect_natted(self, src, tx, dst, src_ip):
592 rx = self.send_and_expect(src, tx, dst)
593
594 for r in rx:
595 self.assertEqual(r[Ether].src, tx[0][Ether].src)
596 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
597 self.assertEqual(r[IP].src, src_ip)
598 self.assertEqual(r[IP].dst, tx[0][IP].dst)
599 return rx
600
Neale Ranns4a6d0232018-04-24 07:45:33 -0700601 def send_and_expect_natted6(self, src, tx, dst, src_ip):
602 rx = self.send_and_expect(src, tx, dst)
603
604 for r in rx:
605 self.assertEqual(r[Ether].src, tx[0][Ether].src)
606 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
607 self.assertEqual(r[IPv6].src, src_ip)
608 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
609 return rx
610
Neale Ranns25b04942018-04-04 09:34:50 -0700611 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
612 rx = self.send_and_expect(src, tx, dst)
613
614 for r in rx:
615 self.assertEqual(r[Ether].src, tx[0][Ether].src)
616 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
617 self.assertEqual(r[IP].dst, dst_ip)
618 self.assertEqual(r[IP].src, tx[0][IP].src)
619 return rx
620
Neale Ranns4a6d0232018-04-24 07:45:33 -0700621 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
622 rx = self.send_and_expect(src, tx, dst)
623
624 for r in rx:
625 self.assertEqual(r[Ether].src, tx[0][Ether].src)
626 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
627 self.assertEqual(r[IPv6].dst, dst_ip)
628 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
629 return rx
630
Neale Ranns25b04942018-04-04 09:34:50 -0700631 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
632 rx = self.send_and_expect(src, tx, dst)
633
634 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700635 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700636 self.assertEqual(r[Ether].dst, dst.remote_mac)
637 self.assertEqual(r[IP].dst, dst_ip)
638 self.assertEqual(r[IP].src, src_ip)
639 return rx
640
Neale Ranns4a6d0232018-04-24 07:45:33 -0700641 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
642 rx = self.send_and_expect(src, tx, dst)
643
644 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700645 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700646 self.assertEqual(r[Ether].dst, dst.remote_mac)
647 self.assertEqual(r[IPv6].dst, dst_ip)
648 self.assertEqual(r[IPv6].src, src_ip)
649 return rx
650
Neale Ranns25b04942018-04-04 09:34:50 -0700651 def test_gbp(self):
652 """ Group Based Policy """
653
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800654 #
Neale Ranns25b04942018-04-04 09:34:50 -0700655 # Bridge Domains
656 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700657 bd1 = VppBridgeDomain(self, 1)
658 bd2 = VppBridgeDomain(self, 2)
659 bd20 = VppBridgeDomain(self, 20)
660
661 bd1.add_vpp_config()
662 bd2.add_vpp_config()
663 bd20.add_vpp_config()
664
665 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
666 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
667 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
668
669 gbd1.add_vpp_config()
670 gbd2.add_vpp_config()
671 gbd20.add_vpp_config()
672
673 #
674 # Route Domains
675 #
676 gt4 = VppIpTable(self, 0)
677 gt4.add_vpp_config()
678 gt6 = VppIpTable(self, 0, is_ip6=True)
679 gt6.add_vpp_config()
680 nt4 = VppIpTable(self, 20)
681 nt4.add_vpp_config()
682 nt6 = VppIpTable(self, 20, is_ip6=True)
683 nt6.add_vpp_config()
684
685 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
686 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
687
688 rd0.add_vpp_config()
689 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700690
691 #
692 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700693 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
694 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700695 epgs = [VppGbpEndpointGroup(self, 220, rd0, gbd1, self.pg4,
Neale Rannsc0a93142018-09-05 15:42:26 -0700696 self.loop0,
697 "10.0.0.128",
698 "2001:10::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700699 VppGbpEndpointGroup(self, 221, rd0, gbd1, self.pg5,
Neale Rannsc0a93142018-09-05 15:42:26 -0700700 self.loop0,
701 "10.0.1.128",
702 "2001:10:1::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700703 VppGbpEndpointGroup(self, 222, rd0, gbd2, self.pg6,
Neale Rannsc0a93142018-09-05 15:42:26 -0700704 self.loop1,
705 "10.0.2.128",
706 "2001:10:2::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700707 VppGbpEndpointGroup(self, 333, rd20, gbd20, self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -0700708 self.loop2,
709 "11.0.0.128",
710 "3001::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700711 VppGbpEndpointGroup(self, 444, rd20, gbd20, self.pg8,
Neale Rannsc0a93142018-09-05 15:42:26 -0700712 self.loop2,
713 "11.0.0.129",
714 "3001::129")]
715 recircs = [VppGbpRecirc(self, epgs[0],
716 self.loop3),
717 VppGbpRecirc(self, epgs[1],
718 self.loop4),
719 VppGbpRecirc(self, epgs[2],
720 self.loop5),
721 VppGbpRecirc(self, epgs[3],
722 self.loop6, is_ext=True),
723 VppGbpRecirc(self, epgs[4],
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700724 self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700725
726 epg_nat = epgs[3]
727 recirc_nat = recircs[3]
728
729 #
730 # 4 end-points, 2 in the same subnet, 3 in the same BD
731 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700732 eps = [VppGbpEndpoint(self, self.pg0,
733 epgs[0], recircs[0],
734 "10.0.0.1", "11.0.0.1",
735 "2001:10::1", "3001::1"),
736 VppGbpEndpoint(self, self.pg1,
737 epgs[0], recircs[0],
738 "10.0.0.2", "11.0.0.2",
739 "2001:10::2", "3001::2"),
740 VppGbpEndpoint(self, self.pg2,
741 epgs[1], recircs[1],
742 "10.0.1.1", "11.0.0.3",
743 "2001:10:1::1", "3001::3"),
744 VppGbpEndpoint(self, self.pg3,
745 epgs[2], recircs[2],
746 "10.0.2.1", "11.0.0.4",
747 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700748
749 #
750 # Config related to each of the EPGs
751 #
752 for epg in epgs:
753 # IP config on the BVI interfaces
754 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700755 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
756 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
757 self.vapi.sw_interface_set_mac_address(
758 epg.bvi.sw_if_index,
759 self.router_mac.bytes)
Neale Ranns25b04942018-04-04 09:34:50 -0700760
761 # The BVIs are NAT inside interfaces
762 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
763 is_inside=1,
764 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700765 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
766 is_inside=1,
767 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700768
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700769 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
770 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
771 if_ip4.add_vpp_config()
772 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700773
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700774 # EPG uplink interfaces in the RD
775 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
776 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700777
778 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700779 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
780 self.router_mac.address,
781 epg.bvi_ip4)
782 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
783 self.router_mac.address,
784 epg.bvi_ip6)
785 epg.bd_arp_ip4.add_vpp_config()
786 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700787
788 # EPG in VPP
789 epg.add_vpp_config()
790
791 for recirc in recircs:
792 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700793 VppIpInterfaceBind(self, recirc.recirc,
794 recirc.epg.rd.t4).add_vpp_config()
795 VppIpInterfaceBind(self, recirc.recirc,
796 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700797
Neale Ranns25b04942018-04-04 09:34:50 -0700798 self.vapi.sw_interface_set_l2_emulation(
799 recirc.recirc.sw_if_index)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700800 self.vapi.nat44_interface_add_del_feature(
801 recirc.recirc.sw_if_index,
802 is_inside=0,
803 is_add=1)
804 self.vapi.nat66_add_del_interface(
805 recirc.recirc.sw_if_index,
806 is_inside=0,
807 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700808
809 recirc.add_vpp_config()
810
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700811 for recirc in recircs:
812 self.assertTrue(find_bridge_domain_port(self,
813 recirc.epg.bd.bd.bd_id,
814 recirc.recirc.sw_if_index))
815
Neale Ranns25b04942018-04-04 09:34:50 -0700816 for ep in eps:
817 self.pg_enable_capture(self.pg_interfaces)
818 self.pg_start()
819 #
820 # routes to the endpoints. We need these since there are no
821 # adj-fibs due to the fact the the BVI address has /32 and
822 # the subnet is not attached.
823 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700824 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700825 # Add static mappings for each EP from the 10/8 to 11/8 network
826 if ip.af == AF_INET:
827 self.vapi.nat44_add_del_static_mapping(ip.bytes,
828 fip.bytes,
829 vrf_id=0,
830 addr_only=1)
831 else:
832 self.vapi.nat66_add_del_static_mapping(ip.bytes,
833 fip.bytes,
834 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700835
Neale Ranns25b04942018-04-04 09:34:50 -0700836 # VPP EP create ...
837 ep.add_vpp_config()
838
Neale Rannsc0a93142018-09-05 15:42:26 -0700839 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700840
Neale Rannsc0a93142018-09-05 15:42:26 -0700841 # ... results in a Gratuitous ARP/ND on the EPG's uplink
842 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
843
844 for ii, ip in enumerate(ep.ips):
845 p = rx[ii]
846
847 if ip.is_ip6:
848 self.assertTrue(p.haslayer(ICMPv6ND_NA))
849 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
850 else:
851 self.assertTrue(p.haslayer(ARP))
852 self.assertEqual(p[ARP].psrc, ip.address)
853 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700854
855 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700856 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700857 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
858 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700859
Neale Rannsc0a93142018-09-05 15:42:26 -0700860 # floating IPs route via EPG recirc
861 r = VppIpRoute(self, fip.address, fip.length,
862 [VppRoutePath(fip.address,
863 ep.recirc.recirc.sw_if_index,
864 is_dvr=1,
865 proto=fip.dpo_proto)],
866 table_id=20,
867 is_ip6=fip.is_ip6)
868 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700869
870 # L2 FIB entries in the NAT EPG BD to bridge the packets from
871 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700872 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
873 ep.recirc.recirc, bvi_mac=0)
874 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700875
876 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700877 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700878 #
879 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
880 src=self.pg0.remote_mac) /
881 ARP(op="who-has",
882 hwdst="ff:ff:ff:ff:ff:ff",
883 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700884 pdst="10.0.0.88",
885 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700886
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700887 self.vapi.cli("clear trace")
888 self.pg0.add_stream(pkt_arp)
889
890 self.pg_enable_capture(self.pg_interfaces)
891 self.pg_start()
892
893 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700894
895 #
896 # ARP/ND packets get a response
897 #
898 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
899 src=self.pg0.remote_mac) /
900 ARP(op="who-has",
901 hwdst="ff:ff:ff:ff:ff:ff",
902 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700903 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700904 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700905
906 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
907
Neale Rannsc0a93142018-09-05 15:42:26 -0700908 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700909 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700910 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
911 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700912 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700913 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700914 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
915 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
916
917 #
918 # broadcast packets are flooded
919 #
920 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
921 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700922 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700923 UDP(sport=1234, dport=1234) /
924 Raw('\xa5' * 100))
925
926 self.vapi.cli("clear trace")
927 self.pg0.add_stream(pkt_bcast)
928
929 self.pg_enable_capture(self.pg_interfaces)
930 self.pg_start()
931
932 rxd = eps[1].itf.get_capture(1)
933 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
934 rxd = epgs[0].uplink.get_capture(1)
935 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
936
937 #
938 # packets to non-local L3 destinations dropped
939 #
940 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700941 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700942 IP(src=eps[0].ip4.address,
943 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700944 UDP(sport=1234, dport=1234) /
945 Raw('\xa5' * 100))
946 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700947 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700948 IP(src=eps[0].ip4.address,
949 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700950 UDP(sport=1234, dport=1234) /
951 Raw('\xa5' * 100))
952
953 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
954
955 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700956 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700957 IPv6(src=eps[0].ip6.address,
958 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700959 UDP(sport=1234, dport=1234) /
960 Raw('\xa5' * 100))
961 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
962
963 #
964 # Add the subnet routes
965 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700966 s41 = VppGbpSubnet(
967 self, rd0, "10.0.0.0", 24,
968 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
969 s42 = VppGbpSubnet(
970 self, rd0, "10.0.1.0", 24,
971 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
972 s43 = VppGbpSubnet(
973 self, rd0, "10.0.2.0", 24,
974 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
975 s61 = VppGbpSubnet(
976 self, rd0, "2001:10::1", 64,
977 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
978 s62 = VppGbpSubnet(
979 self, rd0, "2001:10:1::1", 64,
980 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
981 s63 = VppGbpSubnet(
982 self, rd0, "2001:10:2::1", 64,
983 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -0700984 s41.add_vpp_config()
985 s42.add_vpp_config()
986 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700987 s61.add_vpp_config()
988 s62.add_vpp_config()
989 s63.add_vpp_config()
990
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700991 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700992 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700993 eps[0].epg.uplink)
994 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700995 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700996 eps[0].epg.uplink)
997 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700998 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700999 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001000
1001 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1002 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1003 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1004 self.logger.info(self.vapi.cli("sh gbp recirc"))
1005 self.logger.info(self.vapi.cli("sh int"))
1006 self.logger.info(self.vapi.cli("sh int addr"))
1007 self.logger.info(self.vapi.cli("sh int feat loop6"))
1008 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1009 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001010 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001011
1012 #
1013 # Packet destined to unknown unicast is sent on the epg uplink ...
1014 #
1015 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1016 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001017 IP(src=eps[0].ip4.address,
1018 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001019 UDP(sport=1234, dport=1234) /
1020 Raw('\xa5' * 100))
1021
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001022 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001023 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001024 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001025 # ... and nowhere else
1026 self.pg1.get_capture(0, timeout=0.1)
1027 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1028
1029 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1030 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001031 IP(src=eps[0].ip4.address,
1032 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001033 UDP(sport=1234, dport=1234) /
1034 Raw('\xa5' * 100))
1035
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001036 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001037 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001038 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001039
1040 #
1041 # Packets from the uplink are forwarded in the absence of a contract
1042 #
1043 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1044 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001045 IP(src=eps[0].ip4.address,
1046 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001047 UDP(sport=1234, dport=1234) /
1048 Raw('\xa5' * 100))
1049
1050 self.send_and_expect_bridged(self.pg4,
1051 pkt_intra_epg_220_from_uplink * 65,
1052 self.pg0)
1053
1054 #
1055 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001056 # can communicate
1057 #
1058 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001059 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001060 IP(src=eps[0].ip4.address,
1061 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001062 UDP(sport=1234, dport=1234) /
1063 Raw('\xa5' * 100))
1064
Neale Ranns25b04942018-04-04 09:34:50 -07001065 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001066
1067 #
1068 # in the abscense of policy, endpoints in the different EPG
1069 # cannot communicate
1070 #
1071 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001072 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001073 IP(src=eps[0].ip4.address,
1074 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001075 UDP(sport=1234, dport=1234) /
1076 Raw('\xa5' * 100))
1077 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001078 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001079 IP(src=eps[2].ip4.address,
1080 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001081 UDP(sport=1234, dport=1234) /
1082 Raw('\xa5' * 100))
1083 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001084 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001085 IP(src=eps[0].ip4.address,
1086 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001087 UDP(sport=1234, dport=1234) /
1088 Raw('\xa5' * 100))
1089
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001090 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001091 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001092 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001093 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001094
1095 #
1096 # A uni-directional contract from EPG 220 -> 221
1097 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001098 acl = VppGbpAcl(self)
1099 rule = acl.create_rule(permit_deny=1, proto=17)
1100 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1101 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001102 c1 = VppGbpContract(
1103 self, 220, 221, acl_index,
1104 [VppGbpContractRule(
1105 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1106 []),
1107 VppGbpContractRule(
1108 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1109 [])])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001110 c1.add_vpp_config()
1111
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001112 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001113 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001114 eps[2].itf)
1115 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001116 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001117
1118 #
1119 # contract for the return direction
1120 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001121 c2 = VppGbpContract(
1122 self, 221, 220, acl_index,
1123 [VppGbpContractRule(
1124 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1125 []),
1126 VppGbpContractRule(
1127 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1128 [])])
1129
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001130 c2.add_vpp_config()
1131
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001132 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001133 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001134 eps[2].itf)
1135 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001136 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001137 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001138
1139 #
1140 # check that inter group is still disabled for the groups
1141 # not in the contract.
1142 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001143 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001144 pkt_inter_epg_220_to_222 * 65)
1145
Neale Ranns25b04942018-04-04 09:34:50 -07001146 #
1147 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1148 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001149 c3 = VppGbpContract(
1150 self, 220, 222, acl_index,
1151 [VppGbpContractRule(
1152 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1153 []),
1154 VppGbpContractRule(
1155 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1156 [])])
1157
Neale Ranns25b04942018-04-04 09:34:50 -07001158 c3.add_vpp_config()
1159
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001160 self.logger.info(self.vapi.cli("sh gbp contract"))
1161
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001162 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001163 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001164 eps[3].itf,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001165 self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001166
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001167 #
1168 # remove both contracts, traffic stops in both directions
1169 #
1170 c2.remove_vpp_config()
1171 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001172 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001173 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001174
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001175 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001176 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001177 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001178 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001179 self.send_and_expect_bridged(eps[0].itf,
1180 pkt_intra_epg * 65,
1181 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001182
1183 #
Neale Ranns25b04942018-04-04 09:34:50 -07001184 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001185 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001186
Neale Ranns25b04942018-04-04 09:34:50 -07001187 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001188 se1 = VppGbpSubnet(
1189 self, rd0, "0.0.0.0", 0,
1190 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1191 sw_if_index=recirc_nat.recirc.sw_if_index,
1192 epg=epg_nat.epg)
1193 se2 = VppGbpSubnet(
1194 self, rd0, "11.0.0.0", 8,
1195 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1196 sw_if_index=recirc_nat.recirc.sw_if_index,
1197 epg=epg_nat.epg)
1198 se16 = VppGbpSubnet(
1199 self, rd0, "::", 0,
1200 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1201 sw_if_index=recirc_nat.recirc.sw_if_index,
1202 epg=epg_nat.epg)
Neale Ranns25b04942018-04-04 09:34:50 -07001203 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001204 se3 = VppGbpSubnet(
1205 self, rd20, "0.0.0.0", 0,
1206 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1207 sw_if_index=epg_nat.uplink.sw_if_index,
1208 epg=epg_nat.epg)
1209 se36 = VppGbpSubnet(
1210 self, rd20, "::", 0,
1211 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1212 sw_if_index=epg_nat.uplink.sw_if_index,
1213 epg=epg_nat.epg)
1214 se4 = VppGbpSubnet(
1215 self, rd20, "11.0.0.0", 8,
1216 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1217 sw_if_index=epg_nat.uplink.sw_if_index,
1218 epg=epg_nat.epg)
1219 se1.add_vpp_config()
1220 se2.add_vpp_config()
1221 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001222 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001223 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001224 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001225
Neale Ranns25b04942018-04-04 09:34:50 -07001226 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1227 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001228 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1229 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001230 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001231
Neale Ranns4a6d0232018-04-24 07:45:33 -07001232 #
1233 # From an EP to an outside addess: IN2OUT
1234 #
Neale Ranns25b04942018-04-04 09:34:50 -07001235 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001236 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001237 IP(src=eps[0].ip4.address,
1238 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001239 UDP(sport=1234, dport=1234) /
1240 Raw('\xa5' * 100))
1241
1242 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001243 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001244 pkt_inter_epg_220_to_global * 65)
1245
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001246 acl2 = VppGbpAcl(self)
1247 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1248 sport_to=1234, dport_from=1234, dport_to=1234)
1249 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1250 sport_from=1234, sport_to=1234,
1251 dport_from=1234, dport_to=1234)
1252
1253 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001254 c4 = VppGbpContract(
1255 self, 220, 333, acl_index2,
1256 [VppGbpContractRule(
1257 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1258 []),
1259 VppGbpContractRule(
1260 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1261 [])])
1262
Neale Ranns25b04942018-04-04 09:34:50 -07001263 c4.add_vpp_config()
1264
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001265 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001266 pkt_inter_epg_220_to_global * 65,
1267 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001268 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001269
Neale Ranns4a6d0232018-04-24 07:45:33 -07001270 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001271 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001272 IPv6(src=eps[0].ip6.address,
1273 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001274 UDP(sport=1234, dport=1234) /
1275 Raw('\xa5' * 100))
1276
1277 self.send_and_expect_natted6(self.pg0,
1278 pkt_inter_epg_220_to_global * 65,
1279 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001280 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001281
1282 #
1283 # From a global address to an EP: OUT2IN
1284 #
Neale Ranns4d5b9172018-10-24 02:57:49 -07001285 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001286 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001287 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001288 src="1.1.1.1") /
1289 UDP(sport=1234, dport=1234) /
1290 Raw('\xa5' * 100))
1291
1292 self.send_and_assert_no_replies(self.pg7,
1293 pkt_inter_epg_220_from_global * 65)
1294
Neale Ranns13a08cc2018-11-07 09:25:54 -08001295 c5 = VppGbpContract(
1296 self, 333, 220, acl_index2,
1297 [VppGbpContractRule(
1298 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1299 []),
1300 VppGbpContractRule(
1301 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1302 [])])
1303
Neale Ranns25b04942018-04-04 09:34:50 -07001304 c5.add_vpp_config()
1305
1306 self.send_and_expect_unnatted(self.pg7,
1307 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001308 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001309 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001310
Neale Ranns4d5b9172018-10-24 02:57:49 -07001311 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001312 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001313 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001314 src="6001::1") /
1315 UDP(sport=1234, dport=1234) /
1316 Raw('\xa5' * 100))
1317
1318 self.send_and_expect_unnatted6(self.pg7,
1319 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001320 eps[0].itf,
1321 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001322
1323 #
1324 # From a local VM to another local VM using resp. public addresses:
1325 # IN2OUT2IN
1326 #
Neale Ranns25b04942018-04-04 09:34:50 -07001327 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001328 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001329 IP(src=eps[0].ip4.address,
1330 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001331 UDP(sport=1234, dport=1234) /
1332 Raw('\xa5' * 100))
1333
Neale Ranns4a6d0232018-04-24 07:45:33 -07001334 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001335 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001336 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001337 eps[0].fip4.address,
1338 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001339
Neale Rannsc0a93142018-09-05 15:42:26 -07001340 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001341 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001342 IPv6(src=eps[0].ip6.address,
1343 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001344 UDP(sport=1234, dport=1234) /
1345 Raw('\xa5' * 100))
1346
Neale Rannsc0a93142018-09-05 15:42:26 -07001347 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001348 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001349 eps[1].itf,
1350 eps[0].fip6.address,
1351 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001352
1353 #
Neale Ranns25b04942018-04-04 09:34:50 -07001354 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001355 #
Neale Ranns25b04942018-04-04 09:34:50 -07001356 for ep in eps:
1357 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001358 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1359 ep.fip4.bytes,
1360 vrf_id=0,
1361 addr_only=1,
1362 is_add=0)
1363 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1364 ep.fip6.bytes,
1365 vrf_id=0,
1366 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001367
Neale Ranns25b04942018-04-04 09:34:50 -07001368 for epg in epgs:
1369 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001370 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001371 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1372 is_inside=1,
1373 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001374 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1375 is_inside=1,
1376 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001377
Neale Ranns25b04942018-04-04 09:34:50 -07001378 for recirc in recircs:
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001379 self.vapi.sw_interface_set_l2_emulation(
1380 recirc.recirc.sw_if_index, enable=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001381 self.vapi.nat44_interface_add_del_feature(
1382 recirc.recirc.sw_if_index,
1383 is_inside=0,
1384 is_add=0)
1385 self.vapi.nat66_add_del_interface(
1386 recirc.recirc.sw_if_index,
1387 is_inside=0,
1388 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001389
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001390 def test_gbp_learn_l2(self):
1391 """ GBP L2 Endpoint Learning """
1392
1393 learnt = [{'mac': '00:00:11:11:11:01',
1394 'ip': '10.0.0.1',
1395 'ip6': '2001:10::2'},
1396 {'mac': '00:00:11:11:11:02',
1397 'ip': '10.0.0.2',
1398 'ip6': '2001:10::3'}]
1399
1400 #
1401 # lower the inactive threshold so these tests pass in a
1402 # reasonable amount of time
1403 #
1404 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1405
1406 #
1407 # IP tables
1408 #
1409 gt4 = VppIpTable(self, 1)
1410 gt4.add_vpp_config()
1411 gt6 = VppIpTable(self, 1, is_ip6=True)
1412 gt6.add_vpp_config()
1413
1414 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1415 rd1.add_vpp_config()
1416
1417 #
1418 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1419 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1420 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1421 #
1422 self.pg2.config_ip4()
1423 self.pg2.resolve_arp()
1424 self.pg2.generate_remote_hosts(4)
1425 self.pg2.configure_ipv4_neighbors()
1426 self.pg3.config_ip4()
1427 self.pg3.resolve_arp()
1428 self.pg4.config_ip4()
1429 self.pg4.resolve_arp()
1430
1431 #
1432 # a GBP bridge domain with a BVI and a UU-flood interface
1433 #
1434 bd1 = VppBridgeDomain(self, 1)
1435 bd1.add_vpp_config()
1436 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
1437 gbd1.add_vpp_config()
1438
1439 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1440 self.logger.info(self.vapi.cli("sh gbp bridge"))
1441
1442 # ... and has a /32 applied
1443 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1444 ip_addr.add_vpp_config()
1445
1446 #
1447 # The Endpoint-group in which we are learning endpoints
1448 #
1449 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1450 None, self.loop0,
1451 "10.0.0.128",
1452 "2001:10::128")
1453 epg_220.add_vpp_config()
1454 epg_330 = VppGbpEndpointGroup(self, 330, rd1, gbd1,
1455 None, self.loop1,
1456 "10.0.1.128",
1457 "2001:11::128")
1458 epg_330.add_vpp_config()
1459
1460 #
1461 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1462 # leanring enabled
1463 #
1464 vx_tun_l2_1 = VppGbpVxlanTunnel(
1465 self, 99, bd1.bd_id,
1466 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1467 vx_tun_l2_1.add_vpp_config()
1468
1469 #
1470 # A static endpoint that the learnt endpoints are trying to
1471 # talk to
1472 #
1473 ep = VppGbpEndpoint(self, self.pg0,
1474 epg_220, None,
1475 "10.0.0.127", "11.0.0.127",
1476 "2001:10::1", "3001::1")
1477 ep.add_vpp_config()
1478
1479 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1480
1481 # a packet with an sclass from an unknwon EPG
1482 p = (Ether(src=self.pg2.remote_mac,
1483 dst=self.pg2.local_mac) /
1484 IP(src=self.pg2.remote_hosts[0].ip4,
1485 dst=self.pg2.local_ip4) /
1486 UDP(sport=1234, dport=48879) /
1487 VXLAN(vni=99, gpid=88, flags=0x88) /
1488 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1489 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1490 UDP(sport=1234, dport=1234) /
1491 Raw('\xa5' * 100))
1492
1493 self.send_and_assert_no_replies(self.pg2, p)
1494
1495 #
1496 # we should not have learnt a new tunnel endpoint, since
1497 # the EPG was not learnt.
1498 #
1499 self.assertEqual(INDEX_INVALID,
1500 find_vxlan_gbp_tunnel(self,
1501 self.pg2.local_ip4,
1502 self.pg2.remote_hosts[0].ip4,
1503 99))
1504
1505 # epg is not learnt, becasue the EPG is unknwon
1506 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1507
1508 for ii, l in enumerate(learnt):
1509 # a packet with an sclass from a knwon EPG
1510 # arriving on an unknown TEP
1511 p = (Ether(src=self.pg2.remote_mac,
1512 dst=self.pg2.local_mac) /
1513 IP(src=self.pg2.remote_hosts[1].ip4,
1514 dst=self.pg2.local_ip4) /
1515 UDP(sport=1234, dport=48879) /
1516 VXLAN(vni=99, gpid=220, flags=0x88) /
1517 Ether(src=l['mac'], dst=ep.mac) /
1518 IP(src=l['ip'], dst=ep.ip4.address) /
1519 UDP(sport=1234, dport=1234) /
1520 Raw('\xa5' * 100))
1521
1522 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1523
1524 # the new TEP
1525 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1526 self,
1527 self.pg2.local_ip4,
1528 self.pg2.remote_hosts[1].ip4,
1529 99)
1530 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1531
1532 #
1533 # the EP is learnt via the learnt TEP
1534 # both from its MAC and its IP
1535 #
1536 self.assertTrue(find_gbp_endpoint(self,
1537 vx_tun_l2_1.sw_if_index,
1538 mac=l['mac']))
1539 self.assertTrue(find_gbp_endpoint(self,
1540 vx_tun_l2_1.sw_if_index,
1541 ip=l['ip']))
1542
1543 self.logger.info(self.vapi.cli("show gbp endpoint"))
1544 self.logger.info(self.vapi.cli("show gbp vxlan"))
1545 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1546
1547 #
1548 # If we sleep for the threshold time, the learnt endpoints should
1549 # age out
1550 #
1551 self.sleep(2)
1552 for l in learnt:
1553 self.assertFalse(find_gbp_endpoint(self,
1554 tep1_sw_if_index,
1555 mac=l['mac']))
1556
1557 self.logger.info(self.vapi.cli("show gbp endpoint"))
1558 self.logger.info(self.vapi.cli("show gbp vxlan"))
1559 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1560
1561 #
1562 # repeat. the do not learn bit is set so the EPs are not learnt
1563 #
1564 for l in learnt:
1565 # a packet with an sclass from a knwon EPG
1566 p = (Ether(src=self.pg2.remote_mac,
1567 dst=self.pg2.local_mac) /
1568 IP(src=self.pg2.remote_hosts[1].ip4,
1569 dst=self.pg2.local_ip4) /
1570 UDP(sport=1234, dport=48879) /
1571 VXLAN(vni=99, gpid=220, flags=0x88, gpflags="D") /
1572 Ether(src=l['mac'], dst=ep.mac) /
1573 IP(src=l['ip'], dst=ep.ip4.address) /
1574 UDP(sport=1234, dport=1234) /
1575 Raw('\xa5' * 100))
1576
1577 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1578
1579 for l in learnt:
1580 self.assertFalse(find_gbp_endpoint(self,
1581 vx_tun_l2_1.sw_if_index,
1582 mac=l['mac']))
1583
1584 #
1585 # repeat
1586 #
1587 for l in learnt:
1588 # a packet with an sclass from a knwon EPG
1589 p = (Ether(src=self.pg2.remote_mac,
1590 dst=self.pg2.local_mac) /
1591 IP(src=self.pg2.remote_hosts[1].ip4,
1592 dst=self.pg2.local_ip4) /
1593 UDP(sport=1234, dport=48879) /
1594 VXLAN(vni=99, gpid=220, flags=0x88) /
1595 Ether(src=l['mac'], dst=ep.mac) /
1596 IP(src=l['ip'], dst=ep.ip4.address) /
1597 UDP(sport=1234, dport=1234) /
1598 Raw('\xa5' * 100))
1599
1600 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1601
1602 self.assertTrue(find_gbp_endpoint(self,
1603 vx_tun_l2_1.sw_if_index,
1604 mac=l['mac']))
1605
1606 #
1607 # Static EP replies to dynamics
1608 #
1609 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1610 for l in learnt:
1611 p = (Ether(src=ep.mac, dst=l['mac']) /
1612 IP(dst=l['ip'], src=ep.ip4.address) /
1613 UDP(sport=1234, dport=1234) /
1614 Raw('\xa5' * 100))
1615
1616 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1617
1618 for rx in rxs:
1619 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1620 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1621 self.assertEqual(rx[UDP].dport, 48879)
1622 # the UDP source port is a random value for hashing
1623 self.assertEqual(rx[VXLAN].gpid, 220)
1624 self.assertEqual(rx[VXLAN].vni, 99)
1625 self.assertTrue(rx[VXLAN].flags.G)
1626 self.assertTrue(rx[VXLAN].flags.Instance)
1627 self.assertTrue(rx[VXLAN].gpflags.A)
1628 self.assertFalse(rx[VXLAN].gpflags.D)
1629
1630 self.sleep(2)
1631 for l in learnt:
1632 self.assertFalse(find_gbp_endpoint(self,
1633 vx_tun_l2_1.sw_if_index,
1634 mac=l['mac']))
1635
1636 #
1637 # repeat in the other EPG
1638 # there's no contract between 220 and 330, but the A-bit is set
1639 # so the packet is cleared for delivery
1640 #
1641 for l in learnt:
1642 # a packet with an sclass from a knwon EPG
1643 p = (Ether(src=self.pg2.remote_mac,
1644 dst=self.pg2.local_mac) /
1645 IP(src=self.pg2.remote_hosts[1].ip4,
1646 dst=self.pg2.local_ip4) /
1647 UDP(sport=1234, dport=48879) /
1648 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1649 Ether(src=l['mac'], dst=ep.mac) /
1650 IP(src=l['ip'], dst=ep.ip4.address) /
1651 UDP(sport=1234, dport=1234) /
1652 Raw('\xa5' * 100))
1653
1654 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1655
1656 self.assertTrue(find_gbp_endpoint(self,
1657 vx_tun_l2_1.sw_if_index,
1658 mac=l['mac']))
1659
1660 #
1661 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001662 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001663 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001664 p = (Ether(src=ep.mac, dst=l['mac']) /
1665 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1666 UDP(sport=1234, dport=1234) /
1667 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001668
Neale Ranns13a08cc2018-11-07 09:25:54 -08001669 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001670
1671 #
1672 # refresh the entries after the check for no replies above
1673 #
1674 for l in learnt:
1675 # a packet with an sclass from a knwon EPG
1676 p = (Ether(src=self.pg2.remote_mac,
1677 dst=self.pg2.local_mac) /
1678 IP(src=self.pg2.remote_hosts[1].ip4,
1679 dst=self.pg2.local_ip4) /
1680 UDP(sport=1234, dport=48879) /
1681 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1682 Ether(src=l['mac'], dst=ep.mac) /
1683 IP(src=l['ip'], dst=ep.ip4.address) /
1684 UDP(sport=1234, dport=1234) /
1685 Raw('\xa5' * 100))
1686
1687 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1688
1689 self.assertTrue(find_gbp_endpoint(self,
1690 vx_tun_l2_1.sw_if_index,
1691 mac=l['mac']))
1692
1693 #
1694 # Add the contract so they can talk
1695 #
1696 acl = VppGbpAcl(self)
1697 rule = acl.create_rule(permit_deny=1, proto=17)
1698 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1699 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001700 c1 = VppGbpContract(
1701 self, 220, 330, acl_index,
1702 [VppGbpContractRule(
1703 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1704 []),
1705 VppGbpContractRule(
1706 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1707 [])])
1708
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001709 c1.add_vpp_config()
1710
1711 for l in learnt:
1712 p = (Ether(src=ep.mac, dst=l['mac']) /
1713 IP(dst=l['ip'], src=ep.ip4.address) /
1714 UDP(sport=1234, dport=1234) /
1715 Raw('\xa5' * 100))
1716
1717 self.send_and_expect(self.pg0, [p], self.pg2)
1718
1719 #
1720 # send UU packets from the local EP
1721 #
1722 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1723 self.logger.info(self.vapi.cli("sh gbp bridge"))
1724 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1725 IP(dst="10.0.0.133", src=ep.ip4.address) /
1726 UDP(sport=1234, dport=1234) /
1727 Raw('\xa5' * 100))
1728 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_flood)
1729
1730 #
1731 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1732 #
1733 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1734 "239.1.1.1", 88,
1735 mcast_itf=self.pg4)
1736 tun_bm.add_vpp_config()
1737 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
1738 port_type=L2_PORT_TYPE.NORMAL)
1739 bp_bm.add_vpp_config()
1740
1741 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1742
1743 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1744 IP(dst="10.0.0.133", src=ep.ip4.address) /
1745 UDP(sport=1234, dport=1234) /
1746 Raw('\xa5' * 100))
1747 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1748
1749 #
1750 # Check v6 Endpoints
1751 #
1752 for l in learnt:
1753 # a packet with an sclass from a knwon EPG
1754 p = (Ether(src=self.pg2.remote_mac,
1755 dst=self.pg2.local_mac) /
1756 IP(src=self.pg2.remote_hosts[1].ip4,
1757 dst=self.pg2.local_ip4) /
1758 UDP(sport=1234, dport=48879) /
1759 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1760 Ether(src=l['mac'], dst=ep.mac) /
1761 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1762 UDP(sport=1234, dport=1234) /
1763 Raw('\xa5' * 100))
1764
1765 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1766
1767 self.assertTrue(find_gbp_endpoint(self,
1768 vx_tun_l2_1.sw_if_index,
1769 mac=l['mac']))
1770
1771 #
1772 # L3 Endpoint Learning
1773 # - configured on the bridge's BVI
1774 #
1775
1776 #
1777 # clean up
1778 #
1779 self.sleep(2)
1780 for l in learnt:
1781 self.assertFalse(find_gbp_endpoint(self,
1782 vx_tun_l2_1.sw_if_index,
1783 mac=l['mac']))
1784
1785 self.pg2.unconfig_ip4()
1786 self.pg3.unconfig_ip4()
1787 self.pg4.unconfig_ip4()
1788
1789 self.logger.info(self.vapi.cli("sh int"))
1790 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1791
Neale Rannsc29c0af2018-11-07 04:21:12 -08001792 def test_gbp_learn_vlan_l2(self):
1793 """ GBP L2 Endpoint w/ VLANs"""
1794
1795 learnt = [{'mac': '00:00:11:11:11:01',
1796 'ip': '10.0.0.1',
1797 'ip6': '2001:10::2'},
1798 {'mac': '00:00:11:11:11:02',
1799 'ip': '10.0.0.2',
1800 'ip6': '2001:10::3'}]
1801
1802 #
1803 # lower the inactive threshold so these tests pass in a
1804 # reasonable amount of time
1805 #
1806 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1807
1808 #
1809 # IP tables
1810 #
1811 gt4 = VppIpTable(self, 1)
1812 gt4.add_vpp_config()
1813 gt6 = VppIpTable(self, 1, is_ip6=True)
1814 gt6.add_vpp_config()
1815
1816 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1817 rd1.add_vpp_config()
1818
1819 #
1820 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1821 #
1822 self.pg2.config_ip4()
1823 self.pg2.resolve_arp()
1824 self.pg2.generate_remote_hosts(4)
1825 self.pg2.configure_ipv4_neighbors()
1826 self.pg3.config_ip4()
1827 self.pg3.resolve_arp()
1828
1829 #
1830 # The EP will be on a vlan sub-interface
1831 #
1832 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1833 vlan_11.admin_up()
1834 self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index,
1835 L2_VTR_OP.L2_POP_1,
1836 11)
1837
1838 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1839 self.pg3.remote_ip4, 116)
1840 bd_uu_fwd.add_vpp_config()
1841
1842 #
1843 # a GBP bridge domain with a BVI and a UU-flood interface
1844 # The BD is marked as do not learn, so no endpoints are ever
1845 # learnt in this BD.
1846 #
1847 bd1 = VppBridgeDomain(self, 1)
1848 bd1.add_vpp_config()
1849 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1850 learn=False)
1851 gbd1.add_vpp_config()
1852
1853 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1854 self.logger.info(self.vapi.cli("sh gbp bridge"))
1855
1856 # ... and has a /32 applied
1857 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1858 ip_addr.add_vpp_config()
1859
1860 #
1861 # The Endpoint-group in which we are learning endpoints
1862 #
1863 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1864 None, self.loop0,
1865 "10.0.0.128",
1866 "2001:10::128")
1867 epg_220.add_vpp_config()
1868
1869 #
1870 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1871 # leanring enabled
1872 #
1873 vx_tun_l2_1 = VppGbpVxlanTunnel(
1874 self, 99, bd1.bd_id,
1875 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1876 vx_tun_l2_1.add_vpp_config()
1877
1878 #
1879 # A static endpoint that the learnt endpoints are trying to
1880 # talk to
1881 #
1882 ep = VppGbpEndpoint(self, vlan_11,
1883 epg_220, None,
1884 "10.0.0.127", "11.0.0.127",
1885 "2001:10::1", "3001::1")
1886 ep.add_vpp_config()
1887
1888 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1889
1890 #
1891 # Send to the static EP
1892 #
1893 for ii, l in enumerate(learnt):
1894 # a packet with an sclass from a knwon EPG
1895 # arriving on an unknown TEP
1896 p = (Ether(src=self.pg2.remote_mac,
1897 dst=self.pg2.local_mac) /
1898 IP(src=self.pg2.remote_hosts[1].ip4,
1899 dst=self.pg2.local_ip4) /
1900 UDP(sport=1234, dport=48879) /
1901 VXLAN(vni=99, gpid=220, flags=0x88) /
1902 Ether(src=l['mac'], dst=ep.mac) /
1903 IP(src=l['ip'], dst=ep.ip4.address) /
1904 UDP(sport=1234, dport=1234) /
1905 Raw('\xa5' * 100))
1906
1907 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
1908
1909 #
1910 # packet to EP has the EP's vlan tag
1911 #
1912 for rx in rxs:
1913 self.assertEqual(rx[Dot1Q].vlan, 11)
1914
1915 #
1916 # the EP is not learnt since the BD setting prevents it
1917 # also no TEP too
1918 #
1919 self.assertFalse(find_gbp_endpoint(self,
1920 vx_tun_l2_1.sw_if_index,
1921 mac=l['mac']))
1922 self.assertEqual(INDEX_INVALID,
1923 find_vxlan_gbp_tunnel(
1924 self,
1925 self.pg2.local_ip4,
1926 self.pg2.remote_hosts[1].ip4,
1927 99))
1928
1929 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1930
1931 #
1932 # static to remotes
1933 # we didn't learn the remotes so they are sent to the UU-fwd
1934 #
1935 for l in learnt:
1936 p = (Ether(src=ep.mac, dst=l['mac']) /
1937 Dot1Q(vlan=11) /
1938 IP(dst=l['ip'], src=ep.ip4.address) /
1939 UDP(sport=1234, dport=1234) /
1940 Raw('\xa5' * 100))
1941
1942 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
1943
1944 for rx in rxs:
1945 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
1946 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
1947 self.assertEqual(rx[UDP].dport, 48879)
1948 # the UDP source port is a random value for hashing
1949 self.assertEqual(rx[VXLAN].gpid, 220)
1950 self.assertEqual(rx[VXLAN].vni, 116)
1951 self.assertTrue(rx[VXLAN].flags.G)
1952 self.assertTrue(rx[VXLAN].flags.Instance)
1953 self.assertFalse(rx[VXLAN].gpflags.A)
1954 self.assertFalse(rx[VXLAN].gpflags.D)
1955
1956 self.pg2.unconfig_ip4()
1957 self.pg3.unconfig_ip4()
1958
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001959 def test_gbp_learn_l3(self):
1960 """ GBP L3 Endpoint Learning """
1961
Neale Ranns13a08cc2018-11-07 09:25:54 -08001962 self.vapi.cli("set logging class gbp debug")
1963
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001964 routed_dst_mac = "00:0c:0c:0c:0c:0c"
1965 routed_src_mac = "00:22:bd:f8:19:ff"
1966
1967 learnt = [{'mac': '00:00:11:11:11:02',
1968 'ip': '10.0.1.2',
1969 'ip6': '2001:10::2'},
1970 {'mac': '00:00:11:11:11:03',
1971 'ip': '10.0.1.3',
1972 'ip6': '2001:10::3'}]
1973
1974 #
1975 # lower the inactive threshold so these tests pass in a
1976 # reasonable amount of time
1977 #
1978 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1979
1980 #
1981 # IP tables
1982 #
1983 t4 = VppIpTable(self, 1)
1984 t4.add_vpp_config()
1985 t6 = VppIpTable(self, 1, True)
1986 t6.add_vpp_config()
1987
1988 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1989 self.pg4.remote_ip4, 114)
1990 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1991 self.pg4.remote_ip4, 116)
1992 tun_ip4_uu.add_vpp_config()
1993 tun_ip6_uu.add_vpp_config()
1994
1995 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
1996 rd1.add_vpp_config()
1997
1998 self.loop0.set_mac(self.router_mac.address)
1999
2000 #
2001 # Bind the BVI to the RD
2002 #
2003 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2004 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2005
2006 #
2007 # Pg2 hosts the vxlan tunnel
2008 # hosts on pg2 to act as TEPs
2009 # pg3 is BD uu-fwd
2010 # pg4 is RD uu-fwd
2011 #
2012 self.pg2.config_ip4()
2013 self.pg2.resolve_arp()
2014 self.pg2.generate_remote_hosts(4)
2015 self.pg2.configure_ipv4_neighbors()
2016 self.pg3.config_ip4()
2017 self.pg3.resolve_arp()
2018 self.pg4.config_ip4()
2019 self.pg4.resolve_arp()
2020
2021 #
2022 # a GBP bridge domain with a BVI and a UU-flood interface
2023 #
2024 bd1 = VppBridgeDomain(self, 1)
2025 bd1.add_vpp_config()
2026 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2027 gbd1.add_vpp_config()
2028
2029 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2030 self.logger.info(self.vapi.cli("sh gbp bridge"))
2031 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002032
2033 # ... and has a /32 and /128 applied
2034 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2035 ip4_addr.add_vpp_config()
2036 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2037 ip6_addr.add_vpp_config()
2038
2039 #
2040 # The Endpoint-group in which we are learning endpoints
2041 #
2042 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2043 None, self.loop0,
2044 "10.0.0.128",
2045 "2001:10::128")
2046 epg_220.add_vpp_config()
2047
2048 #
2049 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2050 # leanring enabled
2051 #
2052 vx_tun_l3 = VppGbpVxlanTunnel(
2053 self, 101, rd1.rd_id,
2054 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2055 vx_tun_l3.add_vpp_config()
2056
2057 #
2058 # A static endpoint that the learnt endpoints are trying to
2059 # talk to
2060 #
2061 ep = VppGbpEndpoint(self, self.pg0,
2062 epg_220, None,
2063 "10.0.0.127", "11.0.0.127",
2064 "2001:10::1", "3001::1")
2065 ep.add_vpp_config()
2066
2067 #
2068 # learn some remote IPv4 EPs
2069 #
2070 for ii, l in enumerate(learnt):
2071 # a packet with an sclass from a knwon EPG
2072 # arriving on an unknown TEP
2073 p = (Ether(src=self.pg2.remote_mac,
2074 dst=self.pg2.local_mac) /
2075 IP(src=self.pg2.remote_hosts[1].ip4,
2076 dst=self.pg2.local_ip4) /
2077 UDP(sport=1234, dport=48879) /
2078 VXLAN(vni=101, gpid=220, flags=0x88) /
2079 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2080 IP(src=l['ip'], dst=ep.ip4.address) /
2081 UDP(sport=1234, dport=1234) /
2082 Raw('\xa5' * 100))
2083
2084 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2085
2086 # the new TEP
2087 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2088 self,
2089 self.pg2.local_ip4,
2090 self.pg2.remote_hosts[1].ip4,
2091 vx_tun_l3.vni)
2092 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2093
2094 # endpoint learnt via the parent GBP-vxlan interface
2095 self.assertTrue(find_gbp_endpoint(self,
2096 vx_tun_l3._sw_if_index,
2097 ip=l['ip']))
2098
2099 #
2100 # Static IPv4 EP replies to learnt
2101 #
2102 for l in learnt:
2103 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2104 IP(dst=l['ip'], src=ep.ip4.address) /
2105 UDP(sport=1234, dport=1234) /
2106 Raw('\xa5' * 100))
2107
2108 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2109
2110 for rx in rxs:
2111 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2112 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2113 self.assertEqual(rx[UDP].dport, 48879)
2114 # the UDP source port is a random value for hashing
2115 self.assertEqual(rx[VXLAN].gpid, 220)
2116 self.assertEqual(rx[VXLAN].vni, 101)
2117 self.assertTrue(rx[VXLAN].flags.G)
2118 self.assertTrue(rx[VXLAN].flags.Instance)
2119 self.assertTrue(rx[VXLAN].gpflags.A)
2120 self.assertFalse(rx[VXLAN].gpflags.D)
2121
2122 inner = rx[VXLAN].payload
2123
2124 self.assertEqual(inner[Ether].src, routed_src_mac)
2125 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2126 self.assertEqual(inner[IP].src, ep.ip4.address)
2127 self.assertEqual(inner[IP].dst, l['ip'])
2128
2129 self.sleep(2)
2130 for l in learnt:
2131 self.assertFalse(find_gbp_endpoint(self,
2132 tep1_sw_if_index,
2133 ip=l['ip']))
2134
2135 #
2136 # learn some remote IPv6 EPs
2137 #
2138 for ii, l in enumerate(learnt):
2139 # a packet with an sclass from a knwon EPG
2140 # arriving on an unknown TEP
2141 p = (Ether(src=self.pg2.remote_mac,
2142 dst=self.pg2.local_mac) /
2143 IP(src=self.pg2.remote_hosts[1].ip4,
2144 dst=self.pg2.local_ip4) /
2145 UDP(sport=1234, dport=48879) /
2146 VXLAN(vni=101, gpid=220, flags=0x88) /
2147 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2148 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2149 UDP(sport=1234, dport=1234) /
2150 Raw('\xa5' * 100))
2151
2152 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2153
2154 # the new TEP
2155 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2156 self,
2157 self.pg2.local_ip4,
2158 self.pg2.remote_hosts[1].ip4,
2159 vx_tun_l3.vni)
2160 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2161
2162 self.logger.info(self.vapi.cli("show gbp bridge"))
2163 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2164 self.logger.info(self.vapi.cli("show gbp vxlan"))
2165 self.logger.info(self.vapi.cli("show int addr"))
2166
2167 # endpoint learnt via the TEP
2168 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2169
2170 self.logger.info(self.vapi.cli("show gbp endpoint"))
2171 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2172
2173 #
2174 # Static EP replies to learnt
2175 #
2176 for l in learnt:
2177 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2178 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2179 UDP(sport=1234, dport=1234) /
2180 Raw('\xa5' * 100))
2181
2182 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2183
2184 for rx in rxs:
2185 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2186 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2187 self.assertEqual(rx[UDP].dport, 48879)
2188 # the UDP source port is a random value for hashing
2189 self.assertEqual(rx[VXLAN].gpid, 220)
2190 self.assertEqual(rx[VXLAN].vni, 101)
2191 self.assertTrue(rx[VXLAN].flags.G)
2192 self.assertTrue(rx[VXLAN].flags.Instance)
2193 self.assertTrue(rx[VXLAN].gpflags.A)
2194 self.assertFalse(rx[VXLAN].gpflags.D)
2195
2196 inner = rx[VXLAN].payload
2197
2198 self.assertEqual(inner[Ether].src, routed_src_mac)
2199 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2200 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2201 self.assertEqual(inner[IPv6].dst, l['ip6'])
2202
2203 self.logger.info(self.vapi.cli("sh gbp endpoint"))
2204 self.sleep(2)
2205 for l in learnt:
2206 self.assertFalse(find_gbp_endpoint(self,
2207 tep1_sw_if_index,
2208 ip=l['ip']))
2209
2210 #
2211 # Static sends to unknown EP with no route
2212 #
2213 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2214 IP(dst="10.0.0.99", src=ep.ip4.address) /
2215 UDP(sport=1234, dport=1234) /
2216 Raw('\xa5' * 100))
2217
2218 self.send_and_assert_no_replies(self.pg0, [p])
2219
2220 #
2221 # Add a route to static EP's v4 and v6 subnet
2222 # packets should be send on the v4/v6 uu=fwd interface resp.
2223 #
2224 se_10_24 = VppGbpSubnet(
2225 self, rd1, "10.0.0.0", 24,
2226 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2227 se_10_24.add_vpp_config()
2228
2229 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2230 IP(dst="10.0.0.99", src=ep.ip4.address) /
2231 UDP(sport=1234, dport=1234) /
2232 Raw('\xa5' * 100))
2233
2234 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2235 for rx in rxs:
2236 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2237 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2238 self.assertEqual(rx[UDP].dport, 48879)
2239 # the UDP source port is a random value for hashing
2240 self.assertEqual(rx[VXLAN].gpid, 220)
2241 self.assertEqual(rx[VXLAN].vni, 114)
2242 self.assertTrue(rx[VXLAN].flags.G)
2243 self.assertTrue(rx[VXLAN].flags.Instance)
2244 # policy is not applied to packets sent to the uu-fwd interfaces
2245 self.assertFalse(rx[VXLAN].gpflags.A)
2246 self.assertFalse(rx[VXLAN].gpflags.D)
2247
2248 #
2249 # learn some remote IPv4 EPs
2250 #
2251 for ii, l in enumerate(learnt):
2252 # a packet with an sclass from a knwon EPG
2253 # arriving on an unknown TEP
2254 p = (Ether(src=self.pg2.remote_mac,
2255 dst=self.pg2.local_mac) /
2256 IP(src=self.pg2.remote_hosts[1].ip4,
2257 dst=self.pg2.local_ip4) /
2258 UDP(sport=1234, dport=48879) /
2259 VXLAN(vni=101, gpid=220, flags=0x88) /
2260 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2261 IP(src=l['ip'], dst=ep.ip4.address) /
2262 UDP(sport=1234, dport=1234) /
2263 Raw('\xa5' * 100))
2264
2265 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2266
2267 # the new TEP
2268 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2269 self,
2270 self.pg2.local_ip4,
2271 self.pg2.remote_hosts[1].ip4,
2272 vx_tun_l3.vni)
2273 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2274
2275 # endpoint learnt via the parent GBP-vxlan interface
2276 self.assertTrue(find_gbp_endpoint(self,
2277 vx_tun_l3._sw_if_index,
2278 ip=l['ip']))
2279
2280 #
2281 # Add a remote endpoint from the API
2282 #
2283 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2284 epg_220, None,
2285 "10.0.0.88", "11.0.0.88",
2286 "2001:10::88", "3001::88",
2287 VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE,
2288 self.pg2.local_ip4,
2289 self.pg2.remote_hosts[1].ip4,
2290 mac=None)
2291 rep_88.add_vpp_config()
2292
2293 #
2294 # Add a remote endpoint from the API that matches an existing one
2295 #
2296 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2297 epg_220, None,
2298 learnt[0]['ip'], "11.0.0.101",
2299 learnt[0]['ip6'], "3001::101",
2300 VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE,
2301 self.pg2.local_ip4,
2302 self.pg2.remote_hosts[1].ip4,
2303 mac=None)
2304 rep_2.add_vpp_config()
2305
2306 #
2307 # Add a route to the leanred EP's v4 subnet
2308 # packets should be send on the v4/v6 uu=fwd interface resp.
2309 #
2310 se_10_1_24 = VppGbpSubnet(
2311 self, rd1, "10.0.1.0", 24,
2312 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2313 se_10_1_24.add_vpp_config()
2314
2315 self.logger.info(self.vapi.cli("show gbp endpoint"))
2316
2317 ips = ["10.0.0.88", learnt[0]['ip']]
2318 for ip in ips:
2319 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2320 IP(dst=ip, src=ep.ip4.address) /
2321 UDP(sport=1234, dport=1234) /
2322 Raw('\xa5' * 100))
2323
2324 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2325
2326 for rx in rxs:
2327 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2328 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2329 self.assertEqual(rx[UDP].dport, 48879)
2330 # the UDP source port is a random value for hashing
2331 self.assertEqual(rx[VXLAN].gpid, 220)
2332 self.assertEqual(rx[VXLAN].vni, 101)
2333 self.assertTrue(rx[VXLAN].flags.G)
2334 self.assertTrue(rx[VXLAN].flags.Instance)
2335 self.assertTrue(rx[VXLAN].gpflags.A)
2336 self.assertFalse(rx[VXLAN].gpflags.D)
2337
2338 inner = rx[VXLAN].payload
2339
2340 self.assertEqual(inner[Ether].src, routed_src_mac)
2341 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2342 self.assertEqual(inner[IP].src, ep.ip4.address)
2343 self.assertEqual(inner[IP].dst, ip)
2344
2345 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002346 # remove the API remote EPs, only API sourced is gone, the DP
2347 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002348 #
2349 rep_88.remove_vpp_config()
2350 rep_2.remove_vpp_config()
2351
2352 self.logger.info(self.vapi.cli("show gbp endpoint"))
2353
Neale Ranns13a08cc2018-11-07 09:25:54 -08002354 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002355
Neale Ranns13a08cc2018-11-07 09:25:54 -08002356 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2357 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2358 UDP(sport=1234, dport=1234) /
2359 Raw('\xa5' * 100))
2360 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002361
Neale Ranns13a08cc2018-11-07 09:25:54 -08002362 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2363
2364 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2365 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2366 UDP(sport=1234, dport=1234) /
2367 Raw('\xa5' * 100))
2368 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
2369
2370 #
2371 # to appease the testcase we cannot have the registered EP stll
2372 # present (because it's DP learnt) when the TC ends so wait until
2373 # it is removed
2374 #
2375 self.sleep(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002376
2377 #
2378 # shutdown with learnt endpoint present
2379 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002380 p = (Ether(src=self.pg2.remote_mac,
2381 dst=self.pg2.local_mac) /
2382 IP(src=self.pg2.remote_hosts[1].ip4,
2383 dst=self.pg2.local_ip4) /
2384 UDP(sport=1234, dport=48879) /
2385 VXLAN(vni=101, gpid=220, flags=0x88) /
2386 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2387 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2388 UDP(sport=1234, dport=1234) /
2389 Raw('\xa5' * 100))
2390
2391 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2392
2393 # endpoint learnt via the parent GBP-vxlan interface
2394 self.assertTrue(find_gbp_endpoint(self,
2395 vx_tun_l3._sw_if_index,
2396 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002397
2398 #
2399 # TODO
2400 # remote endpoint becomes local
2401 #
2402 self.pg2.unconfig_ip4()
2403 self.pg3.unconfig_ip4()
2404 self.pg4.unconfig_ip4()
2405
Neale Ranns13a08cc2018-11-07 09:25:54 -08002406 def test_gbp_redirect(self):
2407 """ GBP Endpoint Redirect """
2408
2409 self.vapi.cli("set logging class gbp debug")
2410
2411 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2412 routed_src_mac = "00:22:bd:f8:19:ff"
2413
2414 learnt = [{'mac': '00:00:11:11:11:02',
2415 'ip': '10.0.1.2',
2416 'ip6': '2001:10::2'},
2417 {'mac': '00:00:11:11:11:03',
2418 'ip': '10.0.1.3',
2419 'ip6': '2001:10::3'}]
2420
2421 #
2422 # lower the inactive threshold so these tests pass in a
2423 # reasonable amount of time
2424 #
2425 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
2426
2427 #
2428 # IP tables
2429 #
2430 t4 = VppIpTable(self, 1)
2431 t4.add_vpp_config()
2432 t6 = VppIpTable(self, 1, True)
2433 t6.add_vpp_config()
2434
2435 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2436 rd1.add_vpp_config()
2437
2438 self.loop0.set_mac(self.router_mac.address)
2439
2440 #
2441 # Bind the BVI to the RD
2442 #
2443 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2444 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2445
2446 #
2447 # Pg7 hosts a BD's UU-fwd
2448 #
2449 self.pg7.config_ip4()
2450 self.pg7.resolve_arp()
2451
2452 #
2453 # a GBP bridge domains for the EPs
2454 #
2455 bd1 = VppBridgeDomain(self, 1)
2456 bd1.add_vpp_config()
2457 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2458 gbd1.add_vpp_config()
2459
2460 bd2 = VppBridgeDomain(self, 2)
2461 bd2.add_vpp_config()
2462 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2463 gbd2.add_vpp_config()
2464
2465 # ... and has a /32 and /128 applied
2466 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2467 ip4_addr.add_vpp_config()
2468 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2469 ip6_addr.add_vpp_config()
2470 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2471 ip4_addr.add_vpp_config()
2472 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2473 ip6_addr.add_vpp_config()
2474
2475 #
2476 # The Endpoint-groups in which we are learning endpoints
2477 #
2478 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2479 None, gbd1.bvi,
2480 "10.0.0.128",
2481 "2001:10::128")
2482 epg_220.add_vpp_config()
2483 epg_221 = VppGbpEndpointGroup(self, 221, rd1, gbd2,
2484 None, gbd2.bvi,
2485 "10.0.1.128",
2486 "2001:11::128")
2487 epg_221.add_vpp_config()
2488 epg_222 = VppGbpEndpointGroup(self, 222, rd1, gbd1,
2489 None, gbd1.bvi,
2490 "10.0.2.128",
2491 "2001:12::128")
2492 epg_222.add_vpp_config()
2493
2494 #
2495 # a GBP bridge domains for the SEPs
2496 #
2497 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2498 self.pg7.remote_ip4, 116)
2499 bd_uu1.add_vpp_config()
2500 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2501 self.pg7.remote_ip4, 117)
2502 bd_uu2.add_vpp_config()
2503
2504 bd3 = VppBridgeDomain(self, 3)
2505 bd3.add_vpp_config()
2506 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2507 gbd3.add_vpp_config()
2508 bd4 = VppBridgeDomain(self, 4)
2509 bd4.add_vpp_config()
2510 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2511 gbd4.add_vpp_config()
2512
2513 #
2514 # EPGs in which the service endpoints exist
2515 #
2516 epg_320 = VppGbpEndpointGroup(self, 320, rd1, gbd3,
2517 None, gbd1.bvi,
2518 "12.0.0.128",
2519 "4001:10::128")
2520 epg_320.add_vpp_config()
2521 epg_321 = VppGbpEndpointGroup(self, 321, rd1, gbd4,
2522 None, gbd2.bvi,
2523 "12.0.1.128",
2524 "4001:11::128")
2525 epg_321.add_vpp_config()
2526
2527 #
2528 # three local endpoints
2529 #
2530 ep1 = VppGbpEndpoint(self, self.pg0,
2531 epg_220, None,
2532 "10.0.0.1", "11.0.0.1",
2533 "2001:10::1", "3001:10::1")
2534 ep1.add_vpp_config()
2535 ep2 = VppGbpEndpoint(self, self.pg1,
2536 epg_221, None,
2537 "10.0.1.1", "11.0.1.1",
2538 "2001:11::1", "3001:11::1")
2539 ep2.add_vpp_config()
2540 ep3 = VppGbpEndpoint(self, self.pg2,
2541 epg_222, None,
2542 "10.0.2.2", "11.0.2.2",
2543 "2001:12::1", "3001:12::1")
2544 ep3.add_vpp_config()
2545
2546 #
2547 # service endpoints
2548 #
2549 sep1 = VppGbpEndpoint(self, self.pg3,
2550 epg_320, None,
2551 "12.0.0.1", "13.0.0.1",
2552 "4001:10::1", "5001:10::1")
2553 sep1.add_vpp_config()
2554 sep2 = VppGbpEndpoint(self, self.pg4,
2555 epg_320, None,
2556 "12.0.0.2", "13.0.0.2",
2557 "4001:10::2", "5001:10::2")
2558 sep2.add_vpp_config()
2559 sep3 = VppGbpEndpoint(self, self.pg5,
2560 epg_321, None,
2561 "12.0.1.1", "13.0.1.1",
2562 "4001:11::1", "5001:11::1")
2563 sep3.add_vpp_config()
2564 # this EP is not installed immediately
2565 sep4 = VppGbpEndpoint(self, self.pg6,
2566 epg_321, None,
2567 "12.0.1.2", "13.0.1.2",
2568 "4001:11::2", "5001:11::2")
2569
2570 #
2571 # an L2 switch packet between local EPs in different EPGs
2572 # different dest ports on each so the are LB hashed differently
2573 #
2574 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2575 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2576 UDP(sport=1234, dport=1234) /
2577 Raw('\xa5' * 100)),
2578 (Ether(src=ep1.mac, dst=ep3.mac) /
2579 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2580 UDP(sport=1234, dport=1235) /
2581 Raw('\xa5' * 100))]
2582 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2583 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2584 UDP(sport=1234, dport=1234) /
2585 Raw('\xa5' * 100)),
2586 (Ether(src=ep1.mac, dst=ep3.mac) /
2587 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2588 UDP(sport=1234, dport=1230) /
2589 Raw('\xa5' * 100))]
2590
2591 # should be dropped since no contract yet
2592 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2593 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2594
2595 #
2596 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2597 # one of the next-hops is via an EP that is not known
2598 #
2599 acl = VppGbpAcl(self)
2600 rule4 = acl.create_rule(permit_deny=1, proto=17)
2601 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2602 acl_index = acl.add_vpp_config([rule4, rule6])
2603
2604 c1 = VppGbpContract(
2605 self, 220, 222, acl_index,
2606 [VppGbpContractRule(
2607 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2608 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2609 sep1.ip4, sep1.epg.rd),
2610 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2611 sep2.ip4, sep2.epg.rd)]),
2612 VppGbpContractRule(
2613 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2614 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2615 sep3.ip6, sep3.epg.rd),
2616 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2617 sep4.ip6, sep4.epg.rd)])])
2618 c1.add_vpp_config()
2619
2620 #
2621 # send again with the contract preset, now packets arrive
2622 # at SEP1 or SEP2 depending on the hashing
2623 #
2624 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep2.itf)
2625
2626 for rx in rxs:
2627 self.assertEqual(rx[Ether].src, routed_src_mac)
2628 self.assertEqual(rx[Ether].dst, sep2.mac)
2629 self.assertEqual(rx[IP].src, ep1.ip4.address)
2630 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2631
2632 rxs = self.send_and_expect(self.pg0, p4[1] * 17, sep1.itf)
2633
2634 for rx in rxs:
2635 self.assertEqual(rx[Ether].src, routed_src_mac)
2636 self.assertEqual(rx[Ether].dst, sep1.mac)
2637 self.assertEqual(rx[IP].src, ep1.ip4.address)
2638 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2639
2640 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2641
2642 for rx in rxs:
2643 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2644 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2645 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2646 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2647 self.assertEqual(rx[VXLAN].vni, 117)
2648 self.assertTrue(rx[VXLAN].flags.G)
2649 self.assertTrue(rx[VXLAN].flags.Instance)
2650 # redirect policy has been applied
2651 self.assertTrue(rx[VXLAN].gpflags.A)
2652 self.assertFalse(rx[VXLAN].gpflags.D)
2653
2654 inner = rx[VXLAN].payload
2655
2656 self.assertEqual(inner[Ether].src, routed_src_mac)
2657 self.assertEqual(inner[Ether].dst, sep4.mac)
2658 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2659 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2660
2661 rxs = self.send_and_expect(self.pg0, p6[1] * 17, sep3.itf)
2662
2663 for rx in rxs:
2664 self.assertEqual(rx[Ether].src, routed_src_mac)
2665 self.assertEqual(rx[Ether].dst, sep3.mac)
2666 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2667 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2668
2669 #
2670 # programme the unknown EP
2671 #
2672 sep4.add_vpp_config()
2673
2674 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2675
2676 for rx in rxs:
2677 self.assertEqual(rx[Ether].src, routed_src_mac)
2678 self.assertEqual(rx[Ether].dst, sep4.mac)
2679 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2680 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2681
2682 #
2683 # and revert back to unprogrammed
2684 #
2685 sep4.remove_vpp_config()
2686
2687 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2688
2689 for rx in rxs:
2690 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2691 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2692 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2693 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2694 self.assertEqual(rx[VXLAN].vni, 117)
2695 self.assertTrue(rx[VXLAN].flags.G)
2696 self.assertTrue(rx[VXLAN].flags.Instance)
2697 # redirect policy has been applied
2698 self.assertTrue(rx[VXLAN].gpflags.A)
2699 self.assertFalse(rx[VXLAN].gpflags.D)
2700
2701 inner = rx[VXLAN].payload
2702
2703 self.assertEqual(inner[Ether].src, routed_src_mac)
2704 self.assertEqual(inner[Ether].dst, sep4.mac)
2705 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2706 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2707
2708 #
2709 # programme the unknown EP for the L3 tests
2710 #
2711 sep4.add_vpp_config()
2712
2713 #
2714 # an L3 switch packet between local EPs in different EPGs
2715 # different dest ports on each so the are LB hashed differently
2716 #
2717 p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2718 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2719 UDP(sport=1234, dport=1234) /
2720 Raw('\xa5' * 100)),
2721 (Ether(src=ep1.mac, dst=self.router_mac.address) /
2722 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2723 UDP(sport=1234, dport=1235) /
2724 Raw('\xa5' * 100))]
2725 p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2726 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2727 UDP(sport=1234, dport=1234) /
2728 Raw('\xa5' * 100)),
2729 (Ether(src=ep1.mac, dst=self.router_mac.address) /
2730 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2731 UDP(sport=1234, dport=1230) /
2732 Raw('\xa5' * 100))]
2733
2734 c2 = VppGbpContract(
2735 self, 220, 221, acl_index,
2736 [VppGbpContractRule(
2737 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2738 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2739 sep1.ip4, sep1.epg.rd),
2740 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2741 sep2.ip4, sep2.epg.rd)]),
2742 VppGbpContractRule(
2743 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2744 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2745 sep3.ip6, sep3.epg.rd),
2746 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2747 sep4.ip6, sep4.epg.rd)])])
2748 c2.add_vpp_config()
2749
2750 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep2.itf)
2751
2752 for rx in rxs:
2753 self.assertEqual(rx[Ether].src, routed_src_mac)
2754 self.assertEqual(rx[Ether].dst, sep2.mac)
2755 self.assertEqual(rx[IP].src, ep1.ip4.address)
2756 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2757
2758 #
2759 # learn a remote EP in EPG 221
2760 #
2761 vx_tun_l3 = VppGbpVxlanTunnel(
2762 self, 444, rd1.rd_id,
2763 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2764 vx_tun_l3.add_vpp_config()
2765
2766 c3 = VppGbpContract(
2767 self, 221, 220, acl_index,
2768 [VppGbpContractRule(
2769 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2770 []),
2771 VppGbpContractRule(
2772 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2773 [])])
2774 c3.add_vpp_config()
2775
2776 p = (Ether(src=self.pg7.remote_mac,
2777 dst=self.pg7.local_mac) /
2778 IP(src=self.pg7.remote_ip4,
2779 dst=self.pg7.local_ip4) /
2780 UDP(sport=1234, dport=48879) /
2781 VXLAN(vni=444, gpid=221, flags=0x88) /
2782 Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) /
2783 IP(src="10.0.0.88", dst=ep1.ip4.address) /
2784 UDP(sport=1234, dport=1234) /
2785 Raw('\xa5' * 100))
2786
2787 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2788
2789 # endpoint learnt via the parent GBP-vxlan interface
2790 self.assertTrue(find_gbp_endpoint(self,
2791 vx_tun_l3._sw_if_index,
2792 ip="10.0.0.88"))
2793
2794 p = (Ether(src=self.pg7.remote_mac,
2795 dst=self.pg7.local_mac) /
2796 IP(src=self.pg7.remote_ip4,
2797 dst=self.pg7.local_ip4) /
2798 UDP(sport=1234, dport=48879) /
2799 VXLAN(vni=444, gpid=221, flags=0x88) /
2800 Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) /
2801 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
2802 UDP(sport=1234, dport=1234) /
2803 Raw('\xa5' * 100))
2804
2805 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2806
2807 # endpoint learnt via the parent GBP-vxlan interface
2808 self.assertTrue(find_gbp_endpoint(self,
2809 vx_tun_l3._sw_if_index,
2810 ip="2001:10::88"))
2811
2812 #
2813 # L3 switch from local to remote EP
2814 #
2815 p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2816 IP(src=ep1.ip4.address, dst="10.0.0.88") /
2817 UDP(sport=1234, dport=1234) /
2818 Raw('\xa5' * 100)),
2819 (Ether(src=ep1.mac, dst=self.router_mac.address) /
2820 IP(src=ep1.ip4.address, dst="10.0.0.88") /
2821 UDP(sport=1234, dport=1235) /
2822 Raw('\xa5' * 100))]
2823 p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2824 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
2825 UDP(sport=1234, dport=1234) /
2826 Raw('\xa5' * 100)),
2827 (Ether(src=ep1.mac, dst=self.router_mac.address) /
2828 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
2829 UDP(sport=1234, dport=123) /
2830 Raw('\xa5' * 100))]
2831
2832 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep2.itf)
2833
2834 for rx in rxs:
2835 self.assertEqual(rx[Ether].src, routed_src_mac)
2836 self.assertEqual(rx[Ether].dst, sep2.mac)
2837 self.assertEqual(rx[IP].src, ep1.ip4.address)
2838 self.assertEqual(rx[IP].dst, "10.0.0.88")
2839
2840 rxs = self.send_and_expect(self.pg0, p4[1] * 17, sep1.itf)
2841
2842 for rx in rxs:
2843 self.assertEqual(rx[Ether].src, routed_src_mac)
2844 self.assertEqual(rx[Ether].dst, sep1.mac)
2845 self.assertEqual(rx[IP].src, ep1.ip4.address)
2846 self.assertEqual(rx[IP].dst, "10.0.0.88")
2847
2848 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2849
2850 for rx in rxs:
2851 self.assertEqual(rx[Ether].src, routed_src_mac)
2852 self.assertEqual(rx[Ether].dst, sep4.mac)
2853 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2854 self.assertEqual(rx[IPv6].dst, "2001:10::88")
2855
2856 rxs = self.send_and_expect(self.pg0, p6[1] * 17, sep3.itf)
2857
2858 for rx in rxs:
2859 self.assertEqual(rx[Ether].src, routed_src_mac)
2860 self.assertEqual(rx[Ether].dst, sep3.mac)
2861 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2862 self.assertEqual(rx[IPv6].dst, "2001:10::88")
2863
Neale Rannsbc27d1b2018-02-05 01:13:38 -08002864
2865if __name__ == '__main__':
2866 unittest.main(testRunner=VppTestRunner)