11import os
22import ast
3+ import socket
34import subprocess
45import scapy
56# Packet Test Framework imports
2728DHCP6OptOptReq = scapy .layers .dhcp6 .DHCP6OptOptReq
2829DHCP6OptElapsedTime = scapy .layers .dhcp6 .DHCP6OptElapsedTime
2930DHCP6OptIA_NA = scapy .layers .dhcp6 .DHCP6OptIA_NA
30- DUID_LLT = scapy .layers .dhcp6 .DUID_LLT
31+ DUID_LL = scapy .layers .dhcp6 .DUID_LL
3132DHCP6OptIfaceId = scapy .layers .dhcp6 .DHCP6OptIfaceId
3233DHCP6OptServerId = scapy .layers .dhcp6 .DHCP6OptServerId
3334
@@ -123,11 +124,11 @@ def setUp(self):
123124 self .relay_iface_mac = self .test_params ['relay_iface_mac' ]
124125 self .relay_link_local = self .test_params ['relay_link_local' ]
125126 self .relay_linkaddr = '::'
126-
127127 self .vlan_ip = self .test_params ['vlan_ip' ]
128-
129128 self .client_mac = self .dataplane .get_mac (0 , self .client_port_index )
130129 self .uplink_mac = self .test_params ['uplink_mac' ]
130+ self .loopback_ipv6 = self .test_params ['loopback_ipv6' ]
131+ self .is_dualtor = True if self .test_params ['is_dualtor' ] == 'True' else False
131132
132133 def generate_client_interace_ipv6_link_local_address (self , client_port_index ):
133134 # Shutdown and startup the client interface to generate a proper IPv6 link-local address
@@ -162,31 +163,27 @@ def create_dhcp_solicit_packet(self):
162163 dport = self .DHCP_SERVER_PORT )
163164 solicit_packet /= DHCP6_Solicit (trid = 12345 )
164165 solicit_packet /= DHCP6OptClientId (
165- duid = DUID_LLT (lladdr = self .client_mac ))
166+ duid = DUID_LL (lladdr = self .client_mac ))
166167 solicit_packet /= DHCP6OptIA_NA ()
167168 solicit_packet /= DHCP6OptOptReq (reqopts = [23 , 24 , 29 ])
168169 solicit_packet /= DHCP6OptElapsedTime (elapsedtime = 0 )
169170
170171 return solicit_packet
171172
172- # order: relay forward option list sequence
173- # 0 - increase order, 1 - decrease order
174- def create_dhcp_solicit_relay_forward_packet (self , order ):
173+ def create_dhcp_solicit_relay_forward_packet (self ):
175174 solicit_relay_forward_packet = packet .Ether (src = self .uplink_mac )
176175 solicit_relay_forward_packet /= IPv6 ()
177176 solicit_relay_forward_packet /= packet .UDP (
178177 sport = self .DHCP_SERVER_PORT , dport = self .DHCP_SERVER_PORT )
179178 solicit_relay_forward_packet /= DHCP6_RelayForward (msgtype = 12 , linkaddr = self .vlan_ip ,
180179 peeraddr = self .client_link_local )
181- if order == 1 :
182- solicit_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
183-
184180 solicit_relay_forward_packet /= DHCP6OptRelayMsg (message = [DHCP6_Solicit (trid = 12345 ) /
185- DHCP6OptClientId (duid = DUID_LLT (lladdr = self .client_mac )) /
181+ DHCP6OptClientId (duid = DUID_LL (lladdr = self .client_mac )) /
186182 DHCP6OptIA_NA ()/ DHCP6OptOptReq (reqopts = [23 , 24 , 29 ]) /
187183 DHCP6OptElapsedTime (elapsedtime = 0 )])
188- if order == 0 :
189- solicit_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
184+ if self .is_dualtor :
185+ solicit_relay_forward_packet /= DHCP6OptIfaceId (ifaceid = socket .inet_pton (socket .AF_INET6 , self .vlan_ip ))
186+ solicit_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
190187
191188 return solicit_relay_forward_packet
192189
@@ -203,8 +200,10 @@ def create_dhcp_advertise_packet(self):
203200
204201 def create_dhcp_advertise_relay_reply_packet (self ):
205202 advertise_relay_reply_packet = packet .Ether (dst = self .uplink_mac )
206- advertise_relay_reply_packet /= IPv6 (
207- src = self .server_ip , dst = self .relay_iface_ip )
203+ if self .is_dualtor :
204+ advertise_relay_reply_packet /= IPv6 (src = self .server_ip , dst = self .loopback_ipv6 )
205+ else :
206+ advertise_relay_reply_packet /= IPv6 (src = self .server_ip , dst = self .relay_iface_ip )
208207 advertise_relay_reply_packet /= packet .UDP (
209208 sport = self .DHCP_SERVER_PORT , dport = self .DHCP_SERVER_PORT )
210209 advertise_relay_reply_packet /= DHCP6_RelayReply (msgtype = 13 , linkaddr = self .vlan_ip ,
@@ -224,22 +223,18 @@ def create_dhcp_request_packet(self):
224223
225224 return request_packet
226225
227- # order: relay forward option list sequence
228- # 0 - increase order, 1 - decrease order
229- def create_dhcp_request_relay_forward_packet (self , order ):
226+ def create_dhcp_request_relay_forward_packet (self ):
230227 request_relay_forward_packet = packet .Ether (src = self .uplink_mac )
231228 request_relay_forward_packet /= IPv6 ()
232229 request_relay_forward_packet /= packet .UDP (
233230 sport = self .DHCP_SERVER_PORT , dport = self .DHCP_SERVER_PORT )
234231 request_relay_forward_packet /= DHCP6_RelayForward (msgtype = 12 , linkaddr = self .vlan_ip ,
235232 peeraddr = self .client_link_local )
236- if order == 1 :
237- request_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
238-
239233 request_relay_forward_packet /= DHCP6OptRelayMsg (
240234 message = [DHCP6_Request (trid = 12345 )])
241- if order == 0 :
242- request_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
235+ if self .is_dualtor :
236+ request_relay_forward_packet /= DHCP6OptIfaceId (ifaceid = socket .inet_pton (socket .AF_INET6 , self .vlan_ip ))
237+ request_relay_forward_packet /= DHCP6OptClientLinkLayerAddr ()
243238
244239 return request_relay_forward_packet
245240
@@ -256,15 +251,16 @@ def create_dhcp_reply_packet(self):
256251
257252 def create_dhcp_reply_relay_reply_packet (self ):
258253 reply_relay_reply_packet = packet .Ether (dst = self .uplink_mac )
259- reply_relay_reply_packet /= IPv6 (src = self .server_ip ,
260- dst = self .relay_iface_ip )
254+ if self .is_dualtor :
255+ reply_relay_reply_packet /= IPv6 (src = self .server_ip , dst = self .loopback_ipv6 )
256+ else :
257+ reply_relay_reply_packet /= IPv6 (src = self .server_ip , dst = self .relay_iface_ip )
261258 reply_relay_reply_packet /= packet .UDP (
262259 sport = self .DHCP_SERVER_PORT , dport = self .DHCP_SERVER_PORT )
263260 reply_relay_reply_packet /= DHCP6_RelayReply (msgtype = 13 , linkaddr = self .vlan_ip ,
264261 peeraddr = self .client_link_local )
265262 reply_relay_reply_packet /= DHCP6OptRelayMsg (
266263 message = [DHCP6_Reply (trid = 12345 )])
267- reply_relay_reply_packet /= DHCP6OptIfaceId (ifaceid = self .vlan_ip )
268264
269265 return reply_relay_reply_packet
270266
@@ -295,6 +291,8 @@ def create_dhcp_relayed_relay_packet(self):
295291 relayed_relay_packet /= DHCP6_RelayForward (msgtype = 12 , hopcount = 1 , linkaddr = self .relay_linkaddr ,
296292 peeraddr = self .client_link_local )
297293 relayed_relay_packet /= DHCP6OptRelayMsg (message = [packet_inside ])
294+ if self .is_dualtor :
295+ relayed_relay_packet /= DHCP6OptIfaceId (ifaceid = socket .inet_pton (socket .AF_INET6 , self .vlan_ip ))
298296
299297 return relayed_relay_packet
300298
@@ -309,7 +307,7 @@ def create_dhcp_relay_relay_reply_packet(self):
309307 packet_inside = DHCP6_RelayReply (
310308 msgtype = 13 , linkaddr = self .vlan_ip , peeraddr = self .client_link_local )
311309 packet_inside /= DHCP6OptRelayMsg (message = [DHCP6_Reply (trid = 12345 )])
312- relay_relay_reply_packet /= DHCP6OptServerId (duid = DUID_LLT (lladdr = "00:11:22:33:44:55" ))
310+ relay_relay_reply_packet /= DHCP6OptServerId (duid = DUID_LL (lladdr = "00:11:22:33:44:55" ))
313311 relay_relay_reply_packet /= DHCP6OptRelayMsg (message = [packet_inside ])
314312
315313 return relay_relay_reply_packet
@@ -341,10 +339,9 @@ def client_send_solicit(self):
341339
342340 # Verify that the DHCP relay actually received and relayed the DHCPv6 SOLICIT message to all of
343341 # its known DHCP servers.
344- def verify_relayed_solicit_relay_forward (self , try_count = 0 ):
342+ def verify_relayed_solicit_relay_forward (self ):
345343 # Create a packet resembling a DHCPv6 RELAY-FORWARD encapsulating SOLICIT packet
346- solicit_relay_forward_packet = self .create_dhcp_solicit_relay_forward_packet (
347- order = try_count )
344+ solicit_relay_forward_packet = self .create_dhcp_solicit_relay_forward_packet ()
348345
349346 # Mask off fields we don't care about matching
350347 masked_packet = Mask (solicit_relay_forward_packet )
@@ -362,18 +359,8 @@ def verify_relayed_solicit_relay_forward(self, try_count=0):
362359 masked_packet .set_do_not_care_scapy (
363360 DHCP6OptClientLinkLayerAddr , "clladdr" )
364361
365- # Count the number of these packets received on the ports connected to our leaves
366- solicit_count = testutils .count_matched_packets_all_ports (self , masked_packet ,
367- self .server_port_indices , timeout = 4.0 )
368-
369- if try_count == 0 :
370- if solicit_count >= 1 :
371- return True
372- return False
373-
374- self .assertTrue (solicit_count >= 1 ,
375- "Failed: Solicit count of %d" % solicit_count )
376- return True
362+ # verify packets received on the ports connected to our leaves
363+ testutils .verify_packet_any_port (self , masked_packet , self .server_port_indices )
377364
378365 # Simulate a DHCP server sending a DHCPv6 RELAY-REPLY encapsulating ADVERTISE packet message to client.
379366 # We do this by injecting a RELAY-REPLY encapsulating ADVERTISE message on the link connected to one
@@ -394,8 +381,7 @@ def verify_relayed_advertise(self):
394381 # Mask off fields we don't care about matching
395382 masked_packet = Mask (advertise_packet )
396383 masked_packet .set_do_not_care_scapy (IPv6 , "fl" )
397- # dual tor uses relay_iface_ip as ip src
398- masked_packet .set_do_not_care_scapy (IPv6 , "src" )
384+ # dual tor uses loopback0 ipv6 address as source
399385 masked_packet .set_do_not_care_scapy (packet .UDP , "chksum" )
400386 masked_packet .set_do_not_care_scapy (packet .UDP , "len" )
401387
@@ -410,10 +396,9 @@ def client_send_request(self):
410396
411397 # Verify that the DHCP relay actually received and relayed the DHCPv6 REQUEST message to all of
412398 # its known DHCP servers.
413- def verify_relayed_request_relay_forward (self , try_count = 0 ):
399+ def verify_relayed_request_relay_forward (self ):
414400 # Create a packet resembling a DHCPv6 RELAY-FORWARD encapsulating REQUEST packet
415- request_relay_forward_packet = self .create_dhcp_request_relay_forward_packet (
416- try_count )
401+ request_relay_forward_packet = self .create_dhcp_request_relay_forward_packet ()
417402
418403 # Mask off fields we don't care about matching
419404 masked_packet = Mask (request_relay_forward_packet )
@@ -431,18 +416,8 @@ def verify_relayed_request_relay_forward(self, try_count=0):
431416 masked_packet .set_do_not_care_scapy (
432417 DHCP6OptClientLinkLayerAddr , "clladdr" )
433418
434- # Count the number of these packets received on the ports connected to our leaves
435- request_count = testutils .count_matched_packets_all_ports (self , masked_packet ,
436- self .server_port_indices , timeout = 4.0 )
437-
438- if try_count == 0 :
439- if request_count >= 1 :
440- return True
441- return False
442-
443- self .assertTrue (request_count >= 1 ,
444- "Failed: Request count of %d" % request_count )
445- return True
419+ # verify packets received on the ports connected to our leaves
420+ testutils .verify_packet_any_port (self , masked_packet , self .server_port_indices )
446421
447422 # Simulate a DHCP server sending a DHCPv6 RELAY-REPLY encapsulating REPLY packet message to client.
448423 def server_send_reply_relay_reply (self ):
@@ -461,8 +436,7 @@ def verify_relayed_reply(self):
461436 # Mask off fields we don't care about matching
462437 masked_packet = Mask (reply_packet )
463438 masked_packet .set_do_not_care_scapy (IPv6 , "fl" )
464- # dual tor uses relay_iface_ip as ip src
465- masked_packet .set_do_not_care_scapy (IPv6 , "src" )
439+ # dual tor uses loopback0 ipv6 address as source
466440 masked_packet .set_do_not_care_scapy (packet .UDP , "chksum" )
467441 masked_packet .set_do_not_care_scapy (packet .UDP , "len" )
468442
@@ -515,30 +489,28 @@ def verify_relay_relay_reply(self):
515489 # Mask off fields we don't care about matching
516490 masked_packet = Mask (relay_reply_packet )
517491 masked_packet .set_do_not_care_scapy (IPv6 , "fl" )
518- # dual tor uses relay_iface_ip as ip src
519- masked_packet .set_do_not_care_scapy (IPv6 , "src" )
492+ # dual tor uses loopback0 ipv6 address as source
520493 masked_packet .set_do_not_care_scapy (packet .UDP , "chksum" )
521494 masked_packet .set_do_not_care_scapy (packet .UDP , "len" )
522495
523496 # NOTE: verify_packet() will fail for us via an assert, so no need to check a return value here
524497 testutils .verify_packet (self , masked_packet , self .client_port_index )
525498
526499 def runTest (self ):
527- for x in range (2 ):
528- self .client_send_solicit ()
529- if self .verify_relayed_solicit_relay_forward (x ):
530- break
500+ self .client_send_solicit ()
501+ self .verify_relayed_solicit_relay_forward ()
531502
532503 self .server_send_advertise_relay_reply ()
533504 self .verify_relayed_advertise ()
534- for x in range (2 ):
535- self .client_send_request ()
536- if self .verify_relayed_request_relay_forward (x ):
537- break
505+
506+ self .client_send_request ()
507+ self .verify_relayed_request_relay_forward ()
538508
539509 self .server_send_reply_relay_reply ()
540510 self .verify_relayed_reply ()
511+
541512 self .client_send_relayed_relay_forward ()
542513 self .verify_relayed_relay_forward ()
514+
543515 self .server_send_relay_relay_reply ()
544516 self .verify_relay_relay_reply ()
0 commit comments