blob: f49ba4c49e114bc61ca6bdf4ee207c6e88caa8d0 [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
Neale Rannsb6a47952018-11-21 05:44:35 -0800199class VppGbpExtItf(VppObject):
200 """
201 GBP ExtItfulation Interface
202 """
203
204 def __init__(self, test, itf, bd, rd):
205 self._test = test
206 self.itf = itf
207 self.bd = bd
208 self.rd = rd
209
210 def add_vpp_config(self):
211 self._test.vapi.gbp_ext_itf_add_del(
212 1,
213 self.itf.sw_if_index,
214 self.bd.bd_id,
215 self.rd.rd_id)
216 self._test.registry.register(self, self._test.logger)
217
218 def remove_vpp_config(self):
219 self._test.vapi.gbp_ext_itf_add_del(
220 0,
221 self.itf.sw_if_index,
222 self.bd.bd_id,
223 self.rd.rd_id)
224
225 def __str__(self):
226 return self.object_id()
227
228 def object_id(self):
229 return "gbp-ext-itf:[%d]" % (self.itf.sw_if_index)
230
231 def query_vpp_config(self):
232 rs = self._test.vapi.gbp_ext_itf_dump()
233 for r in rs:
234 if r.ext_itf.sw_if_index == self.itf.sw_if_index:
235 return True
236 return False
237
238
Neale Ranns25b04942018-04-04 09:34:50 -0700239class VppGbpSubnet(VppObject):
240 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200241 GBP Subnet
Neale Ranns25b04942018-04-04 09:34:50 -0700242 """
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700243 def __init__(self, test, rd, address, address_len,
244 type, sw_if_index=None, epg=None):
Neale Ranns25b04942018-04-04 09:34:50 -0700245 self._test = test
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700246 self.rd_id = rd.rd_id
Ole Troana26373b2018-10-22 14:11:45 +0200247 self.prefix = VppIpPrefix(address, address_len)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700248 self.type = type
Neale Ranns25b04942018-04-04 09:34:50 -0700249 self.sw_if_index = sw_if_index
250 self.epg = epg
251
252 def add_vpp_config(self):
253 self._test.vapi.gbp_subnet_add_del(
254 1,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700255 self.rd_id,
Ole Troana26373b2018-10-22 14:11:45 +0200256 self.prefix.encode(),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700257 self.type,
Neale Ranns25b04942018-04-04 09:34:50 -0700258 sw_if_index=self.sw_if_index if self.sw_if_index else 0xffffffff,
Neale Rannsc0a93142018-09-05 15:42:26 -0700259 epg_id=self.epg if self.epg else 0xffff)
Neale Ranns25b04942018-04-04 09:34:50 -0700260 self._test.registry.register(self, self._test.logger)
261
262 def remove_vpp_config(self):
263 self._test.vapi.gbp_subnet_add_del(
264 0,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700265 self.rd_id,
266 self.prefix.encode(),
267 self.type)
Neale Ranns25b04942018-04-04 09:34:50 -0700268
269 def __str__(self):
270 return self.object_id()
271
272 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700273 return "gbp-subnet:[%d-%s]" % (self.rd_id, self.prefix)
Neale Ranns25b04942018-04-04 09:34:50 -0700274
275 def query_vpp_config(self):
276 ss = self._test.vapi.gbp_subnet_dump()
277 for s in ss:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700278 if s.subnet.rd_id == self.rd_id and \
279 s.subnet.type == self.type and \
Ole Troana26373b2018-10-22 14:11:45 +0200280 s.subnet.prefix == self.prefix:
Neale Rannsc0a93142018-09-05 15:42:26 -0700281 return True
Neale Ranns25b04942018-04-04 09:34:50 -0700282 return False
283
284
285class VppGbpEndpointGroup(VppObject):
286 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200287 GBP Endpoint Group
Neale Ranns25b04942018-04-04 09:34:50 -0700288 """
289
290 def __init__(self, test, epg, rd, bd, uplink,
291 bvi, bvi_ip4, bvi_ip6=None):
292 self._test = test
293 self.uplink = uplink
294 self.bvi = bvi
Neale Ranns4d5b9172018-10-24 02:57:49 -0700295 self.bvi_ip4 = VppIpAddress(bvi_ip4)
296 self.bvi_ip6 = VppIpAddress(bvi_ip6)
Neale Ranns25b04942018-04-04 09:34:50 -0700297 self.epg = epg
298 self.bd = bd
299 self.rd = rd
300
301 def add_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700302 self._test.vapi.gbp_endpoint_group_add(
Neale Ranns25b04942018-04-04 09:34:50 -0700303 self.epg,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700304 self.bd.bd.bd_id,
305 self.rd.rd_id,
306 self.uplink.sw_if_index if self.uplink else INDEX_INVALID)
Neale Ranns25b04942018-04-04 09:34:50 -0700307 self._test.registry.register(self, self._test.logger)
308
309 def remove_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700310 self._test.vapi.gbp_endpoint_group_del(
311 self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700312
313 def __str__(self):
314 return self.object_id()
315
316 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700317 return "gbp-endpoint-group:[%d]" % (self.epg)
Neale Ranns25b04942018-04-04 09:34:50 -0700318
319 def query_vpp_config(self):
320 epgs = self._test.vapi.gbp_endpoint_group_dump()
321 for epg in epgs:
322 if epg.epg.epg_id == self.epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800323 return True
324 return False
325
326
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700327class VppGbpBridgeDomain(VppObject):
328 """
329 GBP Bridge Domain
330 """
331
Neale Rannsc29c0af2018-11-07 04:21:12 -0800332 def __init__(self, test, bd, bvi, uu_flood=None, learn=True):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700333 self._test = test
334 self.bvi = bvi
335 self.uu_flood = uu_flood
336 self.bd = bd
337
Neale Rannsc29c0af2018-11-07 04:21:12 -0800338 e = VppEnum.vl_api_gbp_bridge_domain_flags_t
339 if (learn):
340 self.learn = e.GBP_BD_API_FLAG_NONE
341 else:
342 self.learn = e.GBP_BD_API_FLAG_DO_NOT_LEARN
343
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700344 def add_vpp_config(self):
345 self._test.vapi.gbp_bridge_domain_add(
346 self.bd.bd_id,
Neale Rannsc29c0af2018-11-07 04:21:12 -0800347 self.learn,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700348 self.bvi.sw_if_index,
349 self.uu_flood.sw_if_index if self.uu_flood else INDEX_INVALID)
350 self._test.registry.register(self, self._test.logger)
351
352 def remove_vpp_config(self):
353 self._test.vapi.gbp_bridge_domain_del(self.bd.bd_id)
354
355 def __str__(self):
356 return self.object_id()
357
358 def object_id(self):
359 return "gbp-bridge-domain:[%d]" % (self.bd.bd_id)
360
361 def query_vpp_config(self):
362 bds = self._test.vapi.gbp_bridge_domain_dump()
363 for bd in bds:
364 if bd.bd.bd_id == self.bd.bd_id:
365 return True
366 return False
367
368
369class VppGbpRouteDomain(VppObject):
370 """
371 GBP Route Domain
372 """
373
374 def __init__(self, test, rd_id, t4, t6, ip4_uu=None, ip6_uu=None):
375 self._test = test
376 self.rd_id = rd_id
377 self.t4 = t4
378 self.t6 = t6
379 self.ip4_uu = ip4_uu
380 self.ip6_uu = ip6_uu
381
382 def add_vpp_config(self):
383 self._test.vapi.gbp_route_domain_add(
384 self.rd_id,
385 self.t4.table_id,
386 self.t6.table_id,
387 self.ip4_uu.sw_if_index if self.ip4_uu else INDEX_INVALID,
388 self.ip6_uu.sw_if_index if self.ip6_uu else INDEX_INVALID)
389 self._test.registry.register(self, self._test.logger)
390
391 def remove_vpp_config(self):
392 self._test.vapi.gbp_route_domain_del(self.rd_id)
393
394 def __str__(self):
395 return self.object_id()
396
397 def object_id(self):
398 return "gbp-route-domain:[%d]" % (self.rd_id)
399
400 def query_vpp_config(self):
401 rds = self._test.vapi.gbp_route_domain_dump()
402 for rd in rds:
403 if rd.rd.rd_id == self.rd_id:
404 return True
405 return False
406
407
Neale Ranns13a08cc2018-11-07 09:25:54 -0800408class VppGbpContractNextHop():
409 def __init__(self, mac, bd, ip, rd):
410 self.mac = mac
411 self.ip = ip
412 self.bd = bd
413 self.rd = rd
414
415 def encode(self):
416 return {'ip': self.ip.encode(),
417 'mac': self.mac.encode(),
418 'bd_id': self.bd.bd.bd_id,
419 'rd_id': self.rd.rd_id}
420
421
422class VppGbpContractRule():
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100423 def __init__(self, action, hash_mode, nhs=[]):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800424 self.action = action
Mohsin Kazmid40c3e62018-11-21 10:46:57 +0100425 self.hash_mode = hash_mode
Neale Ranns13a08cc2018-11-07 09:25:54 -0800426 self.nhs = nhs
Neale Ranns13a08cc2018-11-07 09:25:54 -0800427
428 def encode(self):
429 nhs = []
430 for nh in self.nhs:
431 nhs.append(nh.encode())
432 while len(nhs) < 8:
433 nhs.append({})
434 return {'action': self.action,
435 'nh_set': {
436 'hash_mode': self.hash_mode,
437 'n_nhs': len(self.nhs),
438 'nhs': nhs}}
439
440
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800441class VppGbpContract(VppObject):
442 """
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200443 GBP Contract
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800444 """
445
Neale Ranns13a08cc2018-11-07 09:25:54 -0800446 def __init__(self, test, src_epg, dst_epg, acl_index, rules=[]):
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800447 self._test = test
448 self.acl_index = acl_index
449 self.src_epg = src_epg
450 self.dst_epg = dst_epg
Neale Ranns13a08cc2018-11-07 09:25:54 -0800451 self.rules = rules
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800452
453 def add_vpp_config(self):
Neale Ranns13a08cc2018-11-07 09:25:54 -0800454 rules = []
455 for r in self.rules:
456 rules.append(r.encode())
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800457 self._test.vapi.gbp_contract_add_del(
458 1,
459 self.src_epg,
460 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800461 self.acl_index,
462 rules)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800463 self._test.registry.register(self, self._test.logger)
464
465 def remove_vpp_config(self):
466 self._test.vapi.gbp_contract_add_del(
467 0,
468 self.src_epg,
469 self.dst_epg,
Neale Ranns13a08cc2018-11-07 09:25:54 -0800470 self.acl_index,
471 [])
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800472
473 def __str__(self):
474 return self.object_id()
475
476 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700477 return "gbp-contract:[%d:%s:%d]" % (self.src_epg,
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800478 self.dst_epg,
479 self.acl_index)
480
481 def query_vpp_config(self):
Neale Ranns25b04942018-04-04 09:34:50 -0700482 cs = self._test.vapi.gbp_contract_dump()
483 for c in cs:
484 if c.contract.src_epg == self.src_epg \
485 and c.contract.dst_epg == self.dst_epg:
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800486 return True
487 return False
488
489
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700490class VppGbpVxlanTunnel(VppInterface):
491 """
492 GBP VXLAN tunnel
493 """
494
495 def __init__(self, test, vni, bd_rd_id, mode):
496 super(VppGbpVxlanTunnel, self).__init__(test)
497 self._test = test
498 self.vni = vni
499 self.bd_rd_id = bd_rd_id
500 self.mode = mode
501
502 def add_vpp_config(self):
503 r = self._test.vapi.gbp_vxlan_tunnel_add(
504 self.vni,
505 self.bd_rd_id,
506 self.mode)
507 self.set_sw_if_index(r.sw_if_index)
508 self._test.registry.register(self, self._test.logger)
509
510 def remove_vpp_config(self):
511 self._test.vapi.gbp_vxlan_tunnel_del(self.vni)
512
513 def __str__(self):
514 return self.object_id()
515
516 def object_id(self):
517 return "gbp-vxlan:%d" % (self.vni)
518
519 def query_vpp_config(self):
520 return find_gbp_vxlan(self._test, self.vni)
521
522
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200523class VppGbpAcl(VppObject):
524 """
525 GBP Acl
526 """
527
528 def __init__(self, test):
529 self._test = test
530 self.acl_index = 4294967295
531
532 def create_rule(self, is_ipv6=0, permit_deny=0, proto=-1,
533 s_prefix=0, s_ip='\x00\x00\x00\x00', sport_from=0,
534 sport_to=65535, d_prefix=0, d_ip='\x00\x00\x00\x00',
535 dport_from=0, dport_to=65535):
536 if proto == -1 or proto == 0:
537 sport_to = 0
538 dport_to = sport_to
539 elif proto == 1 or proto == 58:
540 sport_to = 255
541 dport_to = sport_to
542 rule = ({'is_permit': permit_deny, 'is_ipv6': is_ipv6, 'proto': proto,
543 'srcport_or_icmptype_first': sport_from,
544 'srcport_or_icmptype_last': sport_to,
545 'src_ip_prefix_len': s_prefix,
546 'src_ip_addr': s_ip,
547 'dstport_or_icmpcode_first': dport_from,
548 'dstport_or_icmpcode_last': dport_to,
549 'dst_ip_prefix_len': d_prefix,
550 'dst_ip_addr': d_ip})
551 return rule
552
553 def add_vpp_config(self, rules):
554
555 reply = self._test.vapi.acl_add_replace(self.acl_index,
556 r=rules,
557 tag='GBPTest')
558 self.acl_index = reply.acl_index
559 return self.acl_index
560
561 def remove_vpp_config(self):
562 self._test.vapi.acl_del(self.acl_index)
563
564 def __str__(self):
565 return self.object_id()
566
567 def object_id(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700568 return "gbp-acl:[%d]" % (self.acl_index)
Mohsin Kazmi22b3b842018-04-17 19:35:42 +0200569
570 def query_vpp_config(self):
571 cs = self._test.vapi.acl_dump()
572 for c in cs:
573 if c.acl_index == self.acl_index:
574 return True
575 return False
576
577
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800578class TestGBP(VppTestCase):
579 """ GBP Test Case """
580
581 def setUp(self):
582 super(TestGBP, self).setUp()
583
Neale Ranns25b04942018-04-04 09:34:50 -0700584 self.create_pg_interfaces(range(9))
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700585 self.create_loopback_interfaces(8)
Neale Ranns25b04942018-04-04 09:34:50 -0700586
Neale Ranns4d5b9172018-10-24 02:57:49 -0700587 self.router_mac = VppMacAddress("00:11:22:33:44:55")
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800588
589 for i in self.pg_interfaces:
590 i.admin_up()
Neale Ranns25b04942018-04-04 09:34:50 -0700591 for i in self.lo_interfaces:
592 i.admin_up()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800593
594 def tearDown(self):
595 for i in self.pg_interfaces:
Neale Ranns25b04942018-04-04 09:34:50 -0700596 i.admin_down()
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800597
598 super(TestGBP, self).tearDown()
599
Neale Ranns25b04942018-04-04 09:34:50 -0700600 def send_and_expect_bridged(self, src, tx, dst):
601 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800602
Neale Ranns25b04942018-04-04 09:34:50 -0700603 for r in rx:
604 self.assertEqual(r[Ether].src, tx[0][Ether].src)
605 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
606 self.assertEqual(r[IP].src, tx[0][IP].src)
607 self.assertEqual(r[IP].dst, tx[0][IP].dst)
608 return rx
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800609
Neale Ranns25b04942018-04-04 09:34:50 -0700610 def send_and_expect_bridged6(self, src, tx, dst):
611 rx = self.send_and_expect(src, tx, dst)
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800612
Neale Ranns25b04942018-04-04 09:34:50 -0700613 for r in rx:
614 self.assertEqual(r[Ether].src, tx[0][Ether].src)
615 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
616 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
617 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
618 return rx
619
620 def send_and_expect_routed(self, src, tx, dst, src_mac):
621 rx = self.send_and_expect(src, tx, dst)
622
623 for r in rx:
624 self.assertEqual(r[Ether].src, src_mac)
625 self.assertEqual(r[Ether].dst, dst.remote_mac)
626 self.assertEqual(r[IP].src, tx[0][IP].src)
627 self.assertEqual(r[IP].dst, tx[0][IP].dst)
628 return rx
629
630 def send_and_expect_natted(self, src, tx, dst, src_ip):
631 rx = self.send_and_expect(src, tx, dst)
632
633 for r in rx:
634 self.assertEqual(r[Ether].src, tx[0][Ether].src)
635 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
636 self.assertEqual(r[IP].src, src_ip)
637 self.assertEqual(r[IP].dst, tx[0][IP].dst)
638 return rx
639
Neale Ranns4a6d0232018-04-24 07:45:33 -0700640 def send_and_expect_natted6(self, src, tx, dst, src_ip):
641 rx = self.send_and_expect(src, tx, dst)
642
643 for r in rx:
644 self.assertEqual(r[Ether].src, tx[0][Ether].src)
645 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
646 self.assertEqual(r[IPv6].src, src_ip)
647 self.assertEqual(r[IPv6].dst, tx[0][IPv6].dst)
648 return rx
649
Neale Ranns25b04942018-04-04 09:34:50 -0700650 def send_and_expect_unnatted(self, src, tx, dst, dst_ip):
651 rx = self.send_and_expect(src, tx, dst)
652
653 for r in rx:
654 self.assertEqual(r[Ether].src, tx[0][Ether].src)
655 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
656 self.assertEqual(r[IP].dst, dst_ip)
657 self.assertEqual(r[IP].src, tx[0][IP].src)
658 return rx
659
Neale Ranns4a6d0232018-04-24 07:45:33 -0700660 def send_and_expect_unnatted6(self, src, tx, dst, dst_ip):
661 rx = self.send_and_expect(src, tx, dst)
662
663 for r in rx:
664 self.assertEqual(r[Ether].src, tx[0][Ether].src)
665 self.assertEqual(r[Ether].dst, tx[0][Ether].dst)
666 self.assertEqual(r[IPv6].dst, dst_ip)
667 self.assertEqual(r[IPv6].src, tx[0][IPv6].src)
668 return rx
669
Neale Ranns25b04942018-04-04 09:34:50 -0700670 def send_and_expect_double_natted(self, src, tx, dst, src_ip, dst_ip):
671 rx = self.send_and_expect(src, tx, dst)
672
673 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700674 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700675 self.assertEqual(r[Ether].dst, dst.remote_mac)
676 self.assertEqual(r[IP].dst, dst_ip)
677 self.assertEqual(r[IP].src, src_ip)
678 return rx
679
Neale Ranns4a6d0232018-04-24 07:45:33 -0700680 def send_and_expect_double_natted6(self, src, tx, dst, src_ip, dst_ip):
681 rx = self.send_and_expect(src, tx, dst)
682
683 for r in rx:
Neale Ranns4d5b9172018-10-24 02:57:49 -0700684 self.assertEqual(r[Ether].src, self.router_mac.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700685 self.assertEqual(r[Ether].dst, dst.remote_mac)
686 self.assertEqual(r[IPv6].dst, dst_ip)
687 self.assertEqual(r[IPv6].src, src_ip)
688 return rx
689
Neale Ranns25b04942018-04-04 09:34:50 -0700690 def test_gbp(self):
691 """ Group Based Policy """
692
Neale Rannsb6a47952018-11-21 05:44:35 -0800693 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
694
Neale Rannsbc27d1b2018-02-05 01:13:38 -0800695 #
Neale Ranns25b04942018-04-04 09:34:50 -0700696 # Bridge Domains
697 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700698 bd1 = VppBridgeDomain(self, 1)
699 bd2 = VppBridgeDomain(self, 2)
700 bd20 = VppBridgeDomain(self, 20)
701
702 bd1.add_vpp_config()
703 bd2.add_vpp_config()
704 bd20.add_vpp_config()
705
706 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
707 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
708 gbd20 = VppGbpBridgeDomain(self, bd20, self.loop2)
709
710 gbd1.add_vpp_config()
711 gbd2.add_vpp_config()
712 gbd20.add_vpp_config()
713
714 #
715 # Route Domains
716 #
717 gt4 = VppIpTable(self, 0)
718 gt4.add_vpp_config()
719 gt6 = VppIpTable(self, 0, is_ip6=True)
720 gt6.add_vpp_config()
721 nt4 = VppIpTable(self, 20)
722 nt4.add_vpp_config()
723 nt6 = VppIpTable(self, 20, is_ip6=True)
724 nt6.add_vpp_config()
725
726 rd0 = VppGbpRouteDomain(self, 0, gt4, gt6, None, None)
727 rd20 = VppGbpRouteDomain(self, 20, nt4, nt6, None, None)
728
729 rd0.add_vpp_config()
730 rd20.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700731
732 #
733 # 3 EPGs, 2 of which share a BD.
Neale Ranns25b04942018-04-04 09:34:50 -0700734 # 2 NAT EPGs, one for floating-IP subnets, the other for internet
735 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700736 epgs = [VppGbpEndpointGroup(self, 220, rd0, gbd1, self.pg4,
Neale Rannsc0a93142018-09-05 15:42:26 -0700737 self.loop0,
738 "10.0.0.128",
739 "2001:10::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700740 VppGbpEndpointGroup(self, 221, rd0, gbd1, self.pg5,
Neale Rannsc0a93142018-09-05 15:42:26 -0700741 self.loop0,
742 "10.0.1.128",
743 "2001:10:1::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700744 VppGbpEndpointGroup(self, 222, rd0, gbd2, self.pg6,
Neale Rannsc0a93142018-09-05 15:42:26 -0700745 self.loop1,
746 "10.0.2.128",
747 "2001:10:2::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700748 VppGbpEndpointGroup(self, 333, rd20, gbd20, self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -0700749 self.loop2,
750 "11.0.0.128",
751 "3001::128"),
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700752 VppGbpEndpointGroup(self, 444, rd20, gbd20, self.pg8,
Neale Rannsc0a93142018-09-05 15:42:26 -0700753 self.loop2,
754 "11.0.0.129",
755 "3001::129")]
756 recircs = [VppGbpRecirc(self, epgs[0],
757 self.loop3),
758 VppGbpRecirc(self, epgs[1],
759 self.loop4),
760 VppGbpRecirc(self, epgs[2],
761 self.loop5),
762 VppGbpRecirc(self, epgs[3],
763 self.loop6, is_ext=True),
764 VppGbpRecirc(self, epgs[4],
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700765 self.loop7, is_ext=True)]
Neale Ranns25b04942018-04-04 09:34:50 -0700766
767 epg_nat = epgs[3]
768 recirc_nat = recircs[3]
769
770 #
771 # 4 end-points, 2 in the same subnet, 3 in the same BD
772 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700773 eps = [VppGbpEndpoint(self, self.pg0,
774 epgs[0], recircs[0],
775 "10.0.0.1", "11.0.0.1",
776 "2001:10::1", "3001::1"),
777 VppGbpEndpoint(self, self.pg1,
778 epgs[0], recircs[0],
779 "10.0.0.2", "11.0.0.2",
780 "2001:10::2", "3001::2"),
781 VppGbpEndpoint(self, self.pg2,
782 epgs[1], recircs[1],
783 "10.0.1.1", "11.0.0.3",
784 "2001:10:1::1", "3001::3"),
785 VppGbpEndpoint(self, self.pg3,
786 epgs[2], recircs[2],
787 "10.0.2.1", "11.0.0.4",
788 "2001:10:2::1", "3001::4")]
Neale Ranns25b04942018-04-04 09:34:50 -0700789
790 #
791 # Config related to each of the EPGs
792 #
793 for epg in epgs:
794 # IP config on the BVI interfaces
795 if epg != epgs[1] and epg != epgs[4]:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700796 VppIpInterfaceBind(self, epg.bvi, epg.rd.t4).add_vpp_config()
797 VppIpInterfaceBind(self, epg.bvi, epg.rd.t6).add_vpp_config()
798 self.vapi.sw_interface_set_mac_address(
799 epg.bvi.sw_if_index,
800 self.router_mac.bytes)
Neale Ranns25b04942018-04-04 09:34:50 -0700801
802 # The BVIs are NAT inside interfaces
803 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
804 is_inside=1,
805 is_add=1)
Neale Ranns4a6d0232018-04-24 07:45:33 -0700806 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
807 is_inside=1,
808 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700809
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700810 if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32)
811 if_ip6 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip6, 128)
812 if_ip4.add_vpp_config()
813 if_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700814
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700815 # EPG uplink interfaces in the RD
816 VppIpInterfaceBind(self, epg.uplink, epg.rd.t4).add_vpp_config()
817 VppIpInterfaceBind(self, epg.uplink, epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700818
819 # add the BD ARP termination entry for BVI IP
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700820 epg.bd_arp_ip4 = VppBridgeDomainArpEntry(self, epg.bd.bd,
821 self.router_mac.address,
822 epg.bvi_ip4)
823 epg.bd_arp_ip6 = VppBridgeDomainArpEntry(self, epg.bd.bd,
824 self.router_mac.address,
825 epg.bvi_ip6)
826 epg.bd_arp_ip4.add_vpp_config()
827 epg.bd_arp_ip6.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700828
829 # EPG in VPP
830 epg.add_vpp_config()
831
832 for recirc in recircs:
833 # EPG's ingress recirculation interface maps to its RD
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700834 VppIpInterfaceBind(self, recirc.recirc,
835 recirc.epg.rd.t4).add_vpp_config()
836 VppIpInterfaceBind(self, recirc.recirc,
837 recirc.epg.rd.t6).add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700838
Neale Ranns4a6d0232018-04-24 07:45:33 -0700839 self.vapi.nat44_interface_add_del_feature(
840 recirc.recirc.sw_if_index,
841 is_inside=0,
842 is_add=1)
843 self.vapi.nat66_add_del_interface(
844 recirc.recirc.sw_if_index,
845 is_inside=0,
846 is_add=1)
Neale Ranns25b04942018-04-04 09:34:50 -0700847
848 recirc.add_vpp_config()
849
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700850 for recirc in recircs:
851 self.assertTrue(find_bridge_domain_port(self,
852 recirc.epg.bd.bd.bd_id,
853 recirc.recirc.sw_if_index))
854
Neale Ranns25b04942018-04-04 09:34:50 -0700855 for ep in eps:
856 self.pg_enable_capture(self.pg_interfaces)
857 self.pg_start()
858 #
859 # routes to the endpoints. We need these since there are no
860 # adj-fibs due to the fact the the BVI address has /32 and
861 # the subnet is not attached.
862 #
Neale Rannsc0a93142018-09-05 15:42:26 -0700863 for (ip, fip) in zip(ep.ips, ep.fips):
Neale Rannsc0a93142018-09-05 15:42:26 -0700864 # Add static mappings for each EP from the 10/8 to 11/8 network
865 if ip.af == AF_INET:
866 self.vapi.nat44_add_del_static_mapping(ip.bytes,
867 fip.bytes,
868 vrf_id=0,
869 addr_only=1)
870 else:
871 self.vapi.nat66_add_del_static_mapping(ip.bytes,
872 fip.bytes,
873 vrf_id=0)
Neale Ranns25b04942018-04-04 09:34:50 -0700874
Neale Ranns25b04942018-04-04 09:34:50 -0700875 # VPP EP create ...
876 ep.add_vpp_config()
877
Neale Rannsc0a93142018-09-05 15:42:26 -0700878 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns25b04942018-04-04 09:34:50 -0700879
Neale Rannsc0a93142018-09-05 15:42:26 -0700880 # ... results in a Gratuitous ARP/ND on the EPG's uplink
881 rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
882
883 for ii, ip in enumerate(ep.ips):
884 p = rx[ii]
885
886 if ip.is_ip6:
887 self.assertTrue(p.haslayer(ICMPv6ND_NA))
888 self.assertEqual(p[ICMPv6ND_NA].tgt, ip.address)
889 else:
890 self.assertTrue(p.haslayer(ARP))
891 self.assertEqual(p[ARP].psrc, ip.address)
892 self.assertEqual(p[ARP].pdst, ip.address)
Neale Ranns25b04942018-04-04 09:34:50 -0700893
894 # add the BD ARP termination entry for floating IP
Neale Rannsc0a93142018-09-05 15:42:26 -0700895 for fip in ep.fips:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700896 ba = VppBridgeDomainArpEntry(self, epg_nat.bd.bd, ep.mac, fip)
897 ba.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700898
Neale Rannsc0a93142018-09-05 15:42:26 -0700899 # floating IPs route via EPG recirc
900 r = VppIpRoute(self, fip.address, fip.length,
901 [VppRoutePath(fip.address,
902 ep.recirc.recirc.sw_if_index,
903 is_dvr=1,
904 proto=fip.dpo_proto)],
905 table_id=20,
906 is_ip6=fip.is_ip6)
907 r.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700908
909 # L2 FIB entries in the NAT EPG BD to bridge the packets from
910 # the outside direct to the internal EPG
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700911 lf = VppL2FibEntry(self, epg_nat.bd.bd, ep.mac,
912 ep.recirc.recirc, bvi_mac=0)
913 lf.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -0700914
915 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700916 # ARP packets for unknown IP are sent to the EPG uplink
Neale Ranns25b04942018-04-04 09:34:50 -0700917 #
918 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
919 src=self.pg0.remote_mac) /
920 ARP(op="who-has",
921 hwdst="ff:ff:ff:ff:ff:ff",
922 hwsrc=self.pg0.remote_mac,
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700923 pdst="10.0.0.88",
924 psrc="10.0.0.99"))
Neale Ranns25b04942018-04-04 09:34:50 -0700925
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700926 self.vapi.cli("clear trace")
927 self.pg0.add_stream(pkt_arp)
928
929 self.pg_enable_capture(self.pg_interfaces)
930 self.pg_start()
931
932 rxd = epgs[0].uplink.get_capture(1)
Neale Ranns25b04942018-04-04 09:34:50 -0700933
934 #
935 # ARP/ND packets get a response
936 #
937 pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff",
938 src=self.pg0.remote_mac) /
939 ARP(op="who-has",
940 hwdst="ff:ff:ff:ff:ff:ff",
941 hwsrc=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700942 pdst=epgs[0].bvi_ip4.address,
Neale Rannsc0a93142018-09-05 15:42:26 -0700943 psrc=eps[0].ip4.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700944
945 self.send_and_expect(self.pg0, [pkt_arp], self.pg0)
946
Neale Rannsc0a93142018-09-05 15:42:26 -0700947 nsma = in6_getnsma(inet_pton(AF_INET6, eps[0].ip6.address))
Neale Ranns25b04942018-04-04 09:34:50 -0700948 d = inet_ntop(AF_INET6, nsma)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700949 pkt_nd = (Ether(dst=in6_getnsmac(nsma),
950 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700951 IPv6(dst=d, src=eps[0].ip6.address) /
Neale Ranns4d5b9172018-10-24 02:57:49 -0700952 ICMPv6ND_NS(tgt=epgs[0].bvi_ip6.address) /
Neale Ranns25b04942018-04-04 09:34:50 -0700953 ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
954 self.send_and_expect(self.pg0, [pkt_nd], self.pg0)
955
956 #
957 # broadcast packets are flooded
958 #
959 pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff",
960 src=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700961 IP(src=eps[0].ip4.address, dst="232.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -0700962 UDP(sport=1234, dport=1234) /
963 Raw('\xa5' * 100))
964
965 self.vapi.cli("clear trace")
966 self.pg0.add_stream(pkt_bcast)
967
968 self.pg_enable_capture(self.pg_interfaces)
969 self.pg_start()
970
971 rxd = eps[1].itf.get_capture(1)
972 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
973 rxd = epgs[0].uplink.get_capture(1)
974 self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
975
976 #
977 # packets to non-local L3 destinations dropped
978 #
979 pkt_intra_epg_220_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700980 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700981 IP(src=eps[0].ip4.address,
982 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700983 UDP(sport=1234, dport=1234) /
984 Raw('\xa5' * 100))
985 pkt_inter_epg_222_ip4 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700986 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700987 IP(src=eps[0].ip4.address,
988 dst="10.0.1.99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700989 UDP(sport=1234, dport=1234) /
990 Raw('\xa5' * 100))
991
992 self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)
993
994 pkt_inter_epg_222_ip6 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -0700995 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -0700996 IPv6(src=eps[0].ip6.address,
997 dst="2001:10::99") /
Neale Ranns25b04942018-04-04 09:34:50 -0700998 UDP(sport=1234, dport=1234) /
999 Raw('\xa5' * 100))
1000 self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)
1001
1002 #
1003 # Add the subnet routes
1004 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001005 s41 = VppGbpSubnet(
1006 self, rd0, "10.0.0.0", 24,
1007 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1008 s42 = VppGbpSubnet(
1009 self, rd0, "10.0.1.0", 24,
1010 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1011 s43 = VppGbpSubnet(
1012 self, rd0, "10.0.2.0", 24,
1013 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1014 s61 = VppGbpSubnet(
1015 self, rd0, "2001:10::1", 64,
1016 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1017 s62 = VppGbpSubnet(
1018 self, rd0, "2001:10:1::1", 64,
1019 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
1020 s63 = VppGbpSubnet(
1021 self, rd0, "2001:10:2::1", 64,
1022 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_INTERNAL)
Neale Ranns25b04942018-04-04 09:34:50 -07001023 s41.add_vpp_config()
1024 s42.add_vpp_config()
1025 s43.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001026 s61.add_vpp_config()
1027 s62.add_vpp_config()
1028 s63.add_vpp_config()
1029
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001030 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001031 pkt_intra_epg_220_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001032 eps[0].epg.uplink)
1033 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001034 pkt_inter_epg_222_ip4 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001035 eps[0].epg.uplink)
1036 self.send_and_expect_bridged6(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001037 pkt_inter_epg_222_ip6 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001038 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001039
1040 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
1041 self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
1042 self.logger.info(self.vapi.cli("sh gbp endpoint"))
1043 self.logger.info(self.vapi.cli("sh gbp recirc"))
1044 self.logger.info(self.vapi.cli("sh int"))
1045 self.logger.info(self.vapi.cli("sh int addr"))
1046 self.logger.info(self.vapi.cli("sh int feat loop6"))
1047 self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
1048 self.logger.info(self.vapi.cli("sh int feat loop3"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001049 self.logger.info(self.vapi.cli("sh int feat pg0"))
Neale Ranns25b04942018-04-04 09:34:50 -07001050
1051 #
1052 # Packet destined to unknown unicast is sent on the epg uplink ...
1053 #
1054 pkt_intra_epg_220_to_uplink = (Ether(src=self.pg0.remote_mac,
1055 dst="00:00:00:33:44:55") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001056 IP(src=eps[0].ip4.address,
1057 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001058 UDP(sport=1234, dport=1234) /
1059 Raw('\xa5' * 100))
1060
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001061 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001062 pkt_intra_epg_220_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001063 eps[0].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001064 # ... and nowhere else
1065 self.pg1.get_capture(0, timeout=0.1)
1066 self.pg1.assert_nothing_captured(remark="Flood onto other VMS")
1067
1068 pkt_intra_epg_221_to_uplink = (Ether(src=self.pg2.remote_mac,
1069 dst="00:00:00:33:44:66") /
Neale Rannsc0a93142018-09-05 15:42:26 -07001070 IP(src=eps[0].ip4.address,
1071 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001072 UDP(sport=1234, dport=1234) /
1073 Raw('\xa5' * 100))
1074
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001075 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001076 pkt_intra_epg_221_to_uplink * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001077 eps[2].epg.uplink)
Neale Ranns25b04942018-04-04 09:34:50 -07001078
1079 #
1080 # Packets from the uplink are forwarded in the absence of a contract
1081 #
1082 pkt_intra_epg_220_from_uplink = (Ether(src="00:00:00:33:44:55",
1083 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001084 IP(src=eps[0].ip4.address,
1085 dst="10.0.0.99") /
Neale Ranns25b04942018-04-04 09:34:50 -07001086 UDP(sport=1234, dport=1234) /
1087 Raw('\xa5' * 100))
1088
1089 self.send_and_expect_bridged(self.pg4,
1090 pkt_intra_epg_220_from_uplink * 65,
1091 self.pg0)
1092
1093 #
1094 # in the absence of policy, endpoints in the same EPG
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001095 # can communicate
1096 #
1097 pkt_intra_epg = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001098 dst=self.pg1.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001099 IP(src=eps[0].ip4.address,
1100 dst=eps[1].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001101 UDP(sport=1234, dport=1234) /
1102 Raw('\xa5' * 100))
1103
Neale Ranns25b04942018-04-04 09:34:50 -07001104 self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001105
1106 #
1107 # in the abscense of policy, endpoints in the different EPG
1108 # cannot communicate
1109 #
1110 pkt_inter_epg_220_to_221 = (Ether(src=self.pg0.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001111 dst=self.pg2.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001112 IP(src=eps[0].ip4.address,
1113 dst=eps[2].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001114 UDP(sport=1234, dport=1234) /
1115 Raw('\xa5' * 100))
1116 pkt_inter_epg_221_to_220 = (Ether(src=self.pg2.remote_mac,
Neale Ranns25b04942018-04-04 09:34:50 -07001117 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001118 IP(src=eps[2].ip4.address,
1119 dst=eps[0].ip4.address) /
Neale Ranns25b04942018-04-04 09:34:50 -07001120 UDP(sport=1234, dport=1234) /
1121 Raw('\xa5' * 100))
1122 pkt_inter_epg_220_to_222 = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001123 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001124 IP(src=eps[0].ip4.address,
1125 dst=eps[3].ip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001126 UDP(sport=1234, dport=1234) /
1127 Raw('\xa5' * 100))
1128
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001129 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001130 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001131 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001132 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001133
1134 #
1135 # A uni-directional contract from EPG 220 -> 221
1136 #
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001137 acl = VppGbpAcl(self)
1138 rule = acl.create_rule(permit_deny=1, proto=17)
1139 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1140 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001141 c1 = VppGbpContract(
1142 self, 220, 221, acl_index,
1143 [VppGbpContractRule(
1144 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1145 []),
1146 VppGbpContractRule(
1147 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1148 [])])
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001149 c1.add_vpp_config()
1150
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001151 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001152 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001153 eps[2].itf)
1154 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001155 pkt_inter_epg_220_to_222 * 65)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001156
1157 #
1158 # contract for the return direction
1159 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001160 c2 = VppGbpContract(
1161 self, 221, 220, acl_index,
1162 [VppGbpContractRule(
1163 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1164 []),
1165 VppGbpContractRule(
1166 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1167 [])])
1168
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001169 c2.add_vpp_config()
1170
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001171 self.send_and_expect_bridged(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001172 pkt_inter_epg_220_to_221 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001173 eps[2].itf)
1174 self.send_and_expect_bridged(eps[2].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001175 pkt_inter_epg_221_to_220 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001176 eps[0].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001177
1178 #
1179 # check that inter group is still disabled for the groups
1180 # not in the contract.
1181 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001182 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001183 pkt_inter_epg_220_to_222 * 65)
1184
Neale Ranns25b04942018-04-04 09:34:50 -07001185 #
1186 # A uni-directional contract from EPG 220 -> 222 'L3 routed'
1187 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001188 c3 = VppGbpContract(
1189 self, 220, 222, acl_index,
1190 [VppGbpContractRule(
1191 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1192 []),
1193 VppGbpContractRule(
1194 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1195 [])])
1196
Neale Ranns25b04942018-04-04 09:34:50 -07001197 c3.add_vpp_config()
1198
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001199 self.logger.info(self.vapi.cli("sh gbp contract"))
1200
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001201 self.send_and_expect_routed(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001202 pkt_inter_epg_220_to_222 * 65,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001203 eps[3].itf,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001204 self.router_mac.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001205
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001206 #
1207 # remove both contracts, traffic stops in both directions
1208 #
1209 c2.remove_vpp_config()
1210 c1.remove_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001211 c3.remove_vpp_config()
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001212 acl.remove_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001213
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001214 self.send_and_assert_no_replies(eps[2].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001215 pkt_inter_epg_221_to_220 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001216 self.send_and_assert_no_replies(eps[0].itf,
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001217 pkt_inter_epg_220_to_221 * 65)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001218 self.send_and_expect_bridged(eps[0].itf,
1219 pkt_intra_epg * 65,
1220 eps[1].itf)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001221
1222 #
Neale Ranns25b04942018-04-04 09:34:50 -07001223 # EPs to the outside world
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001224 #
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001225
Neale Ranns25b04942018-04-04 09:34:50 -07001226 # in the EP's RD an external subnet via the NAT EPG's recirc
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001227 se1 = VppGbpSubnet(
1228 self, rd0, "0.0.0.0", 0,
1229 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1230 sw_if_index=recirc_nat.recirc.sw_if_index,
1231 epg=epg_nat.epg)
1232 se2 = VppGbpSubnet(
1233 self, rd0, "11.0.0.0", 8,
1234 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1235 sw_if_index=recirc_nat.recirc.sw_if_index,
1236 epg=epg_nat.epg)
1237 se16 = VppGbpSubnet(
1238 self, rd0, "::", 0,
1239 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1240 sw_if_index=recirc_nat.recirc.sw_if_index,
1241 epg=epg_nat.epg)
Neale Ranns25b04942018-04-04 09:34:50 -07001242 # in the NAT RD an external subnet via the NAT EPG's uplink
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001243 se3 = VppGbpSubnet(
1244 self, rd20, "0.0.0.0", 0,
1245 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1246 sw_if_index=epg_nat.uplink.sw_if_index,
1247 epg=epg_nat.epg)
1248 se36 = VppGbpSubnet(
1249 self, rd20, "::", 0,
1250 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1251 sw_if_index=epg_nat.uplink.sw_if_index,
1252 epg=epg_nat.epg)
1253 se4 = VppGbpSubnet(
1254 self, rd20, "11.0.0.0", 8,
1255 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_STITCHED_EXTERNAL,
1256 sw_if_index=epg_nat.uplink.sw_if_index,
1257 epg=epg_nat.epg)
1258 se1.add_vpp_config()
1259 se2.add_vpp_config()
1260 se16.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001261 se3.add_vpp_config()
Neale Ranns4a6d0232018-04-24 07:45:33 -07001262 se36.add_vpp_config()
Neale Ranns25b04942018-04-04 09:34:50 -07001263 se4.add_vpp_config()
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001264
Neale Ranns25b04942018-04-04 09:34:50 -07001265 self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
1266 self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
Neale Ranns4a6d0232018-04-24 07:45:33 -07001267 self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
1268 self.logger.info(self.vapi.cli("sh ip6 fib %s" %
Neale Rannsc0a93142018-09-05 15:42:26 -07001269 eps[0].fip6))
Neale Ranns25b04942018-04-04 09:34:50 -07001270
Neale Ranns4a6d0232018-04-24 07:45:33 -07001271 #
1272 # From an EP to an outside addess: IN2OUT
1273 #
Neale Ranns25b04942018-04-04 09:34:50 -07001274 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001275 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001276 IP(src=eps[0].ip4.address,
1277 dst="1.1.1.1") /
Neale Ranns25b04942018-04-04 09:34:50 -07001278 UDP(sport=1234, dport=1234) /
1279 Raw('\xa5' * 100))
1280
1281 # no policy yet
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001282 self.send_and_assert_no_replies(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001283 pkt_inter_epg_220_to_global * 65)
1284
Mohsin Kazmi22b3b842018-04-17 19:35:42 +02001285 acl2 = VppGbpAcl(self)
1286 rule = acl2.create_rule(permit_deny=1, proto=17, sport_from=1234,
1287 sport_to=1234, dport_from=1234, dport_to=1234)
1288 rule2 = acl2.create_rule(is_ipv6=1, permit_deny=1, proto=17,
1289 sport_from=1234, sport_to=1234,
1290 dport_from=1234, dport_to=1234)
1291
1292 acl_index2 = acl2.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001293 c4 = VppGbpContract(
1294 self, 220, 333, acl_index2,
1295 [VppGbpContractRule(
1296 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1297 []),
1298 VppGbpContractRule(
1299 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1300 [])])
1301
Neale Ranns25b04942018-04-04 09:34:50 -07001302 c4.add_vpp_config()
1303
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001304 self.send_and_expect_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001305 pkt_inter_epg_220_to_global * 65,
1306 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001307 eps[0].fip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001308
Neale Ranns4a6d0232018-04-24 07:45:33 -07001309 pkt_inter_epg_220_to_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001310 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001311 IPv6(src=eps[0].ip6.address,
1312 dst="6001::1") /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001313 UDP(sport=1234, dport=1234) /
1314 Raw('\xa5' * 100))
1315
1316 self.send_and_expect_natted6(self.pg0,
1317 pkt_inter_epg_220_to_global * 65,
1318 self.pg7,
Neale Rannsc0a93142018-09-05 15:42:26 -07001319 eps[0].fip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001320
1321 #
1322 # From a global address to an EP: OUT2IN
1323 #
Neale Ranns4d5b9172018-10-24 02:57:49 -07001324 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001325 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001326 IP(dst=eps[0].fip4.address,
Neale Ranns25b04942018-04-04 09:34:50 -07001327 src="1.1.1.1") /
1328 UDP(sport=1234, dport=1234) /
1329 Raw('\xa5' * 100))
1330
1331 self.send_and_assert_no_replies(self.pg7,
1332 pkt_inter_epg_220_from_global * 65)
1333
Neale Ranns13a08cc2018-11-07 09:25:54 -08001334 c5 = VppGbpContract(
1335 self, 333, 220, acl_index2,
1336 [VppGbpContractRule(
1337 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1338 []),
1339 VppGbpContractRule(
1340 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1341 [])])
1342
Neale Ranns25b04942018-04-04 09:34:50 -07001343 c5.add_vpp_config()
1344
1345 self.send_and_expect_unnatted(self.pg7,
1346 pkt_inter_epg_220_from_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001347 eps[0].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001348 eps[0].ip4.address)
Neale Ranns25b04942018-04-04 09:34:50 -07001349
Neale Ranns4d5b9172018-10-24 02:57:49 -07001350 pkt_inter_epg_220_from_global = (Ether(src=self.router_mac.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001351 dst=self.pg0.remote_mac) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001352 IPv6(dst=eps[0].fip6.address,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001353 src="6001::1") /
1354 UDP(sport=1234, dport=1234) /
1355 Raw('\xa5' * 100))
1356
1357 self.send_and_expect_unnatted6(self.pg7,
1358 pkt_inter_epg_220_from_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001359 eps[0].itf,
1360 eps[0].ip6.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001361
1362 #
1363 # From a local VM to another local VM using resp. public addresses:
1364 # IN2OUT2IN
1365 #
Neale Ranns25b04942018-04-04 09:34:50 -07001366 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001367 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001368 IP(src=eps[0].ip4.address,
1369 dst=eps[1].fip4.address) /
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001370 UDP(sport=1234, dport=1234) /
1371 Raw('\xa5' * 100))
1372
Neale Ranns4a6d0232018-04-24 07:45:33 -07001373 self.send_and_expect_double_natted(eps[0].itf,
Neale Ranns25b04942018-04-04 09:34:50 -07001374 pkt_intra_epg_220_global * 65,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001375 eps[1].itf,
Neale Rannsc0a93142018-09-05 15:42:26 -07001376 eps[0].fip4.address,
1377 eps[1].ip4.address)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001378
Neale Rannsc0a93142018-09-05 15:42:26 -07001379 pkt_intra_epg_220_global = (Ether(src=self.pg0.remote_mac,
Neale Ranns4d5b9172018-10-24 02:57:49 -07001380 dst=self.router_mac.address) /
Neale Rannsc0a93142018-09-05 15:42:26 -07001381 IPv6(src=eps[0].ip6.address,
1382 dst=eps[1].fip6.address) /
Neale Ranns4a6d0232018-04-24 07:45:33 -07001383 UDP(sport=1234, dport=1234) /
1384 Raw('\xa5' * 100))
1385
Neale Rannsc0a93142018-09-05 15:42:26 -07001386 self.send_and_expect_double_natted6(eps[0].itf,
Neale Ranns4a6d0232018-04-24 07:45:33 -07001387 pkt_intra_epg_220_global * 65,
Neale Rannsc0a93142018-09-05 15:42:26 -07001388 eps[1].itf,
1389 eps[0].fip6.address,
1390 eps[1].ip6.address)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001391
1392 #
Neale Ranns25b04942018-04-04 09:34:50 -07001393 # cleanup
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001394 #
Neale Ranns25b04942018-04-04 09:34:50 -07001395 for ep in eps:
1396 # del static mappings for each EP from the 10/8 to 11/8 network
Neale Rannsc0a93142018-09-05 15:42:26 -07001397 self.vapi.nat44_add_del_static_mapping(ep.ip4.bytes,
1398 ep.fip4.bytes,
1399 vrf_id=0,
1400 addr_only=1,
1401 is_add=0)
1402 self.vapi.nat66_add_del_static_mapping(ep.ip6.bytes,
1403 ep.fip6.bytes,
1404 vrf_id=0,
1405 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001406
Neale Ranns25b04942018-04-04 09:34:50 -07001407 for epg in epgs:
1408 # IP config on the BVI interfaces
Neale Ranns25b04942018-04-04 09:34:50 -07001409 if epg != epgs[0] and epg != epgs[3]:
Neale Ranns25b04942018-04-04 09:34:50 -07001410 self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
1411 is_inside=1,
1412 is_add=0)
Neale Ranns4a6d0232018-04-24 07:45:33 -07001413 self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
1414 is_inside=1,
1415 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001416
Neale Ranns25b04942018-04-04 09:34:50 -07001417 for recirc in recircs:
Neale Ranns4a6d0232018-04-24 07:45:33 -07001418 self.vapi.nat44_interface_add_del_feature(
1419 recirc.recirc.sw_if_index,
1420 is_inside=0,
1421 is_add=0)
1422 self.vapi.nat66_add_del_interface(
1423 recirc.recirc.sw_if_index,
1424 is_inside=0,
1425 is_add=0)
Neale Rannsbc27d1b2018-02-05 01:13:38 -08001426
Neale Ranns774356a2018-11-29 12:02:16 +00001427 def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None,
1428 n_tries=100, s_time=1):
1429 while (n_tries):
1430 if not find_gbp_endpoint(self, sw_if_index, ip, mac):
1431 return True
1432 n_tries = n_tries - 1
1433 self.sleep(s_time)
1434 self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac))
1435 return False
1436
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001437 def test_gbp_learn_l2(self):
1438 """ GBP L2 Endpoint Learning """
1439
Neale Rannsb6a47952018-11-21 05:44:35 -08001440 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001441 learnt = [{'mac': '00:00:11:11:11:01',
1442 'ip': '10.0.0.1',
1443 'ip6': '2001:10::2'},
1444 {'mac': '00:00:11:11:11:02',
1445 'ip': '10.0.0.2',
1446 'ip6': '2001:10::3'}]
1447
1448 #
1449 # lower the inactive threshold so these tests pass in a
1450 # reasonable amount of time
1451 #
1452 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1453
1454 #
1455 # IP tables
1456 #
1457 gt4 = VppIpTable(self, 1)
1458 gt4.add_vpp_config()
1459 gt6 = VppIpTable(self, 1, is_ip6=True)
1460 gt6.add_vpp_config()
1461
1462 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1463 rd1.add_vpp_config()
1464
1465 #
1466 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1467 # Pg3 hosts the IP4 UU-flood VXLAN tunnel
1468 # Pg4 hosts the IP6 UU-flood VXLAN tunnel
1469 #
1470 self.pg2.config_ip4()
1471 self.pg2.resolve_arp()
1472 self.pg2.generate_remote_hosts(4)
1473 self.pg2.configure_ipv4_neighbors()
1474 self.pg3.config_ip4()
1475 self.pg3.resolve_arp()
1476 self.pg4.config_ip4()
1477 self.pg4.resolve_arp()
1478
1479 #
1480 # a GBP bridge domain with a BVI and a UU-flood interface
1481 #
1482 bd1 = VppBridgeDomain(self, 1)
1483 bd1.add_vpp_config()
1484 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
1485 gbd1.add_vpp_config()
1486
1487 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1488 self.logger.info(self.vapi.cli("sh gbp bridge"))
1489
1490 # ... and has a /32 applied
1491 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1492 ip_addr.add_vpp_config()
1493
1494 #
1495 # The Endpoint-group in which we are learning endpoints
1496 #
1497 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1498 None, self.loop0,
1499 "10.0.0.128",
1500 "2001:10::128")
1501 epg_220.add_vpp_config()
1502 epg_330 = VppGbpEndpointGroup(self, 330, rd1, gbd1,
1503 None, self.loop1,
1504 "10.0.1.128",
1505 "2001:11::128")
1506 epg_330.add_vpp_config()
1507
1508 #
1509 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1510 # leanring enabled
1511 #
1512 vx_tun_l2_1 = VppGbpVxlanTunnel(
1513 self, 99, bd1.bd_id,
1514 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1515 vx_tun_l2_1.add_vpp_config()
1516
1517 #
1518 # A static endpoint that the learnt endpoints are trying to
1519 # talk to
1520 #
1521 ep = VppGbpEndpoint(self, self.pg0,
1522 epg_220, None,
1523 "10.0.0.127", "11.0.0.127",
1524 "2001:10::1", "3001::1")
1525 ep.add_vpp_config()
1526
1527 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1528
1529 # a packet with an sclass from an unknwon EPG
1530 p = (Ether(src=self.pg2.remote_mac,
1531 dst=self.pg2.local_mac) /
1532 IP(src=self.pg2.remote_hosts[0].ip4,
1533 dst=self.pg2.local_ip4) /
1534 UDP(sport=1234, dport=48879) /
1535 VXLAN(vni=99, gpid=88, flags=0x88) /
1536 Ether(src=learnt[0]["mac"], dst=ep.mac) /
1537 IP(src=learnt[0]["ip"], dst=ep.ip4.address) /
1538 UDP(sport=1234, dport=1234) /
1539 Raw('\xa5' * 100))
1540
1541 self.send_and_assert_no_replies(self.pg2, p)
1542
1543 #
1544 # we should not have learnt a new tunnel endpoint, since
1545 # the EPG was not learnt.
1546 #
1547 self.assertEqual(INDEX_INVALID,
1548 find_vxlan_gbp_tunnel(self,
1549 self.pg2.local_ip4,
1550 self.pg2.remote_hosts[0].ip4,
1551 99))
1552
1553 # epg is not learnt, becasue the EPG is unknwon
1554 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1555
1556 for ii, l in enumerate(learnt):
1557 # a packet with an sclass from a knwon EPG
1558 # arriving on an unknown TEP
1559 p = (Ether(src=self.pg2.remote_mac,
1560 dst=self.pg2.local_mac) /
1561 IP(src=self.pg2.remote_hosts[1].ip4,
1562 dst=self.pg2.local_ip4) /
1563 UDP(sport=1234, dport=48879) /
1564 VXLAN(vni=99, gpid=220, flags=0x88) /
1565 Ether(src=l['mac'], dst=ep.mac) /
1566 IP(src=l['ip'], dst=ep.ip4.address) /
1567 UDP(sport=1234, dport=1234) /
1568 Raw('\xa5' * 100))
1569
1570 rx = self.send_and_expect(self.pg2, [p], self.pg0)
1571
1572 # the new TEP
1573 tep1_sw_if_index = find_vxlan_gbp_tunnel(
1574 self,
1575 self.pg2.local_ip4,
1576 self.pg2.remote_hosts[1].ip4,
1577 99)
1578 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
1579
1580 #
1581 # the EP is learnt via the learnt TEP
1582 # both from its MAC and its IP
1583 #
1584 self.assertTrue(find_gbp_endpoint(self,
1585 vx_tun_l2_1.sw_if_index,
1586 mac=l['mac']))
1587 self.assertTrue(find_gbp_endpoint(self,
1588 vx_tun_l2_1.sw_if_index,
1589 ip=l['ip']))
1590
1591 self.logger.info(self.vapi.cli("show gbp endpoint"))
1592 self.logger.info(self.vapi.cli("show gbp vxlan"))
1593 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
1594
1595 #
1596 # If we sleep for the threshold time, the learnt endpoints should
1597 # age out
1598 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001599 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001600 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1601 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001602
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001603 #
1604 # repeat. the do not learn bit is set so the EPs are not learnt
1605 #
1606 for l in learnt:
1607 # a packet with an sclass from a knwon EPG
1608 p = (Ether(src=self.pg2.remote_mac,
1609 dst=self.pg2.local_mac) /
1610 IP(src=self.pg2.remote_hosts[1].ip4,
1611 dst=self.pg2.local_ip4) /
1612 UDP(sport=1234, dport=48879) /
1613 VXLAN(vni=99, gpid=220, flags=0x88, gpflags="D") /
1614 Ether(src=l['mac'], dst=ep.mac) /
1615 IP(src=l['ip'], dst=ep.ip4.address) /
1616 UDP(sport=1234, dport=1234) /
1617 Raw('\xa5' * 100))
1618
1619 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1620
1621 for l in learnt:
1622 self.assertFalse(find_gbp_endpoint(self,
1623 vx_tun_l2_1.sw_if_index,
1624 mac=l['mac']))
1625
1626 #
1627 # repeat
1628 #
1629 for l in learnt:
1630 # a packet with an sclass from a knwon EPG
1631 p = (Ether(src=self.pg2.remote_mac,
1632 dst=self.pg2.local_mac) /
1633 IP(src=self.pg2.remote_hosts[1].ip4,
1634 dst=self.pg2.local_ip4) /
1635 UDP(sport=1234, dport=48879) /
1636 VXLAN(vni=99, gpid=220, flags=0x88) /
1637 Ether(src=l['mac'], dst=ep.mac) /
1638 IP(src=l['ip'], dst=ep.ip4.address) /
1639 UDP(sport=1234, dport=1234) /
1640 Raw('\xa5' * 100))
1641
1642 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1643
1644 self.assertTrue(find_gbp_endpoint(self,
1645 vx_tun_l2_1.sw_if_index,
1646 mac=l['mac']))
1647
1648 #
1649 # Static EP replies to dynamics
1650 #
1651 self.logger.info(self.vapi.cli("sh l2fib bd_id 1"))
1652 for l in learnt:
1653 p = (Ether(src=ep.mac, dst=l['mac']) /
1654 IP(dst=l['ip'], src=ep.ip4.address) /
1655 UDP(sport=1234, dport=1234) /
1656 Raw('\xa5' * 100))
1657
1658 rxs = self.send_and_expect(self.pg0, p * 17, self.pg2)
1659
1660 for rx in rxs:
1661 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
1662 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
1663 self.assertEqual(rx[UDP].dport, 48879)
1664 # the UDP source port is a random value for hashing
1665 self.assertEqual(rx[VXLAN].gpid, 220)
1666 self.assertEqual(rx[VXLAN].vni, 99)
1667 self.assertTrue(rx[VXLAN].flags.G)
1668 self.assertTrue(rx[VXLAN].flags.Instance)
1669 self.assertTrue(rx[VXLAN].gpflags.A)
1670 self.assertFalse(rx[VXLAN].gpflags.D)
1671
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001672 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001673 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1674 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001675
1676 #
1677 # repeat in the other EPG
1678 # there's no contract between 220 and 330, but the A-bit is set
1679 # so the packet is cleared for delivery
1680 #
1681 for l in learnt:
1682 # a packet with an sclass from a knwon EPG
1683 p = (Ether(src=self.pg2.remote_mac,
1684 dst=self.pg2.local_mac) /
1685 IP(src=self.pg2.remote_hosts[1].ip4,
1686 dst=self.pg2.local_ip4) /
1687 UDP(sport=1234, dport=48879) /
1688 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1689 Ether(src=l['mac'], dst=ep.mac) /
1690 IP(src=l['ip'], dst=ep.ip4.address) /
1691 UDP(sport=1234, dport=1234) /
1692 Raw('\xa5' * 100))
1693
1694 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1695
1696 self.assertTrue(find_gbp_endpoint(self,
1697 vx_tun_l2_1.sw_if_index,
1698 mac=l['mac']))
1699
1700 #
1701 # static EP cannot reach the learnt EPs since there is no contract
Neale Ranns13a08cc2018-11-07 09:25:54 -08001702 # only test 1 EP as the others could timeout
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001703 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08001704 p = (Ether(src=ep.mac, dst=l['mac']) /
1705 IP(dst=learnt[0]['ip'], src=ep.ip4.address) /
1706 UDP(sport=1234, dport=1234) /
1707 Raw('\xa5' * 100))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001708
Neale Ranns13a08cc2018-11-07 09:25:54 -08001709 self.send_and_assert_no_replies(self.pg0, [p])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001710
1711 #
1712 # refresh the entries after the check for no replies above
1713 #
1714 for l in learnt:
1715 # a packet with an sclass from a knwon EPG
1716 p = (Ether(src=self.pg2.remote_mac,
1717 dst=self.pg2.local_mac) /
1718 IP(src=self.pg2.remote_hosts[1].ip4,
1719 dst=self.pg2.local_ip4) /
1720 UDP(sport=1234, dport=48879) /
1721 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1722 Ether(src=l['mac'], dst=ep.mac) /
1723 IP(src=l['ip'], dst=ep.ip4.address) /
1724 UDP(sport=1234, dport=1234) /
1725 Raw('\xa5' * 100))
1726
1727 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1728
1729 self.assertTrue(find_gbp_endpoint(self,
1730 vx_tun_l2_1.sw_if_index,
1731 mac=l['mac']))
1732
1733 #
1734 # Add the contract so they can talk
1735 #
1736 acl = VppGbpAcl(self)
1737 rule = acl.create_rule(permit_deny=1, proto=17)
1738 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
1739 acl_index = acl.add_vpp_config([rule, rule2])
Neale Ranns13a08cc2018-11-07 09:25:54 -08001740 c1 = VppGbpContract(
1741 self, 220, 330, acl_index,
1742 [VppGbpContractRule(
1743 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1744 []),
1745 VppGbpContractRule(
1746 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
1747 [])])
1748
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001749 c1.add_vpp_config()
1750
1751 for l in learnt:
1752 p = (Ether(src=ep.mac, dst=l['mac']) /
1753 IP(dst=l['ip'], src=ep.ip4.address) /
1754 UDP(sport=1234, dport=1234) /
1755 Raw('\xa5' * 100))
1756
1757 self.send_and_expect(self.pg0, [p], self.pg2)
1758
1759 #
1760 # send UU packets from the local EP
1761 #
1762 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1763 self.logger.info(self.vapi.cli("sh gbp bridge"))
1764 p_uu = (Ether(src=ep.mac, dst="00:11:11:11:11:11") /
1765 IP(dst="10.0.0.133", src=ep.ip4.address) /
1766 UDP(sport=1234, dport=1234) /
1767 Raw('\xa5' * 100))
1768 rxs = self.send_and_expect(ep.itf, [p_uu], gbd1.uu_flood)
1769
1770 #
1771 # Add a mcast destination VXLAN-GBP tunnel for B&M traffic
1772 #
1773 tun_bm = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
1774 "239.1.1.1", 88,
1775 mcast_itf=self.pg4)
1776 tun_bm.add_vpp_config()
1777 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
1778 port_type=L2_PORT_TYPE.NORMAL)
1779 bp_bm.add_vpp_config()
1780
1781 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1782
1783 p_bm = (Ether(src=ep.mac, dst="ff:ff:ff:ff:ff:ff") /
1784 IP(dst="10.0.0.133", src=ep.ip4.address) /
1785 UDP(sport=1234, dport=1234) /
1786 Raw('\xa5' * 100))
1787 rxs = self.send_and_expect_only(ep.itf, [p_bm], tun_bm.mcast_itf)
1788
1789 #
1790 # Check v6 Endpoints
1791 #
1792 for l in learnt:
1793 # a packet with an sclass from a knwon EPG
1794 p = (Ether(src=self.pg2.remote_mac,
1795 dst=self.pg2.local_mac) /
1796 IP(src=self.pg2.remote_hosts[1].ip4,
1797 dst=self.pg2.local_ip4) /
1798 UDP(sport=1234, dport=48879) /
1799 VXLAN(vni=99, gpid=330, flags=0x88, gpflags='A') /
1800 Ether(src=l['mac'], dst=ep.mac) /
1801 IPv6(src=l['ip6'], dst=ep.ip6.address) /
1802 UDP(sport=1234, dport=1234) /
1803 Raw('\xa5' * 100))
1804
1805 rx = self.send_and_expect(self.pg2, p*65, self.pg0)
1806
1807 self.assertTrue(find_gbp_endpoint(self,
1808 vx_tun_l2_1.sw_if_index,
1809 mac=l['mac']))
1810
1811 #
1812 # L3 Endpoint Learning
1813 # - configured on the bridge's BVI
1814 #
1815
1816 #
1817 # clean up
1818 #
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001819 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00001820 self.wait_for_ep_timeout(vx_tun_l2_1.sw_if_index,
1821 mac=l['mac'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001822
1823 self.pg2.unconfig_ip4()
1824 self.pg3.unconfig_ip4()
1825 self.pg4.unconfig_ip4()
1826
1827 self.logger.info(self.vapi.cli("sh int"))
1828 self.logger.info(self.vapi.cli("sh gbp vxlan"))
1829
Neale Rannsc29c0af2018-11-07 04:21:12 -08001830 def test_gbp_learn_vlan_l2(self):
1831 """ GBP L2 Endpoint w/ VLANs"""
1832
Neale Rannsb6a47952018-11-21 05:44:35 -08001833 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Rannsc29c0af2018-11-07 04:21:12 -08001834 learnt = [{'mac': '00:00:11:11:11:01',
1835 'ip': '10.0.0.1',
1836 'ip6': '2001:10::2'},
1837 {'mac': '00:00:11:11:11:02',
1838 'ip': '10.0.0.2',
1839 'ip6': '2001:10::3'}]
1840
1841 #
1842 # lower the inactive threshold so these tests pass in a
1843 # reasonable amount of time
1844 #
1845 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
1846
1847 #
1848 # IP tables
1849 #
1850 gt4 = VppIpTable(self, 1)
1851 gt4.add_vpp_config()
1852 gt6 = VppIpTable(self, 1, is_ip6=True)
1853 gt6.add_vpp_config()
1854
1855 rd1 = VppGbpRouteDomain(self, 1, gt4, gt6)
1856 rd1.add_vpp_config()
1857
1858 #
1859 # Pg2 hosts the vxlan tunnel, hosts on pg2 to act as TEPs
1860 #
1861 self.pg2.config_ip4()
1862 self.pg2.resolve_arp()
1863 self.pg2.generate_remote_hosts(4)
1864 self.pg2.configure_ipv4_neighbors()
1865 self.pg3.config_ip4()
1866 self.pg3.resolve_arp()
1867
1868 #
1869 # The EP will be on a vlan sub-interface
1870 #
1871 vlan_11 = VppDot1QSubint(self, self.pg0, 11)
1872 vlan_11.admin_up()
1873 self.vapi.sw_interface_set_l2_tag_rewrite(vlan_11.sw_if_index,
1874 L2_VTR_OP.L2_POP_1,
1875 11)
1876
1877 bd_uu_fwd = VppVxlanGbpTunnel(self, self.pg3.local_ip4,
1878 self.pg3.remote_ip4, 116)
1879 bd_uu_fwd.add_vpp_config()
1880
1881 #
1882 # a GBP bridge domain with a BVI and a UU-flood interface
1883 # The BD is marked as do not learn, so no endpoints are ever
1884 # learnt in this BD.
1885 #
1886 bd1 = VppBridgeDomain(self, 1)
1887 bd1.add_vpp_config()
1888 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, bd_uu_fwd,
1889 learn=False)
1890 gbd1.add_vpp_config()
1891
1892 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
1893 self.logger.info(self.vapi.cli("sh gbp bridge"))
1894
1895 # ... and has a /32 applied
1896 ip_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
1897 ip_addr.add_vpp_config()
1898
1899 #
1900 # The Endpoint-group in which we are learning endpoints
1901 #
1902 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
1903 None, self.loop0,
1904 "10.0.0.128",
1905 "2001:10::128")
1906 epg_220.add_vpp_config()
1907
1908 #
1909 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
1910 # leanring enabled
1911 #
1912 vx_tun_l2_1 = VppGbpVxlanTunnel(
1913 self, 99, bd1.bd_id,
1914 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L2)
1915 vx_tun_l2_1.add_vpp_config()
1916
1917 #
1918 # A static endpoint that the learnt endpoints are trying to
1919 # talk to
1920 #
1921 ep = VppGbpEndpoint(self, vlan_11,
1922 epg_220, None,
1923 "10.0.0.127", "11.0.0.127",
1924 "2001:10::1", "3001::1")
1925 ep.add_vpp_config()
1926
1927 self.assertTrue(find_route(self, ep.ip4.address, 32, table_id=1))
1928
1929 #
1930 # Send to the static EP
1931 #
1932 for ii, l in enumerate(learnt):
1933 # a packet with an sclass from a knwon EPG
1934 # arriving on an unknown TEP
1935 p = (Ether(src=self.pg2.remote_mac,
1936 dst=self.pg2.local_mac) /
1937 IP(src=self.pg2.remote_hosts[1].ip4,
1938 dst=self.pg2.local_ip4) /
1939 UDP(sport=1234, dport=48879) /
1940 VXLAN(vni=99, gpid=220, flags=0x88) /
1941 Ether(src=l['mac'], dst=ep.mac) /
1942 IP(src=l['ip'], dst=ep.ip4.address) /
1943 UDP(sport=1234, dport=1234) /
1944 Raw('\xa5' * 100))
1945
1946 rxs = self.send_and_expect(self.pg2, [p], self.pg0)
1947
1948 #
1949 # packet to EP has the EP's vlan tag
1950 #
1951 for rx in rxs:
1952 self.assertEqual(rx[Dot1Q].vlan, 11)
1953
1954 #
1955 # the EP is not learnt since the BD setting prevents it
1956 # also no TEP too
1957 #
1958 self.assertFalse(find_gbp_endpoint(self,
1959 vx_tun_l2_1.sw_if_index,
1960 mac=l['mac']))
1961 self.assertEqual(INDEX_INVALID,
1962 find_vxlan_gbp_tunnel(
1963 self,
1964 self.pg2.local_ip4,
1965 self.pg2.remote_hosts[1].ip4,
1966 99))
1967
1968 self.assertEqual(len(self.vapi.gbp_endpoint_dump()), 1)
1969
1970 #
1971 # static to remotes
1972 # we didn't learn the remotes so they are sent to the UU-fwd
1973 #
1974 for l in learnt:
1975 p = (Ether(src=ep.mac, dst=l['mac']) /
1976 Dot1Q(vlan=11) /
1977 IP(dst=l['ip'], src=ep.ip4.address) /
1978 UDP(sport=1234, dport=1234) /
1979 Raw('\xa5' * 100))
1980
1981 rxs = self.send_and_expect(self.pg0, p * 17, self.pg3)
1982
1983 for rx in rxs:
1984 self.assertEqual(rx[IP].src, self.pg3.local_ip4)
1985 self.assertEqual(rx[IP].dst, self.pg3.remote_ip4)
1986 self.assertEqual(rx[UDP].dport, 48879)
1987 # the UDP source port is a random value for hashing
1988 self.assertEqual(rx[VXLAN].gpid, 220)
1989 self.assertEqual(rx[VXLAN].vni, 116)
1990 self.assertTrue(rx[VXLAN].flags.G)
1991 self.assertTrue(rx[VXLAN].flags.Instance)
1992 self.assertFalse(rx[VXLAN].gpflags.A)
1993 self.assertFalse(rx[VXLAN].gpflags.D)
1994
1995 self.pg2.unconfig_ip4()
1996 self.pg3.unconfig_ip4()
1997
Neale Ranns93cc3ee2018-10-10 07:22:51 -07001998 def test_gbp_learn_l3(self):
1999 """ GBP L3 Endpoint Learning """
2000
Neale Ranns13a08cc2018-11-07 09:25:54 -08002001 self.vapi.cli("set logging class gbp debug")
2002
Neale Rannsb6a47952018-11-21 05:44:35 -08002003 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002004 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2005 routed_src_mac = "00:22:bd:f8:19:ff"
2006
2007 learnt = [{'mac': '00:00:11:11:11:02',
2008 'ip': '10.0.1.2',
2009 'ip6': '2001:10::2'},
2010 {'mac': '00:00:11:11:11:03',
2011 'ip': '10.0.1.3',
2012 'ip6': '2001:10::3'}]
2013
2014 #
2015 # lower the inactive threshold so these tests pass in a
2016 # reasonable amount of time
2017 #
2018 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
2019
2020 #
2021 # IP tables
2022 #
2023 t4 = VppIpTable(self, 1)
2024 t4.add_vpp_config()
2025 t6 = VppIpTable(self, 1, True)
2026 t6.add_vpp_config()
2027
2028 tun_ip4_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2029 self.pg4.remote_ip4, 114)
2030 tun_ip6_uu = VppVxlanGbpTunnel(self, self.pg4.local_ip4,
2031 self.pg4.remote_ip4, 116)
2032 tun_ip4_uu.add_vpp_config()
2033 tun_ip6_uu.add_vpp_config()
2034
2035 rd1 = VppGbpRouteDomain(self, 2, t4, t6, tun_ip4_uu, tun_ip6_uu)
2036 rd1.add_vpp_config()
2037
2038 self.loop0.set_mac(self.router_mac.address)
2039
2040 #
2041 # Bind the BVI to the RD
2042 #
2043 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2044 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2045
2046 #
2047 # Pg2 hosts the vxlan tunnel
2048 # hosts on pg2 to act as TEPs
2049 # pg3 is BD uu-fwd
2050 # pg4 is RD uu-fwd
2051 #
2052 self.pg2.config_ip4()
2053 self.pg2.resolve_arp()
2054 self.pg2.generate_remote_hosts(4)
2055 self.pg2.configure_ipv4_neighbors()
2056 self.pg3.config_ip4()
2057 self.pg3.resolve_arp()
2058 self.pg4.config_ip4()
2059 self.pg4.resolve_arp()
2060
2061 #
2062 # a GBP bridge domain with a BVI and a UU-flood interface
2063 #
2064 bd1 = VppBridgeDomain(self, 1)
2065 bd1.add_vpp_config()
2066 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0, self.pg3)
2067 gbd1.add_vpp_config()
2068
2069 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
2070 self.logger.info(self.vapi.cli("sh gbp bridge"))
2071 self.logger.info(self.vapi.cli("sh gbp route"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002072
2073 # ... and has a /32 and /128 applied
2074 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2075 ip4_addr.add_vpp_config()
2076 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2077 ip6_addr.add_vpp_config()
2078
2079 #
2080 # The Endpoint-group in which we are learning endpoints
2081 #
2082 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2083 None, self.loop0,
2084 "10.0.0.128",
2085 "2001:10::128")
2086 epg_220.add_vpp_config()
2087
2088 #
2089 # The VXLAN GBP tunnel is a bridge-port and has L2 endpoint
2090 # leanring enabled
2091 #
2092 vx_tun_l3 = VppGbpVxlanTunnel(
2093 self, 101, rd1.rd_id,
2094 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2095 vx_tun_l3.add_vpp_config()
2096
2097 #
2098 # A static endpoint that the learnt endpoints are trying to
2099 # talk to
2100 #
2101 ep = VppGbpEndpoint(self, self.pg0,
2102 epg_220, None,
2103 "10.0.0.127", "11.0.0.127",
2104 "2001:10::1", "3001::1")
2105 ep.add_vpp_config()
2106
2107 #
2108 # learn some remote IPv4 EPs
2109 #
2110 for ii, l in enumerate(learnt):
2111 # a packet with an sclass from a knwon EPG
2112 # arriving on an unknown TEP
2113 p = (Ether(src=self.pg2.remote_mac,
2114 dst=self.pg2.local_mac) /
2115 IP(src=self.pg2.remote_hosts[1].ip4,
2116 dst=self.pg2.local_ip4) /
2117 UDP(sport=1234, dport=48879) /
2118 VXLAN(vni=101, gpid=220, flags=0x88) /
2119 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2120 IP(src=l['ip'], dst=ep.ip4.address) /
2121 UDP(sport=1234, dport=1234) /
2122 Raw('\xa5' * 100))
2123
2124 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2125
2126 # the new TEP
2127 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2128 self,
2129 self.pg2.local_ip4,
2130 self.pg2.remote_hosts[1].ip4,
2131 vx_tun_l3.vni)
2132 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2133
2134 # endpoint learnt via the parent GBP-vxlan interface
2135 self.assertTrue(find_gbp_endpoint(self,
2136 vx_tun_l3._sw_if_index,
2137 ip=l['ip']))
2138
2139 #
2140 # Static IPv4 EP replies to learnt
2141 #
2142 for l in learnt:
2143 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2144 IP(dst=l['ip'], src=ep.ip4.address) /
2145 UDP(sport=1234, dport=1234) /
2146 Raw('\xa5' * 100))
2147
2148 rxs = self.send_and_expect(self.pg0, p*1, self.pg2)
2149
2150 for rx in rxs:
2151 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2152 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2153 self.assertEqual(rx[UDP].dport, 48879)
2154 # the UDP source port is a random value for hashing
2155 self.assertEqual(rx[VXLAN].gpid, 220)
2156 self.assertEqual(rx[VXLAN].vni, 101)
2157 self.assertTrue(rx[VXLAN].flags.G)
2158 self.assertTrue(rx[VXLAN].flags.Instance)
2159 self.assertTrue(rx[VXLAN].gpflags.A)
2160 self.assertFalse(rx[VXLAN].gpflags.D)
2161
2162 inner = rx[VXLAN].payload
2163
2164 self.assertEqual(inner[Ether].src, routed_src_mac)
2165 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2166 self.assertEqual(inner[IP].src, ep.ip4.address)
2167 self.assertEqual(inner[IP].dst, l['ip'])
2168
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002169 for l in learnt:
2170 self.assertFalse(find_gbp_endpoint(self,
2171 tep1_sw_if_index,
2172 ip=l['ip']))
2173
2174 #
2175 # learn some remote IPv6 EPs
2176 #
2177 for ii, l in enumerate(learnt):
2178 # a packet with an sclass from a knwon EPG
2179 # arriving on an unknown TEP
2180 p = (Ether(src=self.pg2.remote_mac,
2181 dst=self.pg2.local_mac) /
2182 IP(src=self.pg2.remote_hosts[1].ip4,
2183 dst=self.pg2.local_ip4) /
2184 UDP(sport=1234, dport=48879) /
2185 VXLAN(vni=101, gpid=220, flags=0x88) /
2186 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2187 IPv6(src=l['ip6'], dst=ep.ip6.address) /
2188 UDP(sport=1234, dport=1234) /
2189 Raw('\xa5' * 100))
2190
2191 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2192
2193 # the new TEP
2194 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2195 self,
2196 self.pg2.local_ip4,
2197 self.pg2.remote_hosts[1].ip4,
2198 vx_tun_l3.vni)
2199 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2200
2201 self.logger.info(self.vapi.cli("show gbp bridge"))
2202 self.logger.info(self.vapi.cli("show vxlan-gbp tunnel"))
2203 self.logger.info(self.vapi.cli("show gbp vxlan"))
2204 self.logger.info(self.vapi.cli("show int addr"))
2205
2206 # endpoint learnt via the TEP
2207 self.assertTrue(find_gbp_endpoint(self, ip=l['ip6']))
2208
2209 self.logger.info(self.vapi.cli("show gbp endpoint"))
2210 self.logger.info(self.vapi.cli("show ip fib index 1 %s" % l['ip']))
2211
2212 #
2213 # Static EP replies to learnt
2214 #
2215 for l in learnt:
2216 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2217 IPv6(dst=l['ip6'], src=ep.ip6.address) /
2218 UDP(sport=1234, dport=1234) /
2219 Raw('\xa5' * 100))
2220
2221 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2222
2223 for rx in rxs:
2224 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2225 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2226 self.assertEqual(rx[UDP].dport, 48879)
2227 # the UDP source port is a random value for hashing
2228 self.assertEqual(rx[VXLAN].gpid, 220)
2229 self.assertEqual(rx[VXLAN].vni, 101)
2230 self.assertTrue(rx[VXLAN].flags.G)
2231 self.assertTrue(rx[VXLAN].flags.Instance)
2232 self.assertTrue(rx[VXLAN].gpflags.A)
2233 self.assertFalse(rx[VXLAN].gpflags.D)
2234
2235 inner = rx[VXLAN].payload
2236
2237 self.assertEqual(inner[Ether].src, routed_src_mac)
2238 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2239 self.assertEqual(inner[IPv6].src, ep.ip6.address)
2240 self.assertEqual(inner[IPv6].dst, l['ip6'])
2241
2242 self.logger.info(self.vapi.cli("sh gbp endpoint"))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002243 for l in learnt:
Neale Ranns774356a2018-11-29 12:02:16 +00002244 self.wait_for_ep_timeout(ip=l['ip'])
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002245
2246 #
2247 # Static sends to unknown EP with no route
2248 #
2249 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2250 IP(dst="10.0.0.99", src=ep.ip4.address) /
2251 UDP(sport=1234, dport=1234) /
2252 Raw('\xa5' * 100))
2253
2254 self.send_and_assert_no_replies(self.pg0, [p])
2255
2256 #
2257 # Add a route to static EP's v4 and v6 subnet
Neale Rannsb6a47952018-11-21 05:44:35 -08002258 # packets should be sent on the v4/v6 uu=fwd interface resp.
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002259 #
2260 se_10_24 = VppGbpSubnet(
2261 self, rd1, "10.0.0.0", 24,
2262 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2263 se_10_24.add_vpp_config()
2264
2265 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2266 IP(dst="10.0.0.99", src=ep.ip4.address) /
2267 UDP(sport=1234, dport=1234) /
2268 Raw('\xa5' * 100))
2269
2270 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
2271 for rx in rxs:
2272 self.assertEqual(rx[IP].src, self.pg4.local_ip4)
2273 self.assertEqual(rx[IP].dst, self.pg4.remote_ip4)
2274 self.assertEqual(rx[UDP].dport, 48879)
2275 # the UDP source port is a random value for hashing
2276 self.assertEqual(rx[VXLAN].gpid, 220)
2277 self.assertEqual(rx[VXLAN].vni, 114)
2278 self.assertTrue(rx[VXLAN].flags.G)
2279 self.assertTrue(rx[VXLAN].flags.Instance)
2280 # policy is not applied to packets sent to the uu-fwd interfaces
2281 self.assertFalse(rx[VXLAN].gpflags.A)
2282 self.assertFalse(rx[VXLAN].gpflags.D)
2283
2284 #
2285 # learn some remote IPv4 EPs
2286 #
2287 for ii, l in enumerate(learnt):
2288 # a packet with an sclass from a knwon EPG
2289 # arriving on an unknown TEP
2290 p = (Ether(src=self.pg2.remote_mac,
2291 dst=self.pg2.local_mac) /
2292 IP(src=self.pg2.remote_hosts[1].ip4,
2293 dst=self.pg2.local_ip4) /
2294 UDP(sport=1234, dport=48879) /
2295 VXLAN(vni=101, gpid=220, flags=0x88) /
2296 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2297 IP(src=l['ip'], dst=ep.ip4.address) /
2298 UDP(sport=1234, dport=1234) /
2299 Raw('\xa5' * 100))
2300
2301 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2302
2303 # the new TEP
2304 tep1_sw_if_index = find_vxlan_gbp_tunnel(
2305 self,
2306 self.pg2.local_ip4,
2307 self.pg2.remote_hosts[1].ip4,
2308 vx_tun_l3.vni)
2309 self.assertNotEqual(INDEX_INVALID, tep1_sw_if_index)
2310
2311 # endpoint learnt via the parent GBP-vxlan interface
2312 self.assertTrue(find_gbp_endpoint(self,
2313 vx_tun_l3._sw_if_index,
2314 ip=l['ip']))
2315
2316 #
2317 # Add a remote endpoint from the API
2318 #
2319 rep_88 = VppGbpEndpoint(self, vx_tun_l3,
2320 epg_220, None,
2321 "10.0.0.88", "11.0.0.88",
2322 "2001:10::88", "3001::88",
Neale Rannsb6a47952018-11-21 05:44:35 -08002323 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002324 self.pg2.local_ip4,
2325 self.pg2.remote_hosts[1].ip4,
2326 mac=None)
2327 rep_88.add_vpp_config()
2328
2329 #
2330 # Add a remote endpoint from the API that matches an existing one
2331 #
2332 rep_2 = VppGbpEndpoint(self, vx_tun_l3,
2333 epg_220, None,
2334 learnt[0]['ip'], "11.0.0.101",
2335 learnt[0]['ip6'], "3001::101",
Neale Rannsb6a47952018-11-21 05:44:35 -08002336 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002337 self.pg2.local_ip4,
2338 self.pg2.remote_hosts[1].ip4,
2339 mac=None)
2340 rep_2.add_vpp_config()
2341
2342 #
2343 # Add a route to the leanred EP's v4 subnet
2344 # packets should be send on the v4/v6 uu=fwd interface resp.
2345 #
2346 se_10_1_24 = VppGbpSubnet(
2347 self, rd1, "10.0.1.0", 24,
2348 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_TRANSPORT)
2349 se_10_1_24.add_vpp_config()
2350
2351 self.logger.info(self.vapi.cli("show gbp endpoint"))
2352
2353 ips = ["10.0.0.88", learnt[0]['ip']]
2354 for ip in ips:
2355 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2356 IP(dst=ip, src=ep.ip4.address) /
2357 UDP(sport=1234, dport=1234) /
2358 Raw('\xa5' * 100))
2359
2360 rxs = self.send_and_expect(self.pg0, p*65, self.pg2)
2361
2362 for rx in rxs:
2363 self.assertEqual(rx[IP].src, self.pg2.local_ip4)
2364 self.assertEqual(rx[IP].dst, self.pg2.remote_hosts[1].ip4)
2365 self.assertEqual(rx[UDP].dport, 48879)
2366 # the UDP source port is a random value for hashing
2367 self.assertEqual(rx[VXLAN].gpid, 220)
2368 self.assertEqual(rx[VXLAN].vni, 101)
2369 self.assertTrue(rx[VXLAN].flags.G)
2370 self.assertTrue(rx[VXLAN].flags.Instance)
2371 self.assertTrue(rx[VXLAN].gpflags.A)
2372 self.assertFalse(rx[VXLAN].gpflags.D)
2373
2374 inner = rx[VXLAN].payload
2375
2376 self.assertEqual(inner[Ether].src, routed_src_mac)
2377 self.assertEqual(inner[Ether].dst, routed_dst_mac)
2378 self.assertEqual(inner[IP].src, ep.ip4.address)
2379 self.assertEqual(inner[IP].dst, ip)
2380
2381 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002382 # remove the API remote EPs, only API sourced is gone, the DP
2383 # learnt one remains
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002384 #
2385 rep_88.remove_vpp_config()
2386 rep_2.remove_vpp_config()
2387
2388 self.logger.info(self.vapi.cli("show gbp endpoint"))
2389
Neale Ranns13a08cc2018-11-07 09:25:54 -08002390 self.assertFalse(find_gbp_endpoint(self, ip=rep_88.ip4.address))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002391
Neale Ranns13a08cc2018-11-07 09:25:54 -08002392 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2393 IP(src=ep.ip4.address, dst=rep_88.ip4.address) /
2394 UDP(sport=1234, dport=1234) /
2395 Raw('\xa5' * 100))
2396 rxs = self.send_and_expect(self.pg0, [p], self.pg4)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002397
Neale Ranns13a08cc2018-11-07 09:25:54 -08002398 self.assertTrue(find_gbp_endpoint(self, ip=rep_2.ip4.address))
2399
2400 p = (Ether(src=ep.mac, dst=self.loop0.local_mac) /
2401 IP(src=ep.ip4.address, dst=rep_2.ip4.address) /
2402 UDP(sport=1234, dport=1234) /
2403 Raw('\xa5' * 100))
2404 rxs = self.send_and_expect(self.pg0, [p], self.pg2)
2405
2406 #
2407 # to appease the testcase we cannot have the registered EP stll
2408 # present (because it's DP learnt) when the TC ends so wait until
2409 # it is removed
2410 #
2411 self.sleep(2)
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002412
2413 #
2414 # shutdown with learnt endpoint present
2415 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002416 p = (Ether(src=self.pg2.remote_mac,
2417 dst=self.pg2.local_mac) /
2418 IP(src=self.pg2.remote_hosts[1].ip4,
2419 dst=self.pg2.local_ip4) /
2420 UDP(sport=1234, dport=48879) /
2421 VXLAN(vni=101, gpid=220, flags=0x88) /
2422 Ether(src=l['mac'], dst="00:00:00:11:11:11") /
2423 IP(src=learnt[1]['ip'], dst=ep.ip4.address) /
2424 UDP(sport=1234, dport=1234) /
2425 Raw('\xa5' * 100))
2426
2427 rx = self.send_and_expect(self.pg2, [p], self.pg0)
2428
2429 # endpoint learnt via the parent GBP-vxlan interface
2430 self.assertTrue(find_gbp_endpoint(self,
2431 vx_tun_l3._sw_if_index,
2432 ip=l['ip']))
Neale Ranns93cc3ee2018-10-10 07:22:51 -07002433
2434 #
2435 # TODO
2436 # remote endpoint becomes local
2437 #
2438 self.pg2.unconfig_ip4()
2439 self.pg3.unconfig_ip4()
2440 self.pg4.unconfig_ip4()
2441
Neale Ranns13a08cc2018-11-07 09:25:54 -08002442 def test_gbp_redirect(self):
2443 """ GBP Endpoint Redirect """
2444
2445 self.vapi.cli("set logging class gbp debug")
2446
Neale Rannsb6a47952018-11-21 05:44:35 -08002447 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
Neale Ranns13a08cc2018-11-07 09:25:54 -08002448 routed_dst_mac = "00:0c:0c:0c:0c:0c"
2449 routed_src_mac = "00:22:bd:f8:19:ff"
2450
2451 learnt = [{'mac': '00:00:11:11:11:02',
2452 'ip': '10.0.1.2',
2453 'ip6': '2001:10::2'},
2454 {'mac': '00:00:11:11:11:03',
2455 'ip': '10.0.1.3',
2456 'ip6': '2001:10::3'}]
2457
2458 #
2459 # lower the inactive threshold so these tests pass in a
2460 # reasonable amount of time
2461 #
2462 self.vapi.gbp_endpoint_learn_set_inactive_threshold(1)
2463
2464 #
2465 # IP tables
2466 #
2467 t4 = VppIpTable(self, 1)
2468 t4.add_vpp_config()
2469 t6 = VppIpTable(self, 1, True)
2470 t6.add_vpp_config()
2471
2472 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
2473 rd1.add_vpp_config()
2474
2475 self.loop0.set_mac(self.router_mac.address)
2476
2477 #
2478 # Bind the BVI to the RD
2479 #
2480 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
2481 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
2482
2483 #
2484 # Pg7 hosts a BD's UU-fwd
2485 #
2486 self.pg7.config_ip4()
2487 self.pg7.resolve_arp()
2488
2489 #
2490 # a GBP bridge domains for the EPs
2491 #
2492 bd1 = VppBridgeDomain(self, 1)
2493 bd1.add_vpp_config()
2494 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
2495 gbd1.add_vpp_config()
2496
2497 bd2 = VppBridgeDomain(self, 2)
2498 bd2.add_vpp_config()
2499 gbd2 = VppGbpBridgeDomain(self, bd2, self.loop1)
2500 gbd2.add_vpp_config()
2501
2502 # ... and has a /32 and /128 applied
2503 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 32)
2504 ip4_addr.add_vpp_config()
2505 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 128)
2506 ip6_addr.add_vpp_config()
2507 ip4_addr = VppIpInterfaceAddress(self, gbd2.bvi, "10.0.1.128", 32)
2508 ip4_addr.add_vpp_config()
2509 ip6_addr = VppIpInterfaceAddress(self, gbd2.bvi, "2001:11::128", 128)
2510 ip6_addr.add_vpp_config()
2511
2512 #
2513 # The Endpoint-groups in which we are learning endpoints
2514 #
2515 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
2516 None, gbd1.bvi,
2517 "10.0.0.128",
2518 "2001:10::128")
2519 epg_220.add_vpp_config()
2520 epg_221 = VppGbpEndpointGroup(self, 221, rd1, gbd2,
2521 None, gbd2.bvi,
2522 "10.0.1.128",
2523 "2001:11::128")
2524 epg_221.add_vpp_config()
2525 epg_222 = VppGbpEndpointGroup(self, 222, rd1, gbd1,
2526 None, gbd1.bvi,
2527 "10.0.2.128",
2528 "2001:12::128")
2529 epg_222.add_vpp_config()
2530
2531 #
2532 # a GBP bridge domains for the SEPs
2533 #
2534 bd_uu1 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2535 self.pg7.remote_ip4, 116)
2536 bd_uu1.add_vpp_config()
2537 bd_uu2 = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
2538 self.pg7.remote_ip4, 117)
2539 bd_uu2.add_vpp_config()
2540
2541 bd3 = VppBridgeDomain(self, 3)
2542 bd3.add_vpp_config()
2543 gbd3 = VppGbpBridgeDomain(self, bd3, self.loop2, bd_uu1, learn=False)
2544 gbd3.add_vpp_config()
2545 bd4 = VppBridgeDomain(self, 4)
2546 bd4.add_vpp_config()
2547 gbd4 = VppGbpBridgeDomain(self, bd4, self.loop3, bd_uu2, learn=False)
2548 gbd4.add_vpp_config()
2549
2550 #
2551 # EPGs in which the service endpoints exist
2552 #
2553 epg_320 = VppGbpEndpointGroup(self, 320, rd1, gbd3,
2554 None, gbd1.bvi,
2555 "12.0.0.128",
2556 "4001:10::128")
2557 epg_320.add_vpp_config()
2558 epg_321 = VppGbpEndpointGroup(self, 321, rd1, gbd4,
2559 None, gbd2.bvi,
2560 "12.0.1.128",
2561 "4001:11::128")
2562 epg_321.add_vpp_config()
2563
2564 #
2565 # three local endpoints
2566 #
2567 ep1 = VppGbpEndpoint(self, self.pg0,
2568 epg_220, None,
2569 "10.0.0.1", "11.0.0.1",
2570 "2001:10::1", "3001:10::1")
2571 ep1.add_vpp_config()
2572 ep2 = VppGbpEndpoint(self, self.pg1,
2573 epg_221, None,
2574 "10.0.1.1", "11.0.1.1",
2575 "2001:11::1", "3001:11::1")
2576 ep2.add_vpp_config()
2577 ep3 = VppGbpEndpoint(self, self.pg2,
2578 epg_222, None,
2579 "10.0.2.2", "11.0.2.2",
2580 "2001:12::1", "3001:12::1")
2581 ep3.add_vpp_config()
2582
2583 #
2584 # service endpoints
2585 #
2586 sep1 = VppGbpEndpoint(self, self.pg3,
2587 epg_320, None,
2588 "12.0.0.1", "13.0.0.1",
2589 "4001:10::1", "5001:10::1")
2590 sep1.add_vpp_config()
2591 sep2 = VppGbpEndpoint(self, self.pg4,
2592 epg_320, None,
2593 "12.0.0.2", "13.0.0.2",
2594 "4001:10::2", "5001:10::2")
2595 sep2.add_vpp_config()
2596 sep3 = VppGbpEndpoint(self, self.pg5,
2597 epg_321, None,
2598 "12.0.1.1", "13.0.1.1",
2599 "4001:11::1", "5001:11::1")
2600 sep3.add_vpp_config()
2601 # this EP is not installed immediately
2602 sep4 = VppGbpEndpoint(self, self.pg6,
2603 epg_321, None,
2604 "12.0.1.2", "13.0.1.2",
2605 "4001:11::2", "5001:11::2")
2606
2607 #
2608 # an L2 switch packet between local EPs in different EPGs
2609 # different dest ports on each so the are LB hashed differently
2610 #
2611 p4 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2612 IP(src=ep1.ip4.address, dst=ep3.ip4.address) /
2613 UDP(sport=1234, dport=1234) /
2614 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002615 (Ether(src=ep3.mac, dst=ep1.mac) /
2616 IP(src=ep3.ip4.address, dst=ep1.ip4.address) /
2617 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002618 Raw('\xa5' * 100))]
2619 p6 = [(Ether(src=ep1.mac, dst=ep3.mac) /
2620 IPv6(src=ep1.ip6.address, dst=ep3.ip6.address) /
2621 UDP(sport=1234, dport=1234) /
2622 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002623 (Ether(src=ep3.mac, dst=ep1.mac) /
2624 IPv6(src=ep3.ip6.address, dst=ep1.ip6.address) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002625 UDP(sport=1234, dport=1230) /
2626 Raw('\xa5' * 100))]
2627
2628 # should be dropped since no contract yet
2629 self.send_and_assert_no_replies(self.pg0, [p4[0]])
2630 self.send_and_assert_no_replies(self.pg0, [p6[0]])
2631
2632 #
2633 # Add a contract with a rule to load-balance redirect via SEP1 and SEP2
2634 # one of the next-hops is via an EP that is not known
2635 #
2636 acl = VppGbpAcl(self)
2637 rule4 = acl.create_rule(permit_deny=1, proto=17)
2638 rule6 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
2639 acl_index = acl.add_vpp_config([rule4, rule6])
2640
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002641 #
2642 # test the src-ip hash mode
2643 #
Neale Ranns13a08cc2018-11-07 09:25:54 -08002644 c1 = VppGbpContract(
2645 self, 220, 222, acl_index,
2646 [VppGbpContractRule(
2647 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002648 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002649 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2650 sep1.ip4, sep1.epg.rd),
2651 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2652 sep2.ip4, sep2.epg.rd)]),
2653 VppGbpContractRule(
2654 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002655 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
Neale Ranns13a08cc2018-11-07 09:25:54 -08002656 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2657 sep3.ip6, sep3.epg.rd),
2658 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2659 sep4.ip6, sep4.epg.rd)])])
2660 c1.add_vpp_config()
2661
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002662 c2 = VppGbpContract(
2663 self, 222, 220, acl_index,
2664 [VppGbpContractRule(
2665 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2666 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2667 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2668 sep1.ip4, sep1.epg.rd),
2669 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2670 sep2.ip4, sep2.epg.rd)]),
2671 VppGbpContractRule(
2672 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2673 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SRC_IP,
2674 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2675 sep3.ip6, sep3.epg.rd),
2676 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2677 sep4.ip6, sep4.epg.rd)])])
2678 c2.add_vpp_config()
2679
Neale Ranns13a08cc2018-11-07 09:25:54 -08002680 #
2681 # send again with the contract preset, now packets arrive
2682 # at SEP1 or SEP2 depending on the hashing
2683 #
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002684 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002685
2686 for rx in rxs:
2687 self.assertEqual(rx[Ether].src, routed_src_mac)
2688 self.assertEqual(rx[Ether].dst, sep1.mac)
2689 self.assertEqual(rx[IP].src, ep1.ip4.address)
2690 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2691
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002692 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep2.itf)
2693
2694 for rx in rxs:
2695 self.assertEqual(rx[Ether].src, routed_src_mac)
2696 self.assertEqual(rx[Ether].dst, sep2.mac)
2697 self.assertEqual(rx[IP].src, ep3.ip4.address)
2698 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2699
Neale Ranns13a08cc2018-11-07 09:25:54 -08002700 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2701
2702 for rx in rxs:
2703 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2704 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2705 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2706 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2707 self.assertEqual(rx[VXLAN].vni, 117)
2708 self.assertTrue(rx[VXLAN].flags.G)
2709 self.assertTrue(rx[VXLAN].flags.Instance)
2710 # redirect policy has been applied
2711 self.assertTrue(rx[VXLAN].gpflags.A)
2712 self.assertFalse(rx[VXLAN].gpflags.D)
2713
2714 inner = rx[VXLAN].payload
2715
2716 self.assertEqual(inner[Ether].src, routed_src_mac)
2717 self.assertEqual(inner[Ether].dst, sep4.mac)
2718 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2719 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2720
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002721 rxs = self.send_and_expect(self.pg2, p6[1] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002722
2723 for rx in rxs:
2724 self.assertEqual(rx[Ether].src, routed_src_mac)
2725 self.assertEqual(rx[Ether].dst, sep3.mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002726 self.assertEqual(rx[IPv6].src, ep3.ip6.address)
2727 self.assertEqual(rx[IPv6].dst, ep1.ip6.address)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002728
2729 #
2730 # programme the unknown EP
2731 #
2732 sep4.add_vpp_config()
2733
2734 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2735
2736 for rx in rxs:
2737 self.assertEqual(rx[Ether].src, routed_src_mac)
2738 self.assertEqual(rx[Ether].dst, sep4.mac)
2739 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2740 self.assertEqual(rx[IPv6].dst, ep3.ip6.address)
2741
2742 #
2743 # and revert back to unprogrammed
2744 #
2745 sep4.remove_vpp_config()
2746
2747 rxs = self.send_and_expect(self.pg0, p6[0] * 17, self.pg7)
2748
2749 for rx in rxs:
2750 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
2751 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
2752 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
2753 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
2754 self.assertEqual(rx[VXLAN].vni, 117)
2755 self.assertTrue(rx[VXLAN].flags.G)
2756 self.assertTrue(rx[VXLAN].flags.Instance)
2757 # redirect policy has been applied
2758 self.assertTrue(rx[VXLAN].gpflags.A)
2759 self.assertFalse(rx[VXLAN].gpflags.D)
2760
2761 inner = rx[VXLAN].payload
2762
2763 self.assertEqual(inner[Ether].src, routed_src_mac)
2764 self.assertEqual(inner[Ether].dst, sep4.mac)
2765 self.assertEqual(inner[IPv6].src, ep1.ip6.address)
2766 self.assertEqual(inner[IPv6].dst, ep3.ip6.address)
2767
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002768 c1.remove_vpp_config()
2769 c2.remove_vpp_config()
2770
2771 #
2772 # test the symmetric hash mode
2773 #
2774 c1 = VppGbpContract(
2775 self, 220, 222, acl_index,
2776 [VppGbpContractRule(
2777 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2778 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2779 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2780 sep1.ip4, sep1.epg.rd),
2781 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2782 sep2.ip4, sep2.epg.rd)]),
2783 VppGbpContractRule(
2784 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2785 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2786 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2787 sep3.ip6, sep3.epg.rd),
2788 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2789 sep4.ip6, sep4.epg.rd)])])
2790 c1.add_vpp_config()
2791
2792 c2 = VppGbpContract(
2793 self, 222, 220, acl_index,
2794 [VppGbpContractRule(
2795 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2796 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2797 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2798 sep1.ip4, sep1.epg.rd),
2799 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2800 sep2.ip4, sep2.epg.rd)]),
2801 VppGbpContractRule(
2802 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2803 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2804 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2805 sep3.ip6, sep3.epg.rd),
2806 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2807 sep4.ip6, sep4.epg.rd)])])
2808 c2.add_vpp_config()
2809
2810 #
2811 # send again with the contract preset, now packets arrive
2812 # at SEP1 for both directions
2813 #
2814 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2815
2816 for rx in rxs:
2817 self.assertEqual(rx[Ether].src, routed_src_mac)
2818 self.assertEqual(rx[Ether].dst, sep1.mac)
2819 self.assertEqual(rx[IP].src, ep1.ip4.address)
2820 self.assertEqual(rx[IP].dst, ep3.ip4.address)
2821
2822 rxs = self.send_and_expect(self.pg2, p4[1] * 17, sep1.itf)
2823
2824 for rx in rxs:
2825 self.assertEqual(rx[Ether].src, routed_src_mac)
2826 self.assertEqual(rx[Ether].dst, sep1.mac)
2827 self.assertEqual(rx[IP].src, ep3.ip4.address)
2828 self.assertEqual(rx[IP].dst, ep1.ip4.address)
2829
Neale Ranns13a08cc2018-11-07 09:25:54 -08002830 #
2831 # programme the unknown EP for the L3 tests
2832 #
2833 sep4.add_vpp_config()
2834
2835 #
2836 # an L3 switch packet between local EPs in different EPGs
2837 # different dest ports on each so the are LB hashed differently
2838 #
2839 p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2840 IP(src=ep1.ip4.address, dst=ep2.ip4.address) /
2841 UDP(sport=1234, dport=1234) /
2842 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002843 (Ether(src=ep2.mac, dst=self.router_mac.address) /
2844 IP(src=ep2.ip4.address, dst=ep1.ip4.address) /
2845 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002846 Raw('\xa5' * 100))]
2847 p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2848 IPv6(src=ep1.ip6.address, dst=ep2.ip6.address) /
2849 UDP(sport=1234, dport=1234) /
2850 Raw('\xa5' * 100)),
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002851 (Ether(src=ep2.mac, dst=self.router_mac.address) /
2852 IPv6(src=ep2.ip6.address, dst=ep1.ip6.address) /
2853 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002854 Raw('\xa5' * 100))]
2855
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002856 c3 = VppGbpContract(
2857 self, 220, 221, acl_index,
2858 [VppGbpContractRule(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002859 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002860 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2861 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2862 sep1.ip4, sep1.epg.rd),
2863 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2864 sep2.ip4, sep2.epg.rd)]),
2865 VppGbpContractRule(
2866 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2867 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_SYMMETRIC,
2868 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2869 sep3.ip6, sep3.epg.rd),
2870 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2871 sep4.ip6, sep4.epg.rd)])])
2872 c3.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002873
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002874 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002875
2876 for rx in rxs:
2877 self.assertEqual(rx[Ether].src, routed_src_mac)
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002878 self.assertEqual(rx[Ether].dst, sep1.mac)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002879 self.assertEqual(rx[IP].src, ep1.ip4.address)
2880 self.assertEqual(rx[IP].dst, ep2.ip4.address)
2881
2882 #
2883 # learn a remote EP in EPG 221
2884 #
2885 vx_tun_l3 = VppGbpVxlanTunnel(
2886 self, 444, rd1.rd_id,
2887 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
2888 vx_tun_l3.add_vpp_config()
2889
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002890 c4 = VppGbpContract(
Neale Ranns13a08cc2018-11-07 09:25:54 -08002891 self, 221, 220, acl_index,
2892 [VppGbpContractRule(
2893 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2894 []),
2895 VppGbpContractRule(
2896 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
2897 [])])
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002898 c4.add_vpp_config()
Neale Ranns13a08cc2018-11-07 09:25:54 -08002899
2900 p = (Ether(src=self.pg7.remote_mac,
2901 dst=self.pg7.local_mac) /
2902 IP(src=self.pg7.remote_ip4,
2903 dst=self.pg7.local_ip4) /
2904 UDP(sport=1234, dport=48879) /
2905 VXLAN(vni=444, gpid=221, flags=0x88) /
2906 Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) /
2907 IP(src="10.0.0.88", dst=ep1.ip4.address) /
2908 UDP(sport=1234, dport=1234) /
2909 Raw('\xa5' * 100))
2910
2911 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2912
2913 # endpoint learnt via the parent GBP-vxlan interface
2914 self.assertTrue(find_gbp_endpoint(self,
2915 vx_tun_l3._sw_if_index,
2916 ip="10.0.0.88"))
2917
2918 p = (Ether(src=self.pg7.remote_mac,
2919 dst=self.pg7.local_mac) /
2920 IP(src=self.pg7.remote_ip4,
2921 dst=self.pg7.local_ip4) /
2922 UDP(sport=1234, dport=48879) /
2923 VXLAN(vni=444, gpid=221, flags=0x88) /
2924 Ether(src="00:22:22:22:22:33", dst=self.router_mac.address) /
2925 IPv6(src="2001:10::88", dst=ep1.ip6.address) /
2926 UDP(sport=1234, dport=1234) /
2927 Raw('\xa5' * 100))
2928
2929 rx = self.send_and_expect(self.pg7, [p], self.pg0)
2930
2931 # endpoint learnt via the parent GBP-vxlan interface
2932 self.assertTrue(find_gbp_endpoint(self,
2933 vx_tun_l3._sw_if_index,
2934 ip="2001:10::88"))
2935
2936 #
2937 # L3 switch from local to remote EP
2938 #
2939 p4 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2940 IP(src=ep1.ip4.address, dst="10.0.0.88") /
2941 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002942 Raw('\xa5' * 100))]
2943 p6 = [(Ether(src=ep1.mac, dst=self.router_mac.address) /
2944 IPv6(src=ep1.ip6.address, dst="2001:10::88") /
2945 UDP(sport=1234, dport=1234) /
Neale Ranns13a08cc2018-11-07 09:25:54 -08002946 Raw('\xa5' * 100))]
2947
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002948 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002949
2950 for rx in rxs:
2951 self.assertEqual(rx[Ether].src, routed_src_mac)
2952 self.assertEqual(rx[Ether].dst, sep1.mac)
2953 self.assertEqual(rx[IP].src, ep1.ip4.address)
2954 self.assertEqual(rx[IP].dst, "10.0.0.88")
2955
2956 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep4.itf)
2957
2958 for rx in rxs:
2959 self.assertEqual(rx[Ether].src, routed_src_mac)
2960 self.assertEqual(rx[Ether].dst, sep4.mac)
2961 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2962 self.assertEqual(rx[IPv6].dst, "2001:10::88")
2963
Mohsin Kazmid40c3e62018-11-21 10:46:57 +01002964 #
2965 # test the dst-ip hash mode
2966 #
2967 c5 = VppGbpContract(
2968 self, 220, 221, acl_index,
2969 [VppGbpContractRule(
2970 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2971 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
2972 [VppGbpContractNextHop(sep1.vmac, sep1.epg.bd,
2973 sep1.ip4, sep1.epg.rd),
2974 VppGbpContractNextHop(sep2.vmac, sep2.epg.bd,
2975 sep2.ip4, sep2.epg.rd)]),
2976 VppGbpContractRule(
2977 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_REDIRECT,
2978 VppEnum.vl_api_gbp_hash_mode_t.GBP_API_HASH_MODE_DST_IP,
2979 [VppGbpContractNextHop(sep3.vmac, sep3.epg.bd,
2980 sep3.ip6, sep3.epg.rd),
2981 VppGbpContractNextHop(sep4.vmac, sep4.epg.bd,
2982 sep4.ip6, sep4.epg.rd)])])
2983 c5.add_vpp_config()
2984
2985 rxs = self.send_and_expect(self.pg0, p4[0] * 17, sep1.itf)
2986
2987 for rx in rxs:
2988 self.assertEqual(rx[Ether].src, routed_src_mac)
2989 self.assertEqual(rx[Ether].dst, sep1.mac)
2990 self.assertEqual(rx[IP].src, ep1.ip4.address)
2991 self.assertEqual(rx[IP].dst, "10.0.0.88")
2992
2993 rxs = self.send_and_expect(self.pg0, p6[0] * 17, sep3.itf)
Neale Ranns13a08cc2018-11-07 09:25:54 -08002994
2995 for rx in rxs:
2996 self.assertEqual(rx[Ether].src, routed_src_mac)
2997 self.assertEqual(rx[Ether].dst, sep3.mac)
2998 self.assertEqual(rx[IPv6].src, ep1.ip6.address)
2999 self.assertEqual(rx[IPv6].dst, "2001:10::88")
3000
Neale Rannsb6a47952018-11-21 05:44:35 -08003001 #
3002 # cleanup
3003 #
3004 self.pg7.unconfig_ip4()
3005
3006 def test_gbp_l3_out(self):
3007 """ GBP L3 Out """
3008
3009 ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t
3010 self.vapi.cli("set logging class gbp debug")
3011
3012 routed_dst_mac = "00:0c:0c:0c:0c:0c"
3013 routed_src_mac = "00:22:bd:f8:19:ff"
3014
3015 #
3016 # IP tables
3017 #
3018 t4 = VppIpTable(self, 1)
3019 t4.add_vpp_config()
3020 t6 = VppIpTable(self, 1, True)
3021 t6.add_vpp_config()
3022
3023 rd1 = VppGbpRouteDomain(self, 2, t4, t6)
3024 rd1.add_vpp_config()
3025
3026 self.loop0.set_mac(self.router_mac.address)
3027
3028 #
3029 # Bind the BVI to the RD
3030 #
3031 VppIpInterfaceBind(self, self.loop0, t4).add_vpp_config()
3032 VppIpInterfaceBind(self, self.loop0, t6).add_vpp_config()
3033
3034 #
3035 # Pg7 hosts a BD's BUM
3036 # Pg1 some other l3 interface
3037 #
3038 self.pg7.config_ip4()
3039 self.pg7.resolve_arp()
3040
3041 #
3042 # a GBP external bridge domains for the EPs
3043 #
3044 bd1 = VppBridgeDomain(self, 1)
3045 bd1.add_vpp_config()
3046 gbd1 = VppGbpBridgeDomain(self, bd1, self.loop0)
3047 gbd1.add_vpp_config()
3048
3049 #
3050 # The Endpoint-groups in which the external endpoints exist
3051 #
3052 epg_220 = VppGbpEndpointGroup(self, 220, rd1, gbd1,
3053 None, gbd1.bvi,
3054 "10.0.0.128",
3055 "2001:10::128")
3056 epg_220.add_vpp_config()
3057
3058 # the BVIs have the subnets applied ...
3059 ip4_addr = VppIpInterfaceAddress(self, gbd1.bvi, "10.0.0.128", 24)
3060 ip4_addr.add_vpp_config()
3061 ip6_addr = VppIpInterfaceAddress(self, gbd1.bvi, "2001:10::128", 64)
3062 ip6_addr.add_vpp_config()
3063
3064 # ... which are L3-out subnets
3065 l3o_1 = VppGbpSubnet(
3066 self, rd1, "10.0.0.0", 24,
3067 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3068 epg=200)
3069 l3o_1.add_vpp_config()
3070
3071 #
3072 # an external interface attached to the outside world and the
3073 # external BD
3074 #
3075 vlan_100 = VppDot1QSubint(self, self.pg0, 100)
3076 vlan_100.admin_up()
3077 ext_itf = VppGbpExtItf(self, vlan_100, bd1, rd1)
3078 ext_itf.add_vpp_config()
3079
3080 #
3081 # a multicast vxlan-gbp tunnel for broadcast in the BD
3082 #
3083 tun_bm = VppVxlanGbpTunnel(self, self.pg7.local_ip4,
3084 "239.1.1.1", 88,
3085 mcast_itf=self.pg7)
3086 tun_bm.add_vpp_config()
3087 bp_bm = VppBridgeDomainPort(self, bd1, tun_bm,
3088 port_type=L2_PORT_TYPE.NORMAL)
3089 bp_bm.add_vpp_config()
3090
3091 #
3092 # an unicast vxlan-gbp for inter-BD traffic
3093 #
3094 vx_tun_l3 = VppGbpVxlanTunnel(
3095 self, 444, rd1.rd_id,
3096 VppEnum.vl_api_gbp_vxlan_tunnel_mode_t.GBP_VXLAN_TUNNEL_MODE_L3)
3097 vx_tun_l3.add_vpp_config()
3098
3099 #
3100 # packets destined to unkown addresses in the BVI's subnet
3101 # are ARP'd for
3102 #
3103 p4 = (Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3104 Dot1Q(vlan=100) /
3105 IP(src="10.0.0.1", dst="10.0.0.88") /
3106 UDP(sport=1234, dport=1234) /
3107 Raw('\xa5' * 100))
3108 p6 = (Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3109 Dot1Q(vlan=100) /
3110 IPv6(src="2001:10::1", dst="2001:10::88") /
3111 UDP(sport=1234, dport=1234) /
3112 Raw('\xa5' * 100))
3113
3114 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3115
3116 for rx in rxs:
3117 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3118 # self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3119 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3120 self.assertEqual(rx[IP].dst, "239.1.1.1")
3121 self.assertEqual(rx[VXLAN].vni, 88)
3122 self.assertTrue(rx[VXLAN].flags.G)
3123 self.assertTrue(rx[VXLAN].flags.Instance)
3124 # policy is not applied since we don't know where it's going
3125 self.assertFalse(rx[VXLAN].gpflags.A)
3126 self.assertFalse(rx[VXLAN].gpflags.D)
3127
3128 inner = rx[VXLAN].payload
3129
3130 self.assertTrue(inner.haslayer(ARP))
3131
3132 #
3133 # An external Endpoint
3134 #
3135 eep = VppGbpEndpoint(self, vlan_100,
3136 epg_220, None,
3137 "10.0.0.1", "11.0.0.1",
3138 "2001:10::1", "3001::1",
3139 ep_flags.GBP_API_ENDPOINT_FLAG_EXTERNAL)
3140 eep.add_vpp_config()
3141
3142 #
3143 # A remote endpoint
3144 #
3145 rep = VppGbpEndpoint(self, vx_tun_l3,
3146 epg_220, None,
3147 "10.0.0.101", "11.0.0.101",
3148 "2001:10::101", "3001::101",
3149 ep_flags.GBP_API_ENDPOINT_FLAG_REMOTE,
3150 self.pg7.local_ip4,
3151 self.pg7.remote_ip4,
3152 mac=None)
3153 rep.add_vpp_config()
3154
3155 #
3156 # remote to external
3157 #
3158 p = (Ether(src=self.pg7.remote_mac,
3159 dst=self.pg7.local_mac) /
3160 IP(src=self.pg7.remote_ip4,
3161 dst=self.pg7.local_ip4) /
3162 UDP(sport=1234, dport=48879) /
3163 VXLAN(vni=444, gpid=220, flags=0x88) /
3164 Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3165 IP(src="10.0.0.101", dst="10.0.0.1") /
3166 UDP(sport=1234, dport=1234) /
3167 Raw('\xa5' * 100))
3168
3169 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3170
3171 #
3172 # A subnet reachable through the external EP
3173 #
3174 ip_220 = VppIpRoute(self, "10.220.0.0", 24,
3175 [VppRoutePath(eep.ip4.address,
3176 eep.epg.bvi.sw_if_index)],
3177 table_id=t4.table_id)
3178 ip_220.add_vpp_config()
3179
3180 l3o_220 = VppGbpSubnet(
3181 self, rd1, "10.220.0.0", 24,
3182 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3183 epg=220)
3184 l3o_220.add_vpp_config()
3185
3186 p = (Ether(src=self.pg7.remote_mac,
3187 dst=self.pg7.local_mac) /
3188 IP(src=self.pg7.remote_ip4,
3189 dst=self.pg7.local_ip4) /
3190 UDP(sport=1234, dport=48879) /
3191 VXLAN(vni=444, gpid=220, flags=0x88) /
3192 Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3193 IP(src="10.0.0.101", dst="10.220.0.1") /
3194 UDP(sport=1234, dport=1234) /
3195 Raw('\xa5' * 100))
3196
3197 rxs = self.send_and_expect(self.pg7, p * 1, self.pg0)
3198
3199 #
3200 # another external subnet, this time in a different EPG
3201 #
3202 ip_200 = VppIpRoute(self, "10.200.0.0", 24,
3203 [VppRoutePath(eep.ip4.address,
3204 eep.epg.bvi.sw_if_index)],
3205 table_id=t4.table_id)
3206 ip_200.add_vpp_config()
3207
3208 l3o_200 = VppGbpSubnet(
3209 self, rd1, "10.200.0.0", 24,
3210 VppEnum.vl_api_gbp_subnet_type_t.GBP_API_SUBNET_L3_OUT,
3211 epg=200)
3212 l3o_200.add_vpp_config()
3213
3214 p = (Ether(src=self.pg7.remote_mac,
3215 dst=self.pg7.local_mac) /
3216 IP(src=self.pg7.remote_ip4,
3217 dst=self.pg7.local_ip4) /
3218 UDP(sport=1234, dport=48879) /
3219 VXLAN(vni=444, gpid=220, flags=0x88) /
3220 Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3221 IP(src="10.0.0.101", dst="10.200.0.1") /
3222 UDP(sport=1234, dport=1234) /
3223 Raw('\xa5' * 100))
3224
3225 #
3226 # packets dropped due to lack of contract.
3227 #
3228 rxs = self.send_and_assert_no_replies(self.pg7, p * 1)
3229
3230 #
3231 # from the the subnet in EPG 220 beyond the external to remote
3232 #
3233 p4 = (Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3234 Dot1Q(vlan=100) /
3235 IP(src="10.220.0.1", dst=rep.ip4.address) /
3236 UDP(sport=1234, dport=1234) /
3237 Raw('\xa5' * 100))
3238
3239 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3240
3241 for rx in rxs:
3242 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3243 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3244 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3245 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3246 self.assertEqual(rx[VXLAN].vni, 444)
3247 self.assertTrue(rx[VXLAN].flags.G)
3248 self.assertTrue(rx[VXLAN].flags.Instance)
3249 self.assertTrue(rx[VXLAN].gpflags.A)
3250 self.assertFalse(rx[VXLAN].gpflags.D)
3251
3252 #
3253 # from the the subnet in EPG 200 beyond the external to remote
3254 # dropped due to no contract
3255 #
3256 p4 = (Ether(src=self.pg0.remote_mac, dst=self.router_mac.address) /
3257 Dot1Q(vlan=100) /
3258 IP(src="10.200.0.1", dst=rep.ip4.address) /
3259 UDP(sport=1234, dport=1234) /
3260 Raw('\xa5' * 100))
3261
3262 rxs = self.send_and_assert_no_replies(self.pg0, p4 * 1)
3263
3264 #
3265 # add a contract
3266 #
3267 acl = VppGbpAcl(self)
3268 rule = acl.create_rule(permit_deny=1, proto=17)
3269 rule2 = acl.create_rule(is_ipv6=1, permit_deny=1, proto=17)
3270 acl_index = acl.add_vpp_config([rule, rule2])
3271 c1 = VppGbpContract(
3272 self, 200, 220, acl_index,
3273 [VppGbpContractRule(
3274 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3275 []),
3276 VppGbpContractRule(
3277 VppEnum.vl_api_gbp_rule_action_t.GBP_API_RULE_PERMIT,
3278 [])])
3279 c1.add_vpp_config()
3280
3281 rxs = self.send_and_expect(self.pg0, p4 * 1, self.pg7)
3282
3283 for rx in rxs:
3284 self.assertEqual(rx[Ether].src, self.pg7.local_mac)
3285 self.assertEqual(rx[Ether].dst, self.pg7.remote_mac)
3286 self.assertEqual(rx[IP].src, self.pg7.local_ip4)
3287 self.assertEqual(rx[IP].dst, self.pg7.remote_ip4)
3288 self.assertEqual(rx[VXLAN].vni, 444)
3289 self.assertTrue(rx[VXLAN].flags.G)
3290 self.assertTrue(rx[VXLAN].flags.Instance)
3291 self.assertTrue(rx[VXLAN].gpflags.A)
3292 self.assertFalse(rx[VXLAN].gpflags.D)
3293
3294 #
3295 # cleanup
3296 #
3297 self.pg7.unconfig_ip4()
3298
Neale Rannsbc27d1b2018-02-05 01:13:38 -08003299
3300if __name__ == '__main__':
3301 unittest.main(testRunner=VppTestRunner)