Skip to content

Commit

Permalink
dhcpv6 per-interface counter script coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
jcaiMR committed Sep 7, 2023
1 parent 2a6585d commit 5b2aa47
Showing 1 changed file with 85 additions and 16 deletions.
101 changes: 85 additions & 16 deletions tests/dhcp_relay/test_dhcpv6_relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@

SINGLE_TOR_MODE = 'single'
DUAL_TOR_MODE = 'dual'
NEW_COUNTER_VALUE_FORMAT = (
"{'Unknown':'0','Solicit':'0','Advertise':'0','Request':'0','Confirm':'0','Renew':'0','Rebind':'0','Reply':'0',"
"'Release':'0','Decline':'0','Reconfigure':'0','Information-Request':'0','Relay-Forward':'0','Relay-Reply':'0',"
"'Malformed':'0'}"
)

logger = logging.getLogger(__name__)

Expand All @@ -33,6 +38,50 @@ def wait_all_bgp_up(duthost):
pytest.fail("not all bgp sessions are up after config change")


def check_dhcpv6_relay_counter(duthost, ifname, type, dir):
# new counter table
# sonic-db-cli STATE_DB hgetall 'DHCPv6_COUNTER_TABLE|Vlan1000'
# {'TX': "{'Unknown':'0','Solicit':'0','Advertise':'0','Request':'0','Confirm':'0','Renew':'0','Rebind':'0',
# 'Reply':'0', 'Release':'0','Decline':'0','Reconfigure':'0','Information-Request':'0','Relay-Forward':'0',
# 'Relay-Reply':'0','Malformed':'0'}", 'RX': "{'Unknown':'0','Solicit':'0','Advertise':'0','Request':'0',
# 'Confirm':'0','Renew':'0','Rebind':'0','Reply':'0', 'Release':'0','Decline':'0','Reconfigure':'0',
# 'Information-Request':'0','Relay-Forward':'0','Relay-Reply':'0','Malformed':'0'}"}
#
# old counter table
# sonic-db-cli STATE_DB hgetall 'DHCPv6_COUNTER_TABLE|Vlan1000'
# {'Unknown':'0','Solicit':'0','Advertise':'0','Request':'0','Confirm':'0','Renew':'0','Rebind':'0','Reply':'0',
# 'Release':'0','Decline':'0','Reconfigure':'0','Information-Request':'0','Relay-Forward':'0','Relay-Reply':'0',
# 'Malformed':'0'}
#
cmd_new_version = 'sonic-db-cli STATE_DB hget "DHCPv6_COUNTER_TABLE|{}" {}'.format(ifname, dir)
cmd_old_version = 'sonic-db-cli STATE_DB hget "DHCPv6_COUNTER_TABLE|{}" {}'.format(ifname, type)
output_new = duthost.shell(cmd_new_version)['stdout']
if len(output_new) != 0:
counters = eval(output_new)
assert int(counters[type]) > 0, "{}({}) missing {} count".format(ifname, dir, type)
else:
# old version only support vlan couting
if 'Vlan' not in ifname:
return
output_old = duthost.shell(cmd_old_version)['stdout']
assert int(output_old) > 0, "{} missing {} count".format(ifname, type)


def init_counter(duthost, ifname, types):
cmd_new_version = 'sonic-db-cli STATE_DB hget "DHCPv6_COUNTER_TABLE|{}" RX'.format(ifname)
output_new = duthost.shell(cmd_new_version)['stdout']
if len(output_new) != 0:
counters_str = NEW_COUNTER_VALUE_FORMAT
cmd = 'sonic-db-cli STATE_DB hmset "DHCPv6_COUNTER_TABLE|{}" "RX" "{}"'.format(ifname, str(counters_str))
duthost.shell(cmd)
cmd = 'sonic-db-cli STATE_DB hmset "DHCPv6_COUNTER_TABLE|{}" "TX" "{}"'.format(ifname, str(counters_str))
duthost.shell(cmd)
else:
for type in types:
cmd = 'sonic-db-cli STATE_DB hmset "DHCPv6_COUNTER_TABLE|{}" {} 0'.format(ifname, type)
duthost.shell(cmd)


@pytest.fixture(scope="module")
def testing_config(duthosts, rand_one_dut_hostname, tbinfo):
duthost = duthosts[rand_one_dut_hostname]
Expand Down Expand Up @@ -140,6 +189,7 @@ def dut_dhcp_relay_data(duthosts, rand_one_dut_hostname, tbinfo):
dhcp_relay_data['uplink_interfaces'] = uplink_interfaces
dhcp_relay_data['uplink_port_indices'] = uplink_port_indices
dhcp_relay_data['down_interface_link_local'] = down_interface_link_local
dhcp_relay_data['loopback_iface'] = mg_facts['minigraph_lo_interfaces']
dhcp_relay_data['loopback_ipv6'] = mg_facts['minigraph_lo_interfaces'][1]['addr']
if 'dualtor' in tbinfo['topo']['name']:
dhcp_relay_data['is_dualtor'] = True
Expand Down Expand Up @@ -195,15 +245,15 @@ def test_dhcpv6_relay_counter(ptfhost, duthosts, rand_one_dut_hostname, dut_dhcp
duthost = duthosts[rand_one_dut_hostname]
skip_release(duthost, ["201911", "202106"])

messages = ["Unknown", "Solicit", "Advertise", "Request", "Confirm", "Renew", "Rebind", "Reply", "Release",
"Decline", "Reconfigure", "Information-Request", "Relay-Forward", "Relay-Reply", "Malformed"]
message_types = ["Unknown", "Solicit", "Advertise", "Request", "Confirm", "Renew", "Rebind", "Reply", "Release",
"Decline", "Reconfigure", "Information-Request", "Relay-Forward", "Relay-Reply", "Malformed"]

for dhcp_relay in dut_dhcp_relay_data:

for message in messages:
cmd = 'sonic-db-cli STATE_DB hmset "DHCPv6_COUNTER_TABLE|{}" {} 0'\
.format(dhcp_relay['downlink_vlan_iface']['name'], message)
duthost.shell(cmd)
init_counter(duthost, dhcp_relay['client_iface']['name'], message_types)
init_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], message_types)
if dhcp_relay['is_dualtor']:
init_counter(duthost, dhcp_relay['loopback_iface'][0]['name'], message_types)

# Send the DHCP relay traffic on the PTF host
ptf_runner(ptfhost,
Expand All @@ -224,16 +274,35 @@ def test_dhcpv6_relay_counter(ptfhost, duthosts, rand_one_dut_hostname, dut_dhcp
"is_dualtor": str(dhcp_relay['is_dualtor'])},
log_file="/tmp/dhcpv6_relay_test.DHCPCounterTest.log", is_python3=True)

for message in messages:
if message == "Relay-Reply" and dhcp_relay['is_dualtor']:
get_message = 'sonic-db-cli STATE_DB hget "DHCPv6_COUNTER_TABLE|Loopback0" {}'.format(message)
message_count = duthost.shell(get_message)['stdout']
assert int(message_count) > 0, "Missing {} count".format(message)
else:
get_message = 'sonic-db-cli STATE_DB hget "DHCPv6_COUNTER_TABLE|{}" {}'\
.format(dhcp_relay['downlink_vlan_iface']['name'], message)
message_count = duthost.shell(get_message)['stdout']
assert int(message_count) > 0, "Missing {} count".format(message)
for type in message_types:
if type in ["Solicit", "Request", "Confirm", "Renew", "Rebind", "Release", "Decline",
"Information-Request"]:
check_dhcpv6_relay_counter(duthost, dhcp_relay['client_iface']['name'], type, "RX")
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "RX")
if type in ["Malformed"]:
# Malformed DHCPv6 Client packet, depend on malformed content. If Type is good but option is malformed
# First Type will be increased on downlink Ethernet interface first. Then increase Malformed counter
# on downlink_vlan_iface.
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "RX")
if type in ["Unknown"]:
# From Server Relay-Reply Unknown DHCPv6 type, it's a valid Relay-Reply so Relay-Reply counter
# is normal increased. But in relay message type is unknown type so drop on downlink_vlan_iface
# interface
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "RX")
if type in ["Advertise", "Reply", "Reconfigure"]:
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "TX")
check_dhcpv6_relay_counter(duthost, dhcp_relay['client_iface']['name'], type, "TX")
if type in ["Relay-Forward"]:
# Relay-Forward, send out from downlink_vlan_iface first, then send out from uplink interfaces
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "TX")
# TBD, add uplink interface TX counter check in future
if type in ["Relay-Reply"]:
if dhcp_relay['is_dualtor']:
# dual tor, Relay-Reply will be received on loopback interface
check_dhcpv6_relay_counter(duthost, dhcp_relay['loopback_iface'][0]['name'], type, "RX")
else:
# Single tor, Relay-Reply will be received on downlink_vlan_iface
check_dhcpv6_relay_counter(duthost, dhcp_relay['downlink_vlan_iface']['name'], type, "RX")


def test_dhcp_relay_default(ptfhost, dut_dhcp_relay_data, validate_dut_routes_exist, testing_config,
Expand Down

0 comments on commit 5b2aa47

Please sign in to comment.