Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions ansible/roles/test/files/ptftests/py3/dhcp_relay_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@
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.client_giaddr = self.test_params.get('client_giaddr', self.switch_loopback_ip)
self.include_client_option82 = self.test_params.get('include_client_option82', True)
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":
Expand Down Expand Up @@ -300,11 +303,12 @@
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.DHCP].options.insert(
discover_packet[scapy.DHCP].options.index("end"),
(82, relay_option82)
)
discover_packet[scapy.BOOTP].giaddr = self.client_giaddr
if self.include_client_option82:
discover_packet[scapy.DHCP].options.insert(
discover_packet[scapy.DHCP].options.index("end"),
(82, relay_option82)
)

return discover_packet

Expand Down Expand Up @@ -337,8 +341,10 @@
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.agent_relay_mode and self.client_giaddr:
giaddr = self.client_giaddr
elif ((self.link_selection and self.source_interface) or
self.server_vrf or self.dual_tor):
giaddr = self.switch_loopback_ip
elif self.server_id_override or not self.dual_tor:
giaddr = self.relay_iface_ip
Expand All @@ -349,7 +355,10 @@
dport=self.DHCP_SERVER_PORT, len=308)

# Relay-side behavior based on agent_mode
if self.agent_relay_mode == "discard":
if not self.include_client_option82:
dhcp_options = [('message-type', 'discover'), ('end')]

elif self.agent_relay_mode == "discard":
dhcp_options = [('message-type', 'discover'), (82, self.option82), ('end')]

elif self.agent_relay_mode == "replace":
Expand Down Expand Up @@ -1201,13 +1210,35 @@

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)

Check failure

Code scanning / CodeQL

Potentially uninitialized local variable Error test

Local variable 'expected_forward' may be used before it is initialized.
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))
Expand Down
62 changes: 62 additions & 0 deletions tests/dhcp_relay/test_dhcpv4_relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down Expand Up @@ -439,6 +440,67 @@ def test_dhcp_relay_agent_mode(
sonic_dhcp_relay_config(duthost, dut_dhcp_relay_data)


def test_dhcp_relay_chained_request_without_option82(
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, # noqa: F811
relay_agent # noqa: F811
):
"""Verify native relay forwards a chained request without adding Option 82."""
testing_mode, duthost = testing_config

try:
for dhcp_relay in dut_dhcp_relay_data:
vlan = str(dhcp_relay['downlink_vlan_iface']['name'])
dhcp_servers = ",".join(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs'])
duthost.shell(f'config dhcpv4_relay del {vlan}')
duthost.shell(f'config dhcpv4_relay add --dhcpv4-servers {dhcp_servers}'
f' --agent-relay-mode discard {vlan}')

ptf_runner(
ptfhost,
"ptftests",
"dhcp_relay_test.DHCPTest",
platform_dir="ptftests",
params={
"hostname": duthost.hostname,
"client_port_index": dhcp_relay['client_iface']['port_idx'],
"other_client_port": repr(dhcp_relay['other_client_ports']),
"client_iface_alias": str(dhcp_relay['client_iface']['alias']),
"leaf_port_indices": repr(dhcp_relay['uplink_port_indices']),
"num_dhcp_servers": len(dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs']),
"server_ip": dhcp_relay['downlink_vlan_iface']['dhcp_server_addrs'],
"relay_iface_ip": str(dhcp_relay['downlink_vlan_iface']['addr']),
"relay_iface_mac": str(dhcp_relay['downlink_vlan_iface']['mac']),
"relay_iface_netmask": str(dhcp_relay['downlink_vlan_iface']['mask']),
"dest_mac_address": BROADCAST_MAC,
"client_udp_src_port": DEFAULT_DHCP_CLIENT_PORT,
"switch_loopback_ip": dhcp_relay['switch_loopback_ip'],
"uplink_mac": str(dhcp_relay['uplink_mac']),
"testing_mode": testing_mode,
"kvm_support": True,
"relay_agent": relay_agent,
"agent_relay_mode": "discard",
"client_giaddr": DOWNSTREAM_RELAY_IP,
"include_client_option82": False,
"expected_forward": True,
"downlink_vlan_iface_name": str(dhcp_relay['downlink_vlan_iface']['name']),
},
log_file="/tmp/test_dhcp_relay_chained_no_option82.log",
is_python3=True
)
except LogAnalyzerError as err:
logger.error("Unable to find expected log in syslog")
raise err
finally:
sonic_dhcp_relay_unconfig(duthost, dut_dhcp_relay_data)
sonic_dhcp_relay_config(duthost, dut_dhcp_relay_data)


@pytest.mark.parametrize("testcase", ["vrf_selection", "source_intf", "server_id_override"])
def test_dhcp_relay_with_non_default_vrf(
ptfhost,
Expand Down
Loading