diff --git a/ansible/roles/test/files/ptftests/py3/dhcp_relay_test.py b/ansible/roles/test/files/ptftests/py3/dhcp_relay_test.py index 7b911e9f5e8..14edd6420bc 100644 --- a/ansible/roles/test/files/ptftests/py3/dhcp_relay_test.py +++ b/ansible/roles/test/files/ptftests/py3/dhcp_relay_test.py @@ -174,6 +174,9 @@ def setUp(self): self.portchannels_ip_list = self.test_params.get('portchannels_ip_list', None) self.agent_relay_mode = self.test_params.get('agent_relay_mode', None) self.max_hop_count = self.test_params.get('max_hop_count', None) + self.incoming_hop_count = self.test_params.get('incoming_hop_count', None) + self.client_giaddr = self.test_params.get('client_giaddr', self.switch_loopback_ip) + self.expected_forward = self.test_params.get('expected_forward', None) self.client_vrf = self.test_params.get('client_vrf', None) self.dhcpv4_disable_flag = self.test_params.get('dhcpv4_disable_flag', None) if self.relay_agent == "sonic-relay-agent": @@ -299,8 +302,11 @@ def create_dhcp_discover_packet(self, dst_mac=BROADCAST_MAC, src_port=DHCP_CLIEN discover_packet[scapy.Ether].dst = self.uplink_mac discover_packet[scapy.IP].src = self.client_ip discover_packet[scapy.IP].dst = self.switch_loopback_ip - discover_packet[scapy.BOOTP].hops = self.max_hop_count if self.max_hop_count == self.MAX_HOP_COUNT else 1 - discover_packet[scapy.BOOTP].giaddr = self.switch_loopback_ip + discover_packet[scapy.BOOTP].hops = ( + self.incoming_hop_count if self.incoming_hop_count is not None + else self.max_hop_count if self.max_hop_count == self.MAX_HOP_COUNT else 1 + ) + discover_packet[scapy.BOOTP].giaddr = self.client_giaddr discover_packet[scapy.DHCP].options.insert( discover_packet[scapy.DHCP].options.index("end"), (82, relay_option82) @@ -337,8 +343,10 @@ def create_dhcp_discover_relayed_packet(self): else: source_ip = self.portchannels_ip_list[0] - if ((self.link_selection and self.source_interface) or - self.server_vrf or self.dual_tor or self.agent_relay_mode): + if self.incoming_hop_count is not None: + giaddr = self.client_giaddr + elif ((self.link_selection and self.source_interface) or + self.server_vrf or self.dual_tor or self.agent_relay_mode): giaddr = self.switch_loopback_ip elif self.server_id_override or not self.dual_tor: giaddr = self.relay_iface_ip @@ -380,7 +388,9 @@ def create_dhcp_discover_relayed_packet(self): (82, self.option82), ('end')] - if self.max_hop_count == self.MAX_HOP_COUNT: + if self.incoming_hop_count is not None: + hops = self.incoming_hop_count + 1 + elif self.max_hop_count == self.MAX_HOP_COUNT: hops = 17 elif self.agent_relay_mode: hops = 2 @@ -1203,11 +1213,33 @@ def check_relayed_pkts_on_server_side(self, mask, pkt, packet_type): logger.info("Expect receiving {} packets from port [{}]".format(packet_type, self.server_port_indices)) log_dhcp_packet_info(pkt) num_expected_packets = self.num_dhcp_servers - if self.agent_relay_mode == "discard" or self.dhcpv4_disable_flag or self.max_hop_count == self.MAX_HOP_COUNT: - # Expected result: No packet sent + if self.expected_forward is None: + expected_forward = not ( + self.agent_relay_mode == "discard" + or self.dhcpv4_disable_flag + or self.max_hop_count == self.MAX_HOP_COUNT + ) + else: + expected_forward = self.expected_forward + if expected_forward: + packet_mask = mask + else: num_expected_packets = 0 + unexpected_packet = ( + scapy.Ether(src=self.uplink_mac) + / scapy.IP() + / scapy.UDP(sport=self.DHCP_SERVER_PORT, dport=self.DHCP_SERVER_PORT) + ) + packet_mask = Mask(unexpected_packet) + packet_mask.set_do_not_care_scapy(scapy.Ether, "dst") + for field in ("version", "ihl", "tos", "len", "id", "flags", + "frag", "ttl", "chksum", "src", "dst", "options"): + packet_mask.set_do_not_care_scapy(scapy.IP, field) + packet_mask.set_do_not_care_scapy(scapy.UDP, "chksum") + packet_mask.set_do_not_care_scapy(scapy.UDP, "len") + packet_mask.set_ignore_extra_bytes() captured_count = testutils.count_matched_packets_all_ports( - self, mask, self.server_port_indices) + self, packet_mask, self.server_port_indices) self.assertTrue(captured_count == num_expected_packets, "Failed: %s packet counts are not equal %d != %d" % (packet_type, captured_count, num_expected_packets)) diff --git a/tests/dhcp_relay/test_dhcpv4_relay.py b/tests/dhcp_relay/test_dhcpv4_relay.py index bd4f2cede48..2dbd8bdb658 100644 --- a/tests/dhcp_relay/test_dhcpv4_relay.py +++ b/tests/dhcp_relay/test_dhcpv4_relay.py @@ -79,6 +79,7 @@ def _restore_interface_ip_entries(duthost, saved_entries): CLIENT_VRF_NAME = "Vrf01" # Global macro for Client VRF MAX_HOP_COUNT = 16 CONFIG_HOP_COUNT = 2 +DOWNSTREAM_RELAY_IP = '192.0.2.1' # TEST-NET-1; synthetic downstream relay logger = logging.getLogger(__name__) @@ -855,13 +856,21 @@ def test_dhcp_relay_with_different_non_default_vrf( duthost.shell("sudo config save -y") -@pytest.mark.parametrize("max_hop_count", [CONFIG_HOP_COUNT, MAX_HOP_COUNT]) +@pytest.mark.parametrize( + "max_hop_count,incoming_hop_count,expected_forward", + [ + (CONFIG_HOP_COUNT, 1, True), + (CONFIG_HOP_COUNT, CONFIG_HOP_COUNT, False), + (MAX_HOP_COUNT, MAX_HOP_COUNT - 1, True), + (MAX_HOP_COUNT, MAX_HOP_COUNT, False), + ] +) def test_dhcp_max_hop_count(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config, setup_standby_ports_on_rand_unselected_tor, rand_unselected_dut, toggle_all_simulator_ports_to_rand_selected_tor_m, relay_agent, # noqa: F811 - max_hop_count): - + max_hop_count, incoming_hop_count, expected_forward): + """Verify configured hop limits distinguish forwarding from dropping.""" testing_mode, duthost = testing_config try: @@ -901,9 +910,12 @@ def test_dhcp_max_hop_count(ptfhost, dut_dhcp_relay_data, validate_dut_routes_ex "relay_agent": relay_agent, "agent_relay_mode": "append", "max_hop_count": max_hop_count, + "incoming_hop_count": incoming_hop_count, + "client_giaddr": DOWNSTREAM_RELAY_IP, + "expected_forward": expected_forward, "downlink_vlan_iface_name": str(dhcp_relay['downlink_vlan_iface']['name']), }, - log_file="/tmp/test_dhcp_relay_agent_mode.log", + log_file="/tmp/test_dhcp_max_hop_count.log", is_python3=True )