2323FG_ECMP_CFG = '/tmp/fg_ecmp.json'
2424USE_INNER_HASHING = False
2525NUM_FLOWS = 1000
26+ ptf_to_dut_port_map = {}
2627
2728SUPPORTED_TOPO = ['t0' ]
2829SUPPORTED_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
127131def 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