Skip to content

Commit b0987ff

Browse files
committed
Initial link oper state handling changes
1 parent ab91edd commit b0987ff

2 files changed

Lines changed: 131 additions & 34 deletions

File tree

ansible/roles/test/files/ptftests/fg_ecmp_test.py

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def log(self, message):
3939
logging.info(message)
4040

4141

42-
def trigger_mac_learning(self, ip_to_port):
43-
for src_ip, src_port in ip_to_port.items():
42+
def trigger_mac_learning(self, exp_ports):
43+
for src_port in exp_ports:
4444
pkt = simple_eth_packet(
4545
eth_dst=self.router_mac,
4646
eth_src=self.dataplane.get_mac(0, src_port),
@@ -90,7 +90,6 @@ def setUp(self):
9090
self.exp_port_set_two = graph['bank_1_port']
9191
self.dst_ip = graph['dst_ip']
9292
self.router_mac = graph['dut_mac']
93-
self.ip_to_port = graph['ip_to_port']
9493
self.num_flows = graph['num_flows']
9594
self.inner_hashing = graph['inner_hashing']
9695

@@ -101,12 +100,11 @@ def setUp(self):
101100
self.log(self.dst_ip)
102101
self.log(self.router_mac)
103102
self.log(self.test_case)
104-
self.log(self.ip_to_port)
105103
self.log(self.num_flows)
106104
self.log(self.inner_hashing)
107105
self.log(self.exp_flow_count)
108106

109-
self.trigger_mac_learning(self.ip_to_port)
107+
self.trigger_mac_learning(self.exp_ports)
110108
time.sleep(3)
111109

112110

@@ -231,6 +229,7 @@ def fg_ecmp(self):
231229
hit_count_map[port_idx] = hit_count_map.get(port_idx, 0) + 1
232230
if port_idx == self.add_nh_port:
233231
assert (port in add_port_grp)
232+
tuple_to_port_map[src_ip] = port_idx
234233
else:
235234
assert port_idx == port
236235

@@ -364,25 +363,26 @@ def send_rcv_ipv6_pkt(self, in_port, sport, dport,
364363
src_mac = self.dataplane.get_mac(0, in_port)
365364
rand_int = random.randint(1, 254)
366365

366+
367367
if self.inner_hashing:
368368
pkt = simple_tcp_packet(
369-
eth_dst=self.router_mac,
370-
eth_src=src_mac,
371-
ip_src=ip_src,
372-
ip_dst=ip_dst,
373-
tcp_sport=sport,
374-
tcp_dport=dport,
375-
ip_ttl=64)
369+
eth_dst=self.router_mac,
370+
eth_src=src_mac,
371+
ip_src=ip_src,
372+
ip_dst=ip_dst,
373+
tcp_sport=sport,
374+
tcp_dport=dport,
375+
ip_ttl=64)
376376
pkt = simple_vxlanv6_packet(
377-
eth_dst=self.router_mac,
378-
eth_src=src_mac,
379-
ipv6_src='2:2:2::' + str(rand_int),
380-
ipv6_dst=self.dst_ip,
381-
udp_sport=rand_int,
382-
udp_dport=4789,
383-
vxlan_vni=rand_int,
384-
with_udp_chksum=False,
385-
inner_frame=pkt)
377+
eth_dst=self.router_mac,
378+
eth_src=src_mac,
379+
ipv6_src='2:2:2::' + str(rand_int),
380+
ipv6_dst=self.dst_ip,
381+
udp_sport=rand_int,
382+
udp_dport=4789,
383+
vxlan_vni=rand_int,
384+
with_udp_chksum=False,
385+
inner_frame=pkt)
386386
else:
387387
pkt = simple_tcpv6_packet(
388388
eth_dst=self.router_mac,
@@ -403,7 +403,6 @@ def send_rcv_ipv6_pkt(self, in_port, sport, dport,
403403
return verify_packet_any_port(self, masked_exp_pkt, dst_port_list)
404404

405405

406-
#---------------------------------------------------------------------
407406
def runTest(self):
408407
# Main function which triggers all the tests
409408
self.fg_ecmp()

tests/ecmp/test_fgnhg.py

Lines changed: 110 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
FG_ECMP_CFG = '/tmp/fg_ecmp.json'
2424
USE_INNER_HASHING = False
2525
NUM_FLOWS = 1000
26+
ptf_to_dut_port_map = {}
2627

2728
SUPPORTED_TOPO = ['t0']
2829
SUPPORTED_PLATFORMS = ['mellanox']
@@ -36,6 +37,7 @@ def configure_interfaces(cfg_facts, duthost, ptfhost, ptfadapter, vlan_ip):
3637
ip_to_port = {}
3738
bank_0_port = []
3839
bank_1_port = []
40+
global ptf_to_dut_port_map
3941

4042
vlan_members = cfg_facts.get('VLAN_MEMBER', {})
4143
print vlan_members
@@ -52,6 +54,7 @@ def configure_interfaces(cfg_facts, duthost, ptfhost, ptfadapter, vlan_ip):
5254
port_list.append(ptf_port_id)
5355
eth_port_list.append(port)
5456
index = index + 1
57+
ptf_to_dut_port_map[ptf_port_id] = port
5558

5659
port_list.sort()
5760
bank_0_port = port_list[:len(port_list)/2]
@@ -88,6 +91,7 @@ def generate_fgnhg_config(duthost, ip_to_port, bank_0_port, bank_1_port, prefix)
8891
bank = "1"
8992
fgnhg_data['FG_NHG_MEMBER'][ip] = {
9093
"bank": bank,
94+
"link": ptf_to_dut_port_map[port],
9195
"FG_NHG": fgnhg_name
9296
}
9397

@@ -126,7 +130,6 @@ def setup_neighbors(duthost, ptfhost, ip_to_port):
126130

127131
def create_fg_ptf_config(ptfhost, ip_to_port, port_list, bank_0_port, bank_1_port, router_mac, net_ports, prefix):
128132
fg_ecmp = {
129-
"ip_to_port": ip_to_port,
130133
"port_list": port_list,
131134
"bank_0_port": bank_0_port,
132135
"bank_1_port": bank_1_port,
@@ -157,18 +160,33 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
157160
else:
158161
ipcmd = "ipv6 route"
159162

163+
### Start test in state where 1 link is down, when nexthop addition occurs for link which is down, the nexthop
164+
### should not go to active
165+
shutdown_link = bank_0_port[0]
166+
dut_if_shutdown = ptf_to_dut_port_map[shutdown_link]
167+
duthost.shell("config interface shutdown " + dut_if_shutdown)
168+
time.sleep(30)
169+
170+
# Now add the route and nhs
160171
for nexthop in ip_to_port:
161172
duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format(ipcmd, prefix, nexthop))
162-
time.sleep(1)
173+
time.sleep(3)
163174

164175
test_time = str(datetime.now().strftime('%Y-%m-%d-%H:%M:%S'))
165176

166-
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.create_flows.log".format(test_time)
167177

178+
### Sned flows with 1 link down, and check the hash distribution
179+
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.create_flows_with_1_link_down.log".format(test_time)
168180
exp_flow_count = {}
169181
flows_per_nh = NUM_FLOWS/len(port_list)
170182
for port in port_list:
171183
exp_flow_count[port] = flows_per_nh
184+
185+
flows_to_redist = exp_flow_count[bank_0_port[0]]
186+
for port in bank_0_port:
187+
if port != shutdown_link:
188+
exp_flow_count[port] = exp_flow_count[port] + flows_to_redist/(len(bank_0_port) - 1)
189+
del exp_flow_count[shutdown_link]
172190

173191
ptf_runner(ptfhost,
174192
"ptftests",
@@ -181,6 +199,7 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
181199
log_file=log_file)
182200

183201

202+
### Hashing verification: Send the same flows again, and verify packets end up on the same ports for a given flow
184203
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.initial_hash_check.log".format(test_time)
185204

186205
ptf_runner(ptfhost,
@@ -192,24 +211,46 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
192211
"config_file": FG_ECMP_CFG},
193212
qlen=1000,
194213
log_file=log_file)
214+
195215

196-
exp_flow_count = {}
216+
### Send the same flows again, but unshut the port which was shutdown at the beginning of test
217+
### Check if hash buckets rebalanced as expected
218+
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.first_link_up.log".format(test_time)
219+
duthost.shell("config interface startup " + dut_if_shutdown)
220+
time.sleep(30)
221+
222+
flows_per_nh = NUM_FLOWS/len(port_list)
223+
for port in port_list:
224+
exp_flow_count[port] = flows_per_nh
225+
226+
ptf_runner(ptfhost,
227+
"ptftests",
228+
"fg_ecmp_test.FgEcmpTest",
229+
platform_dir="ptftests",
230+
params={"test_case": 'add_nh',
231+
"config_file": FG_ECMP_CFG,
232+
"exp_flow_count": exp_flow_count,
233+
"add_nh_port": shutdown_link},
234+
qlen=1000,
235+
log_file=log_file)
236+
237+
238+
### Send the same flows again, but withdraw one next-hop before sending the flows, check if hash bucket
239+
### rebalanced as expected, and the number of flows received on a link is as expected
197240
flows_for_withdrawn_nh_bank = (NUM_FLOWS/2)/(len(bank_0_port) - 1)
198241
withdraw_nh_port = bank_0_port[1]
199-
for port in bank_1_port:
200-
exp_flow_count[port] = flows_per_nh
201242
for port in bank_0_port:
202243
if port != withdraw_nh_port:
203244
exp_flow_count[port] = flows_for_withdrawn_nh_bank
245+
del exp_flow_count[withdraw_nh_port]
204246

205247
for nexthop, port in ip_to_port.items():
206248
if port == withdraw_nh_port:
207249
duthost.shell("vtysh -c 'configure terminal' -c 'no {} {} {}'".format(ipcmd, prefix, nexthop))
208250

209251

210252
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.withdraw_nh.log".format(test_time)
211-
212-
time.sleep(1)
253+
time.sleep(3)
213254

214255
ptf_runner(ptfhost,
215256
"ptftests",
@@ -223,7 +264,61 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
223264
log_file=log_file)
224265

225266

267+
### Send the same flows again, but disable one of the links associated to validate flow redistribution
268+
shutdown_link = bank_0_port[2]
269+
flows_for_shutdown_links_bank = (NUM_FLOWS/2)/(len(bank_0_port) - 2)
270+
for port in bank_0_port:
271+
if port != withdraw_nh_port and port != shutdown_link:
272+
exp_flow_count[port] = flows_for_shutdown_links_bank
273+
del exp_flow_count[shutdown_link]
274+
275+
dut_if_shutdown = ptf_to_dut_port_map[shutdown_link]
276+
duthost.shell("config interface shutdown " + dut_if_shutdown)
277+
278+
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.link_down.log".format(test_time)
279+
time.sleep(30)
280+
281+
ptf_runner(ptfhost,
282+
"ptftests",
283+
"fg_ecmp_test.FgEcmpTest",
284+
platform_dir="ptftests",
285+
params={"test_case": 'withdraw_nh',
286+
"config_file": FG_ECMP_CFG,
287+
"exp_flow_count": exp_flow_count,
288+
"withdraw_nh_port": shutdown_link},
289+
qlen=1000,
290+
log_file=log_file)
291+
292+
293+
### Send the same flows again, but enable the link we disabled the last time
294+
exp_flow_count = {}
295+
flows_for_withdrawn_nh_bank = (NUM_FLOWS/2)/(len(bank_0_port) - 1)
296+
for port in bank_1_port:
297+
exp_flow_count[port] = flows_per_nh
298+
for port in bank_0_port:
299+
if port != withdraw_nh_port:
300+
exp_flow_count[port] = flows_for_withdrawn_nh_bank
301+
302+
duthost.shell("config interface startup " + dut_if_shutdown)
303+
304+
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.second_link_up.log".format(test_time)
305+
time.sleep(30)
306+
307+
ptf_runner(ptfhost,
308+
"ptftests",
309+
"fg_ecmp_test.FgEcmpTest",
310+
platform_dir="ptftests",
311+
params={"test_case": 'add_nh',
312+
"config_file": FG_ECMP_CFG,
313+
"exp_flow_count": exp_flow_count,
314+
"add_nh_port": shutdown_link},
315+
qlen=1000,
316+
log_file=log_file)
317+
318+
319+
### Send the same flows again, but enable the next-hop which was down previously
226320
exp_flow_count = {}
321+
flows_per_nh = NUM_FLOWS/len(port_list)
227322
for port in port_list:
228323
exp_flow_count[port] = flows_per_nh
229324

@@ -232,9 +327,9 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
232327
duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format(ipcmd, prefix, nexthop))
233328

234329

235-
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.add_nh.{}.log".format(test_time)
330+
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.add_nh.log".format(test_time)
236331

237-
time.sleep(1)
332+
time.sleep(3)
238333

239334
ptf_runner(ptfhost,
240335
"ptftests",
@@ -248,6 +343,7 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
248343
log_file=log_file)
249344

250345

346+
### Send the same flows again, but disable all next-hops in a bank to test flow redistribution to the other bank
251347
withdraw_nh_bank = bank_0_port
252348
for nexthop, port in ip_to_port.items():
253349
if port in withdraw_nh_bank:
@@ -256,7 +352,7 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
256352

257353
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.withdraw_bank.log".format(test_time)
258354

259-
time.sleep(1)
355+
time.sleep(3)
260356

261357
exp_flow_count = {}
262358
flows_per_nh = NUM_FLOWS/len(bank_1_port)
@@ -274,14 +370,16 @@ def fg_ecmp(ptfhost, duthost, router_mac, net_ports, port_list, ip_to_port, bank
274370
qlen=1000,
275371
log_file=log_file)
276372

373+
374+
### Send the same flows again, but enable 1 next-hop in a previously down bank to check if flows redistribute back to previously down bank
277375
first_nh = bank_0_port[3]
278376
for nexthop, port in ip_to_port.items():
279377
if port == first_nh:
280378
duthost.shell("vtysh -c 'configure terminal' -c '{} {} {}'".format(ipcmd, prefix, nexthop))
281379

282380
log_file = "/tmp/fg_ecmp_test.FgEcmpTest.{}.add_first_nh.log".format(test_time)
283381

284-
time.sleep(1)
382+
time.sleep(3)
285383

286384
exp_flow_count = {}
287385
flows_per_nh = (NUM_FLOWS/2)/(len(bank_1_port))

0 commit comments

Comments
 (0)