blob: 92480cebba3d0ed95fff0080eac2cf35d779d905 [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 Rannsbc27d1b2018-02-05 01:13:38 -0800368class VppGbpContract(VppObject):
369 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200370 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800371 """
372
373 def __init__(self, test, src_epg, dst_epg, acl_index):
374 self._test = test
375 self.acl_index = acl_index
376 self.src_epg = src_epg
377 self.dst_epg = dst_epg
378
379 def add_vpp_config(self):
380 self._test.vapi.gbp_contract_add_del(
381 1,
382 self.src_epg,
383 self.dst_epg,
384 self.acl_index)
385 self._test.registry.register(self, self._test.logger)
386
387 def remove_vpp_config(self):
388 self._test.vapi.gbp_contract_add_del(
389 0,
390 self.src_epg,
391 self.dst_epg,
392 self.acl_index)
393
394 def __str__(self):
395 return self.object_id()
396
397 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700398 return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800399 self.dst_epg,
400 self.acl_index)
401
402 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700403 cs = self._test.vapi.gbp_contract_dump()
404 for c in cs:
405 if c.contract.src_epg == self.src_epg \
406 and c.contract.dst_epg == self.dst_epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800407 return True
408 return False
409
410
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700411class VppGbpVxlanTunnel(VppInterface):
412 """
413 GBP VXLAN tunnel
414 """
415
416 def __init__(self, test, vni, bd_rd_id, mode):
417 super(VppGbpVxlanTunnel, self).__init__(test)
418 self._test = test
419 self.vni = vni
420 self.bd_rd_id = bd_rd_id
421 self.mode = mode
422
423 def add_vpp_config(self):
424 r = self._test.vapi.gbp_vxlan_tunnel_add(
425 self.vni,
426 self.bd_rd_id,
427 self.mode)
428 self.set_sw_if_index(r.sw_if_index)
429 self._test.registry.register(self, self._test.logger)
430
431 def remove_vpp_config(self):
432 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
433
434 def __str__(self):
435 return self.object_id()
436
437 def object_id(self):
438 return "gbp-vxlan:%d" % (self.vni)
439
440 def query_vpp_config(self):
441 return find_gbp_vxlan(self._test, self.vni)
442
443
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200444class VppGbpAcl(VppObject):
445 """
446 GBP Acl
447 """
448
449 def __init__(self, test):
450 self._test = test
451 self.acl_index = 4294967295
452
453 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
454 s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
455 sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
456 dport_from=0, dport_to=65535):
457 if proto == -1 or proto == 0:
458 sport_to = 0
459 dport_to = sport_to
460 elif proto == 1 or proto == 58:
461 sport_to = 255
462 dport_to = sport_to
463 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
464 'srcport_or_icmptype_first': sport_from,
465 'srcport_or_icmptype_last': sport_to,
466 'src_ip_prefix_len': s_prefix,
467 'src_ip_addr': s_ip,
468 'dstport_or_icmpcode_first': dport_from,
469 'dstport_or_icmpcode_last': dport_to,
470 'dst_ip_prefix_len': d_prefix,
471 'dst_ip_addr': d_ip})
472 return rule
473
474 def add_vpp_config(self, rules):
475
476 reply = self._test.vapi.acl_add_replace(self.acl_index,
477 r=rules,
478 tag='GBPTest')
479 self.acl_index = reply.acl_index
480 return self.acl_index
481
482 def remove_vpp_config(self):
483 self._test.vapi.acl_del(self.acl_index)
484
485 def __str__(self):
486 return self.object_id()
487
488 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700489 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200490
491 def query_vpp_config(self):
492 cs = self._test.vapi.acl_dump()
493 for c in cs:
494 if c.acl_index == self.acl_index:
495 return True
496 return False
497
498
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800499class TestGBP(VppTestCase):
500 """ GBP Test Case """
501
502 def setUp(self):
503 super(TestGBP, self).setUp()
504
Neale Ranns25b04942018-04-04 09:34:50 -0700505 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700506 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700507
Neale Ranns4d5b9172018-10-24 02:57:49 -0700508 self.router_mac = VppMacAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800509
510 for i in self.pg_interfaces:
511 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700512 for i in self.lo_interfaces:
513 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800514
515 def tearDown(self):
516 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700517 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800518
519 super(TestGBP, self).tearDown()
520
Neale Ranns25b04942018-04-04 09:34:50 -0700521 def send_and_expect_bridged(self, src, tx, dst):
522 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800523
Neale Ranns25b04942018-04-04 09:34:50 -0700524 for r in rx:
525 self.assertEqual(r[Ether].src, tx[0][Ether].src)
526 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
527 self.assertEqual(r[IP].src, tx[0][IP].src)
528 self.assertEqual(r[IP].dst, tx[0][IP].dst)
529 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800530
Neale Ranns25b04942018-04-04 09:34:50 -0700531 def send_and_expect_bridged6(self, src, tx, dst):
532 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800533
Neale Ranns25b04942018-04-04 09:34:50 -0700534 for r in rx:
535 self.assertEqual(r[Ether].src, tx[0][Ether].src)
536 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
537 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
538 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
539 return rx
540
541 def send_and_expect_routed(self, src, tx, dst, src_mac):
542 rx = self.send_and_expect(src, tx, dst)
543
544 for r in rx:
545 self.assertEqual(r[Ether].src, src_mac)
546 self.assertEqual(r[Ether].dst, dst.remote_mac)
547 self.assertEqual(r[IP].src, tx[0][IP].src)
548 self.assertEqual(r[IP].dst, tx[0][IP].dst)
549 return rx
550
551 def send_and_expect_natted(self, src, tx, dst, src_ip):
552 rx = self.send_and_expect(src, tx, dst)
553
554 for r in rx:
555 self.assertEqual(r[Ether].src, tx[0][Ether].src)
556 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
557 self.assertEqual(r[IP].src, src_ip)
558 self.assertEqual(r[IP].dst, tx[0][IP].dst)
559 return rx
560
Neale Ranns4a6d0232018-04-24 07:45:33 -0700561 def send_and_expect_natted6(self, src, tx, dst, src_ip):
562 rx = self.send_and_expect(src, tx, dst)
563
564 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[IPv6].src, src_ip)
568 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
569 return rx
570
Neale Ranns25b04942018-04-04 09:34:50 -0700571 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
572 rx = self.send_and_expect(src, tx, dst)
573
574 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[IP].dst, dst_ip)
578 self.assertEqual(r[IP].src, tx[0][IP].src)
579 return rx
580
Neale Ranns4a6d0232018-04-24 07:45:33 -0700581 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
582 rx = self.send_and_expect(src, tx, dst)
583
584 for r in rx:
585 self.assertEqual(r[Ether].src, tx[0][Ether].src)
586 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
587 self.assertEqual(r[IPv6].dst, dst_ip)
588 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
589 return rx
590
Neale Ranns25b04942018-04-04 09:34:50 -0700591 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
592 rx = self.send_and_expect(src, tx, dst)
593
594 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700595 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700596 self.assertEqual(r[Ether].dst, dst.remote_mac)
597 self.assertEqual(r[IP].dst, dst_ip)
598 self.assertEqual(r[IP].src, src_ip)
599 return rx
600
Neale Ranns4a6d0232018-04-24 07:45:33 -0700601 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
602 rx = self.send_and_expect(src, tx, dst)
603
604 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700605 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700606 self.assertEqual(r[Ether].dst, dst.remote_mac)
607 self.assertEqual(r[IPv6].dst, dst_ip)
608 self.assertEqual(r[IPv6].src, src_ip)
609 return rx
610
Neale Ranns25b04942018-04-04 09:34:50 -0700611 def test_gbp(self):
612 """ Group Based Policy """
613
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800614 #
Neale Ranns25b04942018-04-04 09:34:50 -0700615 # Bridge Domains
616 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700617 bd1 = VppBridgeDomain(self, 1)
618 bd2 = VppBridgeDomain(self, 2)
619 bd20 = VppBridgeDomain(self, 20)
620
621 bd1.add_vpp_config()
622 bd2.add_vpp_config()
623 bd20.add_vpp_config()
624
625 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
626 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
627 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
628
629 gbd1.add_vpp_config()
630 gbd2.add_vpp_config()
631 gbd20.add_vpp_config()
632
633 #
634 # Route Domains
635 #
636 gt4 = VppIpTable(self, 0)
637 gt4.add_vpp_config()
638 gt6 = VppIpTable(self, 0, is_ip6=True)
639 gt6.add_vpp_config()
640 nt4 = VppIpTable(self, 20)
641 nt4.add_vpp_config()
642 nt6 = VppIpTable(self, 20, is_ip6=True)
643 nt6.add_vpp_config()
644
645 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
646 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
647
648 rd0.add_vpp_config()
649 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700650
651 #
652 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700653 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
654 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700655 epgs = [VppGbpEndpointGroup(self, 220, rd0, gbd1, self.pg4,
Neale Rannsc0a93142018-09-05 15:42:26 -0700656 self.loop0,
657 "10.0.0.128",
658 "2001:10::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700659 VppGbpEndpointGroup(self, 221, rd0, gbd1, self.pg5,
Neale Rannsc0a93142018-09-05 15:42:26 -0700660 self.loop0,
661 "10.0.1.128",
662 "2001:10:1::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700663 VppGbpEndpointGroup(self, 222, rd0, gbd2, self.pg6,
Neale Rannsc0a93142018-09-05 15:42:26 -0700664 self.loop1,
665 "10.0.2.128",
666 "2001:10:2::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700667 VppGbpEndpointGroup(self, 333, rd20, gbd20, self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -0700668 self.loop2,
669 "11.0.0.128",
670 "3001::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700671 VppGbpEndpointGroup(self, 444, rd20, gbd20, self.pg8,
Neale Rannsc0a93142018-09-05 15:42:26 -0700672 self.loop2,
673 "11.0.0.129",
674 "3001::129")]
675 recircs = [VppGbpRecirc(self, epgs[0],
676 self.loop3),
677 VppGbpRecirc(self, epgs[1],
678 self.loop4),
679 VppGbpRecirc(self, epgs[2],
680 self.loop5),
681 VppGbpRecirc(self, epgs[3],
682 self.loop6, is_ext=True),
683 VppGbpRecirc(self, epgs[4],
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700684 self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700685
686 epg_nat = epgs[3]
687 recirc_nat = recircs[3]
688
689 #
690 # 4 end-points, 2 in the same subnet, 3 in the same BD
691 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700692 eps = [VppGbpEndpoint(self, self.pg0,
693 epgs[0], recircs[0],
694 "10.0.0.1", "11.0.0.1",
695 "2001:10::1", "3001::1"),
696 VppGbpEndpoint(self, self.pg1,
697 epgs[0], recircs[0],
698 "10.0.0.2", "11.0.0.2",
699 "2001:10::2", "3001::2"),
700 VppGbpEndpoint(self, self.pg2,
701 epgs[1], recircs[1],
702 "10.0.1.1", "11.0.0.3",
703 "2001:10:1::1", "3001::3"),
704 VppGbpEndpoint(self, self.pg3,
705 epgs[2], recircs[2],
706 "10.0.2.1", "11.0.0.4",
707 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700708
709 #
710 # Config related to each of the EPGs
711 #
712 for epg in epgs:
713 # IP config on the BVI interfaces
714 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700715 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
716 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
717 self.vapi.sw_interface_set_mac_address(
718 epg.bvi.sw_if_index,
719 self.router_mac.bytes)
Neale Ranns25b04942018-04-04 09:34:50 -0700720
721 # The BVIs are NAT inside interfaces
722 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
723 is_inside=1,
724 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700725 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
726 is_inside=1,
727 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700728
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700729 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
730 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
731 if_ip4.add_vpp_config()
732 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700733
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700734 # EPG uplink interfaces in the RD
735 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
736 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700737
738 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700739 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
740 self.router_mac.address,
741 epg.bvi_ip4)
742 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
743 self.router_mac.address,
744 epg.bvi_ip6)
745 epg.bd_arp_ip4.add_vpp_config()
746 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700747
748 # EPG in VPP
749 epg.add_vpp_config()
750
751 for recirc in recircs:
752 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700753 VppIpInterfaceBind(self, recirc.recirc,
754 recirc.epg.rd.t4).add_vpp_config()
755 VppIpInterfaceBind(self, recirc.recirc,
756 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700757
Neale Ranns25b04942018-04-04 09:34:50 -0700758 self.vapi.sw_interface_set_l2_emulation(
759 recirc.recirc.sw_if_index)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700760 self.vapi.nat44_interface_add_del_feature(
761 recirc.recirc.sw_if_index,
762 is_inside=0,
763 is_add=1)
764 self.vapi.nat66_add_del_interface(
765 recirc.recirc.sw_if_index,
766 is_inside=0,
767 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700768
769 recirc.add_vpp_config()
770
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700771 for recirc in recircs:
772 self.assertTrue(find_bridge_domain_port(self,
773 recirc.epg.bd.bd.bd_id,
774 recirc.recirc.sw_if_index))
775
Neale Ranns25b04942018-04-04 09:34:50 -0700776 for ep in eps:
777 self.pg_enable_capture(self.pg_interfaces)
778 self.pg_start()
779 #
780 # routes to the endpoints. We need these since there are no
781 # adj-fibs due to the fact the the BVI address has /32 and
782 # the subnet is not attached.
783 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700784 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700785 # Add static mappings for each EP from the 10/8 to 11/8 network
786 if ip.af == AF_INET:
787 self.vapi.nat44_add_del_static_mapping(ip.bytes,
788 fip.bytes,
789 vrf_id=0,
790 addr_only=1)
791 else:
792 self.vapi.nat66_add_del_static_mapping(ip.bytes,
793 fip.bytes,
794 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700795
Neale Ranns25b04942018-04-04 09:34:50 -0700796 # VPP EP create ...
797 ep.add_vpp_config()
798
Neale Rannsc0a93142018-09-05 15:42:26 -0700799 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700800
Neale Rannsc0a93142018-09-05 15:42:26 -0700801 # ... results in a Gratuitous ARP/ND on the EPG's uplink
802 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
803
804 for ii, ip in enumerate(ep.ips):
805 p = rx[ii]
806
807 if ip.is_ip6:
808 self.assertTrue(p.haslayer(ICMPv6ND_NA))
809 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
810 else:
811 self.assertTrue(p.haslayer(ARP))
812 self.assertEqual(p[ARP].psrc, ip.address)
813 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700814
815 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700816 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700817 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
818 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700819
Neale Rannsc0a93142018-09-05 15:42:26 -0700820 # floating IPs route via EPG recirc
821 r = VppIpRoute(self, fip.address, fip.length,
822 [VppRoutePath(fip.address,
823 ep.recirc.recirc.sw_if_index,
824 is_dvr=1,
825 proto=fip.dpo_proto)],
826 table_id=20,
827 is_ip6=fip.is_ip6)
828 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700829
830 # L2 FIB entries in the NAT EPG BD to bridge the packets from
831 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700832 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
833 ep.recirc.recirc, bvi_mac=0)
834 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700835
836 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700837 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700838 #
839 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
840 src=self.pg0.remote_mac) /
841 ARP(op="who-has",
842 hwdst="ff:ff:ff:ff:ff:ff",
843 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700844 pdst="10.0.0.88",
845 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700846
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700847 self.vapi.cli("clear trace")
848 self.pg0.add_stream(pkt_arp)
849
850 self.pg_enable_capture(self.pg_interfaces)
851 self.pg_start()
852
853 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700854
855 #
856 # ARP/ND packets get a response
857 #
858 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
859 src=self.pg0.remote_mac) /
860 ARP(op="who-has",
861 hwdst="ff:ff:ff:ff:ff:ff",
862 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700863 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700864 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700865
866 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
867
Neale Rannsc0a93142018-09-05 15:42:26 -0700868 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700869 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700870 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
871 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700872 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700873 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700874 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
875 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
876
877 #
878 # broadcast packets are flooded
879 #
880 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
881 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700882 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700883 UDP(sport=1234, dport=1234) /
884 Raw('\xa5' * 100))
885
886 self.vapi.cli("clear trace")
887 self.pg0.add_stream(pkt_bcast)
888
889 self.pg_enable_capture(self.pg_interfaces)
890 self.pg_start()
891
892 rxd = eps[1].itf.get_capture(1)
893 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
894 rxd = epgs[0].uplink.get_capture(1)
895 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
896
897 #
898 # packets to non-local L3 destinations dropped
899 #
900 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700901 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700902 IP(src=eps[0].ip4.address,
903 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700904 UDP(sport=1234, dport=1234) /
905 Raw('\xa5' * 100))
906 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700907 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700908 IP(src=eps[0].ip4.address,
909 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700910 UDP(sport=1234, dport=1234) /
911 Raw('\xa5' * 100))
912
913 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
914
915 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700916 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700917 IPv6(src=eps[0].ip6.address,
918 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700919 UDP(sport=1234, dport=1234) /
920 Raw('\xa5' * 100))
921 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
922
923 #
924 # Add the subnet routes
925 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700926 s41 = VppGbpSubnet(
927 self, rd0, "10.0.0.0", 24,
928 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
929 s42 = VppGbpSubnet(
930 self, rd0, "10.0.1.0", 24,
931 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
932 s43 = VppGbpSubnet(
933 self, rd0, "10.0.2.0", 24,
934 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
935 s61 = VppGbpSubnet(
936 self, rd0, "2001:10::1", 64,
937 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
938 s62 = VppGbpSubnet(
939 self, rd0, "2001:10:1::1", 64,
940 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
941 s63 = VppGbpSubnet(
942 self, rd0, "2001:10:2::1", 64,
943 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -0700944 s41.add_vpp_config()
945 s42.add_vpp_config()
946 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700947 s61.add_vpp_config()
948 s62.add_vpp_config()
949 s63.add_vpp_config()
950
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700951 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700952 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700953 eps[0].epg.uplink)
954 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700955 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700956 eps[0].epg.uplink)
957 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700958 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700959 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -0700960
961 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
962 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
963 self.logger.info(self.vapi.cli("sh gbp endpoint"))
964 self.logger.info(self.vapi.cli("sh gbp recirc"))
965 self.logger.info(self.vapi.cli("sh int"))
966 self.logger.info(self.vapi.cli("sh int addr"))
967 self.logger.info(self.vapi.cli("sh int feat loop6"))
968 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
969 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700970 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -0700971
972 #
973 # Packet destined to unknown unicast is sent on the epg uplink ...
974 #
975 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
976 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -0700977 IP(src=eps[0].ip4.address,
978 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700979 UDP(sport=1234, dport=1234) /
980 Raw('\xa5' * 100))
981
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700982 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700983 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700984 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -0700985 # ... and nowhere else
986 self.pg1.get_capture(0, timeout=0.1)
987 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
988
989 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
990 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -0700991 IP(src=eps[0].ip4.address,
992 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700993 UDP(sport=1234, dport=1234) /
994 Raw('\xa5' * 100))
995
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700996 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -0700997 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700998 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -0700999
1000 #
1001 # Packets from the uplink are forwarded in the absence of a contract
1002 #
1003 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1004 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001005 IP(src=eps[0].ip4.address,
1006 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001007 UDP(sport=1234, dport=1234) /
1008 Raw('\xa5' * 100))
1009
1010 self.send_and_expect_bridged(self.pg4,
1011 pkt_intra_epg_220_from_uplink * 65,
1012 self.pg0)
1013
1014 #
1015 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001016 # can communicate
1017 #
1018 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001019 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001020 IP(src=eps[0].ip4.address,
1021 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001022 UDP(sport=1234, dport=1234) /
1023 Raw('\xa5' * 100))
1024
Neale Ranns25b04942018-04-04 09:34:50 -07001025 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001026
1027 #
1028 # in the abscense of policy, endpoints in the different EPG
1029 # cannot communicate
1030 #
1031 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001032 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001033 IP(src=eps[0].ip4.address,
1034 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001035 UDP(sport=1234, dport=1234) /
1036 Raw('\xa5' * 100))
1037 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001038 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001039 IP(src=eps[2].ip4.address,
1040 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001041 UDP(sport=1234, dport=1234) /
1042 Raw('\xa5' * 100))
1043 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001044 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001045 IP(src=eps[0].ip4.address,
1046 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001047 UDP(sport=1234, dport=1234) /
1048 Raw('\xa5' * 100))
1049
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001050 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001051 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001052 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001053 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001054
1055 #
1056 # A uni-directional contract from EPG 220 -> 221
1057 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001058 acl = VppGbpAcl(self)
1059 rule = acl.create_rule(permit_deny=1, proto=17)
1060 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1061 acl_index = acl.add_vpp_config([rule, rule2])
1062 c1 = VppGbpContract(self, 220, 221, acl_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001063 c1.add_vpp_config()
1064
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001065 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001066 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001067 eps[2].itf)
1068 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001069 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001070
1071 #
1072 # contract for the return direction
1073 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001074 c2 = VppGbpContract(self, 221, 220, acl_index)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001075 c2.add_vpp_config()
1076
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001077 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001078 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001079 eps[2].itf)
1080 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001081 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001082 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001083
1084 #
1085 # check that inter group is still disabled for the groups
1086 # not in the contract.
1087 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001088 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001089 pkt_inter_epg_220_to_222 * 65)
1090
Neale Ranns25b04942018-04-04 09:34:50 -07001091 #
1092 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1093 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001094 c3 = VppGbpContract(self, 220, 222, acl_index)
Neale Ranns25b04942018-04-04 09:34:50 -07001095 c3.add_vpp_config()
1096
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001097 self.logger.info(self.vapi.cli("sh gbp contract"))
1098
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001099 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001100 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001101 eps[3].itf,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001102 self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001103
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001104 #
1105 # remove both contracts, traffic stops in both directions
1106 #
1107 c2.remove_vpp_config()
1108 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001109 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001110 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001111
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001112 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001113 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001114 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001115 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001116 self.send_and_expect_bridged(eps[0].itf,
1117 pkt_intra_epg * 65,
1118 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001119
1120 #
Neale Ranns25b04942018-04-04 09:34:50 -07001121 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001122 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001123
Neale Ranns25b04942018-04-04 09:34:50 -07001124 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001125 se1 = VppGbpSubnet(
1126 self, rd0, "0.0.0.0", 0,
1127 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1128 sw_if_index=recirc_nat.recirc.sw_if_index,
1129 epg=epg_nat.epg)
1130 se2 = VppGbpSubnet(
1131 self, rd0, "11.0.0.0", 8,
1132 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1133 sw_if_index=recirc_nat.recirc.sw_if_index,
1134 epg=epg_nat.epg)
1135 se16 = VppGbpSubnet(
1136 self, rd0, "::", 0,
1137 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1138 sw_if_index=recirc_nat.recirc.sw_if_index,
1139 epg=epg_nat.epg)
Neale Ranns25b04942018-04-04 09:34:50 -07001140 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001141 se3 = VppGbpSubnet(
1142 self, rd20, "0.0.0.0", 0,
1143 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1144 sw_if_index=epg_nat.uplink.sw_if_index,
1145 epg=epg_nat.epg)
1146 se36 = VppGbpSubnet(
1147 self, rd20, "::", 0,
1148 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1149 sw_if_index=epg_nat.uplink.sw_if_index,
1150 epg=epg_nat.epg)
1151 se4 = VppGbpSubnet(
1152 self, rd20, "11.0.0.0", 8,
1153 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1154 sw_if_index=epg_nat.uplink.sw_if_index,
1155 epg=epg_nat.epg)
1156 se1.add_vpp_config()
1157 se2.add_vpp_config()
1158 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001159 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001160 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001161 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001162
Neale Ranns25b04942018-04-04 09:34:50 -07001163 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1164 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001165 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1166 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001167 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001168
Neale Ranns4a6d0232018-04-24 07:45:33 -07001169 #
1170 # From an EP to an outside addess: IN2OUT
1171 #
Neale Ranns25b04942018-04-04 09:34:50 -07001172 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001173 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001174 IP(src=eps[0].ip4.address,
1175 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001176 UDP(sport=1234, dport=1234) /
1177 Raw('\xa5' * 100))
1178
1179 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001180 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001181 pkt_inter_epg_220_to_global * 65)
1182
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001183 acl2 = VppGbpAcl(self)
1184 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1185 sport_to=1234, dport_from=1234, dport_to=1234)
1186 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1187 sport_from=1234, sport_to=1234,
1188 dport_from=1234, dport_to=1234)
1189
1190 acl_index2 = acl2.add_vpp_config([rule, rule2])
1191 c4 = VppGbpContract(self, 220, 333, acl_index2)
Neale Ranns25b04942018-04-04 09:34:50 -07001192 c4.add_vpp_config()
1193
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001194 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001195 pkt_inter_epg_220_to_global * 65,
1196 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001197 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001198
Neale Ranns4a6d0232018-04-24 07:45:33 -07001199 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001200 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001201 IPv6(src=eps[0].ip6.address,
1202 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001203 UDP(sport=1234, dport=1234) /
1204 Raw('\xa5' * 100))
1205
1206 self.send_and_expect_natted6(self.pg0,
1207 pkt_inter_epg_220_to_global * 65,
1208 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001209 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001210
1211 #
1212 # From a global address to an EP: OUT2IN
1213 #
Neale Ranns4d5b9172018-10-24 02:57:49 -07001214 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001215 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001216 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001217 src="1.1.1.1") /
1218 UDP(sport=1234, dport=1234) /
1219 Raw('\xa5' * 100))
1220
1221 self.send_and_assert_no_replies(self.pg7,
1222 pkt_inter_epg_220_from_global * 65)
1223
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001224 c5 = VppGbpContract(self, 333, 220, acl_index2)
Neale Ranns25b04942018-04-04 09:34:50 -07001225 c5.add_vpp_config()
1226
1227 self.send_and_expect_unnatted(self.pg7,
1228 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001229 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001230 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001231
Neale Ranns4d5b9172018-10-24 02:57:49 -07001232 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001233 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001234 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001235 src="6001::1") /
1236 UDP(sport=1234, dport=1234) /
1237 Raw('\xa5' * 100))
1238
1239 self.send_and_expect_unnatted6(self.pg7,
1240 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001241 eps[0].itf,
1242 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001243
1244 #
1245 # From a local VM to another local VM using resp. public addresses:
1246 # IN2OUT2IN
1247 #
Neale Ranns25b04942018-04-04 09:34:50 -07001248 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001249 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001250 IP(src=eps[0].ip4.address,
1251 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001252 UDP(sport=1234, dport=1234) /
1253 Raw('\xa5' * 100))
1254
Neale Ranns4a6d0232018-04-24 07:45:33 -07001255 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001256 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001257 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001258 eps[0].fip4.address,
1259 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001260
Neale Rannsc0a93142018-09-05 15:42:26 -07001261 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001262 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001263 IPv6(src=eps[0].ip6.address,
1264 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001265 UDP(sport=1234, dport=1234) /
1266 Raw('\xa5' * 100))
1267
Neale Rannsc0a93142018-09-05 15:42:26 -07001268 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001269 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001270 eps[1].itf,
1271 eps[0].fip6.address,
1272 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001273
1274 #
Neale Ranns25b04942018-04-04 09:34:50 -07001275 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001276 #
Neale Ranns25b04942018-04-04 09:34:50 -07001277 for ep in eps:
1278 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001279 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1280 ep.fip4.bytes,
1281 vrf_id=0,
1282 addr_only=1,
1283 is_add=0)
1284 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1285 ep.fip6.bytes,
1286 vrf_id=0,
1287 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001288
Neale Ranns25b04942018-04-04 09:34:50 -07001289 for epg in epgs:
1290 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001291 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001292 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1293 is_inside=1,
1294 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001295 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1296 is_inside=1,
1297 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001298
Neale Ranns25b04942018-04-04 09:34:50 -07001299 for recirc in recircs:
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001300 self.vapi.sw_interface_set_l2_emulation(
1301 recirc.recirc.sw_if_index, enable=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001302 self.vapi.nat44_interface_add_del_feature(
1303 recirc.recirc.sw_if_index,
1304 is_inside=0,
1305 is_add=0)
1306 self.vapi.nat66_add_del_interface(
1307 recirc.recirc.sw_if_index,
1308 is_inside=0,
1309 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001310
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001311 def test_gbp_learn_l2(self):
1312 """ GBP L2 Endpoint Learning """
1313
1314 learnt = [{'mac': '00:00:11:11:11:01',
1315 'ip': '10.0.0.1',
1316 'ip6': '2001:10::2'},
1317 {'mac': '00:00:11:11:11:02',
1318 'ip': '10.0.0.2',
1319 'ip6': '2001:10::3'}]
1320
1321 #
1322 # lower the inactive threshold so these tests pass in a
1323 # reasonable amount of time
1324 #
1325 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1326
1327 #
1328 # IP tables
1329 #
1330 gt4 = VppIpTable(self, 1)
1331 gt4.add_vpp_config()
1332 gt6 = VppIpTable(self, 1, is_ip6=True)
1333 gt6.add_vpp_config()
1334
1335 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1336 rd1.add_vpp_config()
1337
1338 #
1339 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1340 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1341 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1342 #
1343 self.pg2.config_ip4()
1344 self.pg2.resolve_arp()
1345 self.pg2.generate_remote_hosts(4)
1346 self.pg2.configure_ipv4_neighbors()
1347 self.pg3.config_ip4()
1348 self.pg3.resolve_arp()
1349 self.pg4.config_ip4()
1350 self.pg4.resolve_arp()
1351
1352 #
1353 # a GBP bridge domain with a BVI and a UU-flood interface
1354 #
1355 bd1 = VppBridgeDomain(self, 1)
1356 bd1.add_vpp_config()
1357 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
1358 gbd1.add_vpp_config()
1359
1360 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1361 self.logger.info(self.vapi.cli("sh gbp bridge"))
1362
1363 # ... and has a /32 applied
1364 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1365 ip_addr.add_vpp_config()
1366
1367 #
1368 # The Endpoint-group in which we are learning endpoints
1369 #
1370 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1371 None, self.loop0,
1372 "10.0.0.128",
1373 "2001:10::128")
1374 epg_220.add_vpp_config()
1375 epg_330 = VppGbpEndpointGroup(self, 330, rd1, gbd1,
1376 None, self.loop1,
1377 "10.0.1.128",
1378 "2001:11::128")
1379 epg_330.add_vpp_config()
1380
1381 #
1382 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1383 # leanring enabled
1384 #
1385 vx_tun_l2_1 = VppGbpVxlanTunnel(
1386 self, 99, bd1.bd_id,
1387 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1388 vx_tun_l2_1.add_vpp_config()
1389
1390 #
1391 # A static endpoint that the learnt endpoints are trying to
1392 # talk to
1393 #
1394 ep = VppGbpEndpoint(self, self.pg0,
1395 epg_220, None,
1396 "10.0.0.127", "11.0.0.127",
1397 "2001:10::1", "3001::1")
1398 ep.add_vpp_config()
1399
1400 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1401
1402 # a packet with an sclass from an unknwon EPG
1403 p = (Ether(src=self.pg2.remote_mac,
1404 dst=self.pg2.local_mac) /
1405 IP(src=self.pg2.remote_hosts[0].ip4,
1406 dst=self.pg2.local_ip4) /
1407 UDP(sport=1234, dport=48879) /
1408 VXLAN(vni=99, gpid=88, flags=0x88) /
1409 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1410 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1411 UDP(sport=1234, dport=1234) /
1412 Raw('\xa5' * 100))
1413
1414 self.send_and_assert_no_replies(self.pg2, p)
1415
1416 #
1417 # we should not have learnt a new tunnel endpoint, since
1418 # the EPG was not learnt.
1419 #
1420 self.assertEqual(INDEX_INVALID,
1421 find_vxlan_gbp_tunnel(self,
1422 self.pg2.local_ip4,
1423 self.pg2.remote_hosts[0].ip4,
1424 99))
1425
1426 # epg is not learnt, becasue the EPG is unknwon
1427 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1428
1429 for ii, l in enumerate(learnt):
1430 # a packet with an sclass from a knwon EPG
1431 # arriving on an unknown TEP
1432 p = (Ether(src=self.pg2.remote_mac,
1433 dst=self.pg2.local_mac) /
1434 IP(src=self.pg2.remote_hosts[1].ip4,
1435 dst=self.pg2.local_ip4) /
1436 UDP(sport=1234, dport=48879) /
1437 VXLAN(vni=99, gpid=220, flags=0x88) /
1438 Ether(src=l['mac'], dst=ep.mac) /
1439 IP(src=l['ip'], dst=ep.ip4.address) /
1440 UDP(sport=1234, dport=1234) /
1441 Raw('\xa5' * 100))
1442
1443 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1444
1445 # the new TEP
1446 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1447 self,
1448 self.pg2.local_ip4,
1449 self.pg2.remote_hosts[1].ip4,
1450 99)
1451 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1452
1453 #
1454 # the EP is learnt via the learnt TEP
1455 # both from its MAC and its IP
1456 #
1457 self.assertTrue(find_gbp_endpoint(self,
1458 vx_tun_l2_1.sw_if_index,
1459 mac=l['mac']))
1460 self.assertTrue(find_gbp_endpoint(self,
1461 vx_tun_l2_1.sw_if_index,
1462 ip=l['ip']))
1463
1464 self.logger.info(self.vapi.cli("show gbp endpoint"))
1465 self.logger.info(self.vapi.cli("show gbp vxlan"))
1466 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1467
1468 #
1469 # If we sleep for the threshold time, the learnt endpoints should
1470 # age out
1471 #
1472 self.sleep(2)
1473 for l in learnt:
1474 self.assertFalse(find_gbp_endpoint(self,
1475 tep1_sw_if_index,
1476 mac=l['mac']))
1477
1478 self.logger.info(self.vapi.cli("show gbp endpoint"))
1479 self.logger.info(self.vapi.cli("show gbp vxlan"))
1480 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1481
1482 #
1483 # repeat. the do not learn bit is set so the EPs are not learnt
1484 #
1485 for l in learnt:
1486 # a packet with an sclass from a knwon EPG
1487 p = (Ether(src=self.pg2.remote_mac,
1488 dst=self.pg2.local_mac) /
1489 IP(src=self.pg2.remote_hosts[1].ip4,
1490 dst=self.pg2.local_ip4) /
1491 UDP(sport=1234, dport=48879) /
1492 VXLAN(vni=99, gpid=220, flags=0x88, gpflags="D") /
1493 Ether(src=l['mac'], dst=ep.mac) /
1494 IP(src=l['ip'], dst=ep.ip4.address) /
1495 UDP(sport=1234, dport=1234) /
1496 Raw('\xa5' * 100))
1497
1498 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1499
1500 for l in learnt:
1501 self.assertFalse(find_gbp_endpoint(self,
1502 vx_tun_l2_1.sw_if_index,
1503 mac=l['mac']))
1504
1505 #
1506 # repeat
1507 #
1508 for l in learnt:
1509 # a packet with an sclass from a knwon EPG
1510 p = (Ether(src=self.pg2.remote_mac,
1511 dst=self.pg2.local_mac) /
1512 IP(src=self.pg2.remote_hosts[1].ip4,
1513 dst=self.pg2.local_ip4) /
1514 UDP(sport=1234, dport=48879) /
1515 VXLAN(vni=99, gpid=220, flags=0x88) /
1516 Ether(src=l['mac'], dst=ep.mac) /
1517 IP(src=l['ip'], dst=ep.ip4.address) /
1518 UDP(sport=1234, dport=1234) /
1519 Raw('\xa5' * 100))
1520
1521 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1522
1523 self.assertTrue(find_gbp_endpoint(self,
1524 vx_tun_l2_1.sw_if_index,
1525 mac=l['mac']))
1526
1527 #
1528 # Static EP replies to dynamics
1529 #
1530 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1531 for l in learnt:
1532 p = (Ether(src=ep.mac, dst=l['mac']) /
1533 IP(dst=l['ip'], src=ep.ip4.address) /
1534 UDP(sport=1234, dport=1234) /
1535 Raw('\xa5' * 100))
1536
1537 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1538
1539 for rx in rxs:
1540 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1541 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1542 self.assertEqual(rx[UDP].dport, 48879)
1543 # the UDP source port is a random value for hashing
1544 self.assertEqual(rx[VXLAN].gpid, 220)
1545 self.assertEqual(rx[VXLAN].vni, 99)
1546 self.assertTrue(rx[VXLAN].flags.G)
1547 self.assertTrue(rx[VXLAN].flags.Instance)
1548 self.assertTrue(rx[VXLAN].gpflags.A)
1549 self.assertFalse(rx[VXLAN].gpflags.D)
1550
1551 self.sleep(2)
1552 for l in learnt:
1553 self.assertFalse(find_gbp_endpoint(self,
1554 vx_tun_l2_1.sw_if_index,
1555 mac=l['mac']))
1556
1557 #
1558 # repeat in the other EPG
1559 # there's no contract between 220 and 330, but the A-bit is set
1560 # so the packet is cleared for delivery
1561 #
1562 for l in learnt:
1563 # a packet with an sclass from a knwon EPG
1564 p = (Ether(src=self.pg2.remote_mac,
1565 dst=self.pg2.local_mac) /
1566 IP(src=self.pg2.remote_hosts[1].ip4,
1567 dst=self.pg2.local_ip4) /
1568 UDP(sport=1234, dport=48879) /
1569 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1570 Ether(src=l['mac'], dst=ep.mac) /
1571 IP(src=l['ip'], dst=ep.ip4.address) /
1572 UDP(sport=1234, dport=1234) /
1573 Raw('\xa5' * 100))
1574
1575 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1576
1577 self.assertTrue(find_gbp_endpoint(self,
1578 vx_tun_l2_1.sw_if_index,
1579 mac=l['mac']))
1580
1581 #
1582 # static EP cannot reach the learnt EPs since there is no contract
1583 #
1584 self.logger.info(self.vapi.cli("show gbp endpoint"))
1585 self.logger.info(self.vapi.cli("show l2fib all"))
1586 for l in learnt:
1587 p = (Ether(src=ep.mac, dst=l['mac']) /
1588 IP(dst=l['ip'], src=ep.ip4.address) /
1589 UDP(sport=1234, dport=1234) /
1590 Raw('\xa5' * 100))
1591
1592 self.send_and_assert_no_replies(self.pg0, [p], timeout=0.2)
1593
1594 #
1595 # refresh the entries after the check for no replies above
1596 #
1597 for l in learnt:
1598 # a packet with an sclass from a knwon EPG
1599 p = (Ether(src=self.pg2.remote_mac,
1600 dst=self.pg2.local_mac) /
1601 IP(src=self.pg2.remote_hosts[1].ip4,
1602 dst=self.pg2.local_ip4) /
1603 UDP(sport=1234, dport=48879) /
1604 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1605 Ether(src=l['mac'], dst=ep.mac) /
1606 IP(src=l['ip'], dst=ep.ip4.address) /
1607 UDP(sport=1234, dport=1234) /
1608 Raw('\xa5' * 100))
1609
1610 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1611
1612 self.assertTrue(find_gbp_endpoint(self,
1613 vx_tun_l2_1.sw_if_index,
1614 mac=l['mac']))
1615
1616 #
1617 # Add the contract so they can talk
1618 #
1619 acl = VppGbpAcl(self)
1620 rule = acl.create_rule(permit_deny=1, proto=17)
1621 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1622 acl_index = acl.add_vpp_config([rule, rule2])
1623 c1 = VppGbpContract(self, 220, 330, acl_index)
1624 c1.add_vpp_config()
1625
1626 for l in learnt:
1627 p = (Ether(src=ep.mac, dst=l['mac']) /
1628 IP(dst=l['ip'], src=ep.ip4.address) /
1629 UDP(sport=1234, dport=1234) /
1630 Raw('\xa5' * 100))
1631
1632 self.send_and_expect(self.pg0, [p], self.pg2)
1633
1634 #
1635 # send UU packets from the local EP
1636 #
1637 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1638 self.logger.info(self.vapi.cli("sh gbp bridge"))
1639 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1640 IP(dst="10.0.0.133", src=ep.ip4.address) /
1641 UDP(sport=1234, dport=1234) /
1642 Raw('\xa5' * 100))
1643 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_flood)
1644
1645 #
1646 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1647 #
1648 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1649 "239.1.1.1", 88,
1650 mcast_itf=self.pg4)
1651 tun_bm.add_vpp_config()
1652 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
1653 port_type=L2_PORT_TYPE.NORMAL)
1654 bp_bm.add_vpp_config()
1655
1656 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1657
1658 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1659 IP(dst="10.0.0.133", src=ep.ip4.address) /
1660 UDP(sport=1234, dport=1234) /
1661 Raw('\xa5' * 100))
1662 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1663
1664 #
1665 # Check v6 Endpoints
1666 #
1667 for l in learnt:
1668 # a packet with an sclass from a knwon EPG
1669 p = (Ether(src=self.pg2.remote_mac,
1670 dst=self.pg2.local_mac) /
1671 IP(src=self.pg2.remote_hosts[1].ip4,
1672 dst=self.pg2.local_ip4) /
1673 UDP(sport=1234, dport=48879) /
1674 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1675 Ether(src=l['mac'], dst=ep.mac) /
1676 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1677 UDP(sport=1234, dport=1234) /
1678 Raw('\xa5' * 100))
1679
1680 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1681
1682 self.assertTrue(find_gbp_endpoint(self,
1683 vx_tun_l2_1.sw_if_index,
1684 mac=l['mac']))
1685
1686 #
1687 # L3 Endpoint Learning
1688 # - configured on the bridge's BVI
1689 #
1690
1691 #
1692 # clean up
1693 #
1694 self.sleep(2)
1695 for l in learnt:
1696 self.assertFalse(find_gbp_endpoint(self,
1697 vx_tun_l2_1.sw_if_index,
1698 mac=l['mac']))
1699
1700 self.pg2.unconfig_ip4()
1701 self.pg3.unconfig_ip4()
1702 self.pg4.unconfig_ip4()
1703
1704 self.logger.info(self.vapi.cli("sh int"))
1705 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1706
Neale Rannsc29c0af2018-11-07 04:21:12 -08001707 def test_gbp_learn_vlan_l2(self):
1708 """ GBP L2 Endpoint w/ VLANs"""
1709
1710 learnt = [{'mac': '00:00:11:11:11:01',
1711 'ip': '10.0.0.1',
1712 'ip6': '2001:10::2'},
1713 {'mac': '00:00:11:11:11:02',
1714 'ip': '10.0.0.2',
1715 'ip6': '2001:10::3'}]
1716
1717 #
1718 # lower the inactive threshold so these tests pass in a
1719 # reasonable amount of time
1720 #
1721 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1722
1723 #
1724 # IP tables
1725 #
1726 gt4 = VppIpTable(self, 1)
1727 gt4.add_vpp_config()
1728 gt6 = VppIpTable(self, 1, is_ip6=True)
1729 gt6.add_vpp_config()
1730
1731 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1732 rd1.add_vpp_config()
1733
1734 #
1735 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1736 #
1737 self.pg2.config_ip4()
1738 self.pg2.resolve_arp()
1739 self.pg2.generate_remote_hosts(4)
1740 self.pg2.configure_ipv4_neighbors()
1741 self.pg3.config_ip4()
1742 self.pg3.resolve_arp()
1743
1744 #
1745 # The EP will be on a vlan sub-interface
1746 #
1747 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1748 vlan_11.admin_up()
1749 self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index,
1750 L2_VTR_OP.L2_POP_1,
1751 11)
1752
1753 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1754 self.pg3.remote_ip4, 116)
1755 bd_uu_fwd.add_vpp_config()
1756
1757 #
1758 # a GBP bridge domain with a BVI and a UU-flood interface
1759 # The BD is marked as do not learn, so no endpoints are ever
1760 # learnt in this BD.
1761 #
1762 bd1 = VppBridgeDomain(self, 1)
1763 bd1.add_vpp_config()
1764 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1765 learn=False)
1766 gbd1.add_vpp_config()
1767
1768 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1769 self.logger.info(self.vapi.cli("sh gbp bridge"))
1770
1771 # ... and has a /32 applied
1772 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1773 ip_addr.add_vpp_config()
1774
1775 #
1776 # The Endpoint-group in which we are learning endpoints
1777 #
1778 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1779 None, self.loop0,
1780 "10.0.0.128",
1781 "2001:10::128")
1782 epg_220.add_vpp_config()
1783
1784 #
1785 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1786 # leanring enabled
1787 #
1788 vx_tun_l2_1 = VppGbpVxlanTunnel(
1789 self, 99, bd1.bd_id,
1790 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1791 vx_tun_l2_1.add_vpp_config()
1792
1793 #
1794 # A static endpoint that the learnt endpoints are trying to
1795 # talk to
1796 #
1797 ep = VppGbpEndpoint(self, vlan_11,
1798 epg_220, None,
1799 "10.0.0.127", "11.0.0.127",
1800 "2001:10::1", "3001::1")
1801 ep.add_vpp_config()
1802
1803 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1804
1805 #
1806 # Send to the static EP
1807 #
1808 for ii, l in enumerate(learnt):
1809 # a packet with an sclass from a knwon EPG
1810 # arriving on an unknown TEP
1811 p = (Ether(src=self.pg2.remote_mac,
1812 dst=self.pg2.local_mac) /
1813 IP(src=self.pg2.remote_hosts[1].ip4,
1814 dst=self.pg2.local_ip4) /
1815 UDP(sport=1234, dport=48879) /
1816 VXLAN(vni=99, gpid=220, flags=0x88) /
1817 Ether(src=l['mac'], dst=ep.mac) /
1818 IP(src=l['ip'], dst=ep.ip4.address) /
1819 UDP(sport=1234, dport=1234) /
1820 Raw('\xa5' * 100))
1821
1822 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
1823
1824 #
1825 # packet to EP has the EP's vlan tag
1826 #
1827 for rx in rxs:
1828 self.assertEqual(rx[Dot1Q].vlan, 11)
1829
1830 #
1831 # the EP is not learnt since the BD setting prevents it
1832 # also no TEP too
1833 #
1834 self.assertFalse(find_gbp_endpoint(self,
1835 vx_tun_l2_1.sw_if_index,
1836 mac=l['mac']))
1837 self.assertEqual(INDEX_INVALID,
1838 find_vxlan_gbp_tunnel(
1839 self,
1840 self.pg2.local_ip4,
1841 self.pg2.remote_hosts[1].ip4,
1842 99))
1843
1844 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1845
1846 #
1847 # static to remotes
1848 # we didn't learn the remotes so they are sent to the UU-fwd
1849 #
1850 for l in learnt:
1851 p = (Ether(src=ep.mac, dst=l['mac']) /
1852 Dot1Q(vlan=11) /
1853 IP(dst=l['ip'], src=ep.ip4.address) /
1854 UDP(sport=1234, dport=1234) /
1855 Raw('\xa5' * 100))
1856
1857 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
1858
1859 for rx in rxs:
1860 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
1861 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
1862 self.assertEqual(rx[UDP].dport, 48879)
1863 # the UDP source port is a random value for hashing
1864 self.assertEqual(rx[VXLAN].gpid, 220)
1865 self.assertEqual(rx[VXLAN].vni, 116)
1866 self.assertTrue(rx[VXLAN].flags.G)
1867 self.assertTrue(rx[VXLAN].flags.Instance)
1868 self.assertFalse(rx[VXLAN].gpflags.A)
1869 self.assertFalse(rx[VXLAN].gpflags.D)
1870
1871 self.pg2.unconfig_ip4()
1872 self.pg3.unconfig_ip4()
1873
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001874 def test_gbp_learn_l3(self):
1875 """ GBP L3 Endpoint Learning """
1876
1877 routed_dst_mac = "00:0c:0c:0c:0c:0c"
1878 routed_src_mac = "00:22:bd:f8:19:ff"
1879
1880 learnt = [{'mac': '00:00:11:11:11:02',
1881 'ip': '10.0.1.2',
1882 'ip6': '2001:10::2'},
1883 {'mac': '00:00:11:11:11:03',
1884 'ip': '10.0.1.3',
1885 'ip6': '2001:10::3'}]
1886
1887 #
1888 # lower the inactive threshold so these tests pass in a
1889 # reasonable amount of time
1890 #
1891 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1892
1893 #
1894 # IP tables
1895 #
1896 t4 = VppIpTable(self, 1)
1897 t4.add_vpp_config()
1898 t6 = VppIpTable(self, 1, True)
1899 t6.add_vpp_config()
1900
1901 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1902 self.pg4.remote_ip4, 114)
1903 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1904 self.pg4.remote_ip4, 116)
1905 tun_ip4_uu.add_vpp_config()
1906 tun_ip6_uu.add_vpp_config()
1907
1908 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
1909 rd1.add_vpp_config()
1910
1911 self.loop0.set_mac(self.router_mac.address)
1912
1913 #
1914 # Bind the BVI to the RD
1915 #
1916 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
1917 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
1918
1919 #
1920 # Pg2 hosts the vxlan tunnel
1921 # hosts on pg2 to act as TEPs
1922 # pg3 is BD uu-fwd
1923 # pg4 is RD uu-fwd
1924 #
1925 self.pg2.config_ip4()
1926 self.pg2.resolve_arp()
1927 self.pg2.generate_remote_hosts(4)
1928 self.pg2.configure_ipv4_neighbors()
1929 self.pg3.config_ip4()
1930 self.pg3.resolve_arp()
1931 self.pg4.config_ip4()
1932 self.pg4.resolve_arp()
1933
1934 #
1935 # a GBP bridge domain with a BVI and a UU-flood interface
1936 #
1937 bd1 = VppBridgeDomain(self, 1)
1938 bd1.add_vpp_config()
1939 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
1940 gbd1.add_vpp_config()
1941
1942 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1943 self.logger.info(self.vapi.cli("sh gbp bridge"))
1944 self.logger.info(self.vapi.cli("sh gbp route"))
1945 self.logger.info(self.vapi.cli("show l2fib all"))
1946
1947 # ... and has a /32 and /128 applied
1948 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1949 ip4_addr.add_vpp_config()
1950 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
1951 ip6_addr.add_vpp_config()
1952
1953 #
1954 # The Endpoint-group in which we are learning endpoints
1955 #
1956 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1957 None, self.loop0,
1958 "10.0.0.128",
1959 "2001:10::128")
1960 epg_220.add_vpp_config()
1961
1962 #
1963 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1964 # leanring enabled
1965 #
1966 vx_tun_l3 = VppGbpVxlanTunnel(
1967 self, 101, rd1.rd_id,
1968 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
1969 vx_tun_l3.add_vpp_config()
1970
1971 #
1972 # A static endpoint that the learnt endpoints are trying to
1973 # talk to
1974 #
1975 ep = VppGbpEndpoint(self, self.pg0,
1976 epg_220, None,
1977 "10.0.0.127", "11.0.0.127",
1978 "2001:10::1", "3001::1")
1979 ep.add_vpp_config()
1980
1981 #
1982 # learn some remote IPv4 EPs
1983 #
1984 for ii, l in enumerate(learnt):
1985 # a packet with an sclass from a knwon EPG
1986 # arriving on an unknown TEP
1987 p = (Ether(src=self.pg2.remote_mac,
1988 dst=self.pg2.local_mac) /
1989 IP(src=self.pg2.remote_hosts[1].ip4,
1990 dst=self.pg2.local_ip4) /
1991 UDP(sport=1234, dport=48879) /
1992 VXLAN(vni=101, gpid=220, flags=0x88) /
1993 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
1994 IP(src=l['ip'], dst=ep.ip4.address) /
1995 UDP(sport=1234, dport=1234) /
1996 Raw('\xa5' * 100))
1997
1998 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1999
2000 # the new TEP
2001 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2002 self,
2003 self.pg2.local_ip4,
2004 self.pg2.remote_hosts[1].ip4,
2005 vx_tun_l3.vni)
2006 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2007
2008 # endpoint learnt via the parent GBP-vxlan interface
2009 self.assertTrue(find_gbp_endpoint(self,
2010 vx_tun_l3._sw_if_index,
2011 ip=l['ip']))
2012
2013 #
2014 # Static IPv4 EP replies to learnt
2015 #
2016 for l in learnt:
2017 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2018 IP(dst=l['ip'], src=ep.ip4.address) /
2019 UDP(sport=1234, dport=1234) /
2020 Raw('\xa5' * 100))
2021
2022 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2023
2024 for rx in rxs:
2025 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2026 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2027 self.assertEqual(rx[UDP].dport, 48879)
2028 # the UDP source port is a random value for hashing
2029 self.assertEqual(rx[VXLAN].gpid, 220)
2030 self.assertEqual(rx[VXLAN].vni, 101)
2031 self.assertTrue(rx[VXLAN].flags.G)
2032 self.assertTrue(rx[VXLAN].flags.Instance)
2033 self.assertTrue(rx[VXLAN].gpflags.A)
2034 self.assertFalse(rx[VXLAN].gpflags.D)
2035
2036 inner = rx[VXLAN].payload
2037
2038 self.assertEqual(inner[Ether].src, routed_src_mac)
2039 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2040 self.assertEqual(inner[IP].src, ep.ip4.address)
2041 self.assertEqual(inner[IP].dst, l['ip'])
2042
2043 self.sleep(2)
2044 for l in learnt:
2045 self.assertFalse(find_gbp_endpoint(self,
2046 tep1_sw_if_index,
2047 ip=l['ip']))
2048
2049 #
2050 # learn some remote IPv6 EPs
2051 #
2052 for ii, l in enumerate(learnt):
2053 # a packet with an sclass from a knwon EPG
2054 # arriving on an unknown TEP
2055 p = (Ether(src=self.pg2.remote_mac,
2056 dst=self.pg2.local_mac) /
2057 IP(src=self.pg2.remote_hosts[1].ip4,
2058 dst=self.pg2.local_ip4) /
2059 UDP(sport=1234, dport=48879) /
2060 VXLAN(vni=101, gpid=220, flags=0x88) /
2061 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2062 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2063 UDP(sport=1234, dport=1234) /
2064 Raw('\xa5' * 100))
2065
2066 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2067
2068 # the new TEP
2069 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2070 self,
2071 self.pg2.local_ip4,
2072 self.pg2.remote_hosts[1].ip4,
2073 vx_tun_l3.vni)
2074 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2075
2076 self.logger.info(self.vapi.cli("show gbp bridge"))
2077 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2078 self.logger.info(self.vapi.cli("show gbp vxlan"))
2079 self.logger.info(self.vapi.cli("show int addr"))
2080
2081 # endpoint learnt via the TEP
2082 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2083
2084 self.logger.info(self.vapi.cli("show gbp endpoint"))
2085 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2086
2087 #
2088 # Static EP replies to learnt
2089 #
2090 for l in learnt:
2091 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2092 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2093 UDP(sport=1234, dport=1234) /
2094 Raw('\xa5' * 100))
2095
2096 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2097
2098 for rx in rxs:
2099 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2100 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2101 self.assertEqual(rx[UDP].dport, 48879)
2102 # the UDP source port is a random value for hashing
2103 self.assertEqual(rx[VXLAN].gpid, 220)
2104 self.assertEqual(rx[VXLAN].vni, 101)
2105 self.assertTrue(rx[VXLAN].flags.G)
2106 self.assertTrue(rx[VXLAN].flags.Instance)
2107 self.assertTrue(rx[VXLAN].gpflags.A)
2108 self.assertFalse(rx[VXLAN].gpflags.D)
2109
2110 inner = rx[VXLAN].payload
2111
2112 self.assertEqual(inner[Ether].src, routed_src_mac)
2113 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2114 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2115 self.assertEqual(inner[IPv6].dst, l['ip6'])
2116
2117 self.logger.info(self.vapi.cli("sh gbp endpoint"))
2118 self.sleep(2)
2119 for l in learnt:
2120 self.assertFalse(find_gbp_endpoint(self,
2121 tep1_sw_if_index,
2122 ip=l['ip']))
2123
2124 #
2125 # Static sends to unknown EP with no route
2126 #
2127 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2128 IP(dst="10.0.0.99", src=ep.ip4.address) /
2129 UDP(sport=1234, dport=1234) /
2130 Raw('\xa5' * 100))
2131
2132 self.send_and_assert_no_replies(self.pg0, [p])
2133
2134 #
2135 # Add a route to static EP's v4 and v6 subnet
2136 # packets should be send on the v4/v6 uu=fwd interface resp.
2137 #
2138 se_10_24 = VppGbpSubnet(
2139 self, rd1, "10.0.0.0", 24,
2140 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2141 se_10_24.add_vpp_config()
2142
2143 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2144 IP(dst="10.0.0.99", src=ep.ip4.address) /
2145 UDP(sport=1234, dport=1234) /
2146 Raw('\xa5' * 100))
2147
2148 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2149 for rx in rxs:
2150 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2151 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2152 self.assertEqual(rx[UDP].dport, 48879)
2153 # the UDP source port is a random value for hashing
2154 self.assertEqual(rx[VXLAN].gpid, 220)
2155 self.assertEqual(rx[VXLAN].vni, 114)
2156 self.assertTrue(rx[VXLAN].flags.G)
2157 self.assertTrue(rx[VXLAN].flags.Instance)
2158 # policy is not applied to packets sent to the uu-fwd interfaces
2159 self.assertFalse(rx[VXLAN].gpflags.A)
2160 self.assertFalse(rx[VXLAN].gpflags.D)
2161
2162 #
2163 # learn some remote IPv4 EPs
2164 #
2165 for ii, l in enumerate(learnt):
2166 # a packet with an sclass from a knwon EPG
2167 # arriving on an unknown TEP
2168 p = (Ether(src=self.pg2.remote_mac,
2169 dst=self.pg2.local_mac) /
2170 IP(src=self.pg2.remote_hosts[1].ip4,
2171 dst=self.pg2.local_ip4) /
2172 UDP(sport=1234, dport=48879) /
2173 VXLAN(vni=101, gpid=220, flags=0x88) /
2174 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2175 IP(src=l['ip'], dst=ep.ip4.address) /
2176 UDP(sport=1234, dport=1234) /
2177 Raw('\xa5' * 100))
2178
2179 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2180
2181 # the new TEP
2182 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2183 self,
2184 self.pg2.local_ip4,
2185 self.pg2.remote_hosts[1].ip4,
2186 vx_tun_l3.vni)
2187 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2188
2189 # endpoint learnt via the parent GBP-vxlan interface
2190 self.assertTrue(find_gbp_endpoint(self,
2191 vx_tun_l3._sw_if_index,
2192 ip=l['ip']))
2193
2194 #
2195 # Add a remote endpoint from the API
2196 #
2197 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2198 epg_220, None,
2199 "10.0.0.88", "11.0.0.88",
2200 "2001:10::88", "3001::88",
2201 VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE,
2202 self.pg2.local_ip4,
2203 self.pg2.remote_hosts[1].ip4,
2204 mac=None)
2205 rep_88.add_vpp_config()
2206
2207 #
2208 # Add a remote endpoint from the API that matches an existing one
2209 #
2210 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2211 epg_220, None,
2212 learnt[0]['ip'], "11.0.0.101",
2213 learnt[0]['ip6'], "3001::101",
2214 VppEnum.vl_api_gbp_endpoint_flags_t.REMOTE,
2215 self.pg2.local_ip4,
2216 self.pg2.remote_hosts[1].ip4,
2217 mac=None)
2218 rep_2.add_vpp_config()
2219
2220 #
2221 # Add a route to the leanred EP's v4 subnet
2222 # packets should be send on the v4/v6 uu=fwd interface resp.
2223 #
2224 se_10_1_24 = VppGbpSubnet(
2225 self, rd1, "10.0.1.0", 24,
2226 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2227 se_10_1_24.add_vpp_config()
2228
2229 self.logger.info(self.vapi.cli("show gbp endpoint"))
2230
2231 ips = ["10.0.0.88", learnt[0]['ip']]
2232 for ip in ips:
2233 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2234 IP(dst=ip, src=ep.ip4.address) /
2235 UDP(sport=1234, dport=1234) /
2236 Raw('\xa5' * 100))
2237
2238 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2239
2240 for rx in rxs:
2241 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2242 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2243 self.assertEqual(rx[UDP].dport, 48879)
2244 # the UDP source port is a random value for hashing
2245 self.assertEqual(rx[VXLAN].gpid, 220)
2246 self.assertEqual(rx[VXLAN].vni, 101)
2247 self.assertTrue(rx[VXLAN].flags.G)
2248 self.assertTrue(rx[VXLAN].flags.Instance)
2249 self.assertTrue(rx[VXLAN].gpflags.A)
2250 self.assertFalse(rx[VXLAN].gpflags.D)
2251
2252 inner = rx[VXLAN].payload
2253
2254 self.assertEqual(inner[Ether].src, routed_src_mac)
2255 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2256 self.assertEqual(inner[IP].src, ep.ip4.address)
2257 self.assertEqual(inner[IP].dst, ip)
2258
2259 #
2260 # remove the API remote EPs, they are now UU-fwd
2261 #
2262 rep_88.remove_vpp_config()
2263 rep_2.remove_vpp_config()
2264
2265 self.logger.info(self.vapi.cli("show gbp endpoint"))
2266
2267 for ip in ips:
2268 self.assertFalse(find_gbp_endpoint(self, ip=ip))
2269
2270 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2271 IP(dst=ip, src=ep.ip4.address) /
2272 UDP(sport=1234, dport=1234) /
2273 Raw('\xa5' * 100))
2274
2275 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2276
2277 #
2278 # shutdown with learnt endpoint present
2279 #
2280 self.logger.info(self.vapi.cli("show gbp endpoint-group"))
2281
2282 #
2283 # TODO
2284 # remote endpoint becomes local
2285 #
2286 self.pg2.unconfig_ip4()
2287 self.pg3.unconfig_ip4()
2288 self.pg4.unconfig_ip4()
2289
Neale Rannsbc27d1b2018-02-05 01:13:38 -08002290
2291if __name__ == '__main__':
2292 unittest.main(testRunner=VppTestRunner)