Skip to content

Commit 2611017

Browse files
SuvarnaMeenakshiAharonMalkin
authored andcommitted
Use device loopback IP address to send SNMP query from neighboring ceos or vsonic (sonic-net#8802)
What is the motivation for this PR? sonic-net/sonic-buildimage#15487 modifies snmpd in SONiC to listen on management and loopback ip by default instead of listening on any IP. test_interop_protocol.py::test_snmp sends a query to the neighbor device using the link ip address. After the above change to listen on management and loopback ip, the snmp query will fail. Hence, modifying the test to send SNMP query to SONiC DUT from neighboring vsonic/eos using Loopback IP of SONiC DUT. How did you do it? Get loopback IPv4 address DUT and use that to query from neighbor device. Added a generic helped function to send SNMP query to DUT from a neighbor.
1 parent f8ed86b commit 2611017

File tree

3 files changed

+73
-47
lines changed

3 files changed

+73
-47
lines changed

tests/common/helpers/snmp_helpers.py

+45
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import logging
2+
import ipaddress
23

34
from tests.common.utilities import wait_until
45
from tests.common.errors import RunAnsibleModuleFail
56
from tests.common.helpers.assertions import pytest_assert
7+
from tests.common.devices.eos import EosHost
68

79
logger = logging.getLogger(__name__)
810

@@ -42,3 +44,46 @@ def get_snmp_facts(localhost, host, version, community, is_dell=False, module_ig
4244
pytest_assert(wait_until(timeout, interval, 0, _update_snmp_facts, localhost, host, version,
4345
community, is_dell, include_swap), "Timeout waiting for SNMP facts")
4446
return global_snmp_facts
47+
48+
49+
def get_snmp_output(ip, duthost, nbr, creds_all_duts, oid='.1.3.6.1.2.1.1.1.0'):
50+
"""
51+
Get snmp output from duthost using specific ip to query
52+
snmp query is sent from neighboring ceos/vsonic
53+
54+
Args:
55+
ip(str): IP of dut to be used to send SNMP query
56+
duthost: duthost
57+
nbr: from where the snmp query should be executed
58+
creds_all_duts: creds to get snmp_rocommunity of duthost
59+
oid: to query
60+
61+
Returns:
62+
SNMP result
63+
"""
64+
ipaddr = ipaddress.ip_address(ip)
65+
iptables_cmd = "iptables"
66+
67+
# TODO : Fix snmp query over loopback v6 and remove this check and add IPv6 ACL table/rule.
68+
if isinstance(ipaddr, ipaddress.IPv6Address):
69+
iptables_cmd = "ip6tables"
70+
return None
71+
72+
ip_tbl_rule_add = "sudo {} -I INPUT 1 -p udp --dport 161 -d {} -j ACCEPT".format(
73+
iptables_cmd, ip)
74+
duthost.shell(ip_tbl_rule_add)
75+
76+
if isinstance(nbr["host"], EosHost):
77+
eos_snmpget = "bash snmpget -v2c -c {} {} {}".format(
78+
creds_all_duts[duthost.hostname]['snmp_rocommunity'], ip, oid)
79+
out = nbr['host'].eos_command(commands=[eos_snmpget])
80+
else:
81+
command = "docker exec snmp snmpwalk -v 2c -c {} {} {}".format(
82+
creds_all_duts[duthost.hostname]['snmp_rocommunity'], ip, oid)
83+
out = nbr['host'].command(command)
84+
85+
ip_tbl_rule_del = "sudo {} -D INPUT -p udp --dport 161 -d {} -j ACCEPT".format(
86+
iptables_cmd, ip)
87+
duthost.shell(ip_tbl_rule_del)
88+
89+
return out

tests/macsec/test_interop_protocol.py

+19-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import pytest
22
import logging
3-
import re
3+
import ipaddress
44

55
from tests.common.utilities import wait_until
6-
from tests.common.devices.eos import EosHost
76
from .macsec_helper import getns_prefix
87
from .macsec_config_helper import disable_macsec_port, enable_macsec_port
98
from .macsec_platform_helper import find_portchannel_from_member, get_portchannel, get_lldp_list, sonic_db_cli
9+
from tests.common.helpers.snmp_helpers import get_snmp_output
1010

1111
logger = logging.getLogger(__name__)
1212

@@ -119,24 +119,28 @@ def check_bgp_established(ctrl_port, up_link):
119119
assert wait_until(BGP_TIMEOUT, BGP_KEEPALIVE, BGP_HOLDTIME,
120120
check_bgp_established, ctrl_port, upstream_links[ctrl_port])
121121

122-
def test_snmp(self, duthost, ctrl_links, upstream_links, creds, wait_mka_establish):
122+
def test_snmp(self, duthost, ctrl_links, upstream_links, creds_all_duts, wait_mka_establish):
123123
'''
124124
Verify SNMP request/response works across interface with macsec configuration
125125
'''
126126
if duthost.is_multi_asic:
127127
pytest.skip("The test is for Single ASIC devices")
128128

129+
loopback0_ips = duthost.config_facts(host=duthost.hostname,
130+
source="running")[
131+
"ansible_facts"].get(
132+
"LOOPBACK_INTERFACE",
133+
{}).get('Loopback0', {})
134+
for ip in loopback0_ips:
135+
if isinstance(ipaddress.ip_network(ip),
136+
ipaddress.IPv4Network):
137+
dut_loip = ip.split('/')[0]
138+
break
139+
else:
140+
pytest.fail("No Loopback0 IPv4 address for {}".
141+
format(duthost.hostname))
129142
for ctrl_port, nbr in list(ctrl_links.items()):
130-
if isinstance(nbr["host"], EosHost):
131-
result = nbr["host"].eos_command(
132-
commands=['show snmp community | include name'])
133-
community = re.search(r'Community name: (\S+)',
134-
result['stdout'][0]).groups()[0]
135-
else: # vsonic neighbour
136-
community = creds['snmp_rocommunity']
137-
138-
up_link = upstream_links[ctrl_port]
139143
sysDescr = ".1.3.6.1.2.1.1.1.0"
140-
command = "docker exec snmp snmpwalk -v 2c -c {} {} {}".format(
141-
community, up_link["local_ipv4_addr"], sysDescr)
142-
assert not duthost.command(command)["failed"]
144+
result = get_snmp_output(dut_loip, duthost, nbr,
145+
creds_all_duts, sysDescr)
146+
assert not result["failed"]

tests/snmp/test_snmp_loopback.py

+9-32
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,14 @@
11
import pytest
22
import ipaddress
3-
from tests.common.helpers.snmp_helpers import get_snmp_facts
4-
try: # python3
5-
from shlex import quote
6-
except ImportError: # python2
7-
from pipes import quote
3+
from tests.common.helpers.snmp_helpers import get_snmp_facts, get_snmp_output
4+
from tests.common.devices.eos import EosHost
85

96
pytestmark = [
107
pytest.mark.topology('t0', 't1', 't2', 'm0', 'mx'),
118
pytest.mark.device_type('vs')
129
]
1310

1411

15-
def get_snmp_output(ip, duthost, nbr, creds_all_duts):
16-
ipaddr = ipaddress.ip_address(ip)
17-
iptables_cmd = "iptables"
18-
19-
# TODO : Fix snmp query over loopback v6 and remove this check and add IPv6 ACL table/rule.
20-
if isinstance(ipaddr, ipaddress.IPv6Address):
21-
iptables_cmd = "ip6tables"
22-
return None
23-
24-
ip_tbl_rule_add = "sudo {} -I INPUT 1 -p udp --dport 161 -d {} -j ACCEPT".format(
25-
iptables_cmd, ip)
26-
duthost.shell(ip_tbl_rule_add)
27-
28-
eos_snmpget = "bash snmpget -v2c -c {} {} 1.3.6.1.2.1.1.1.0".format(
29-
quote(creds_all_duts[duthost.hostname]['snmp_rocommunity']), ip)
30-
out = nbr['host'].eos_command(commands=[eos_snmpget])
31-
32-
ip_tbl_rule_del = "sudo {} -D INPUT -p udp --dport 161 -d {} -j ACCEPT".format(
33-
iptables_cmd, ip)
34-
duthost.shell(ip_tbl_rule_del)
35-
36-
return out
37-
38-
3912
@pytest.mark.bsl
4013
def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname,
4114
nbrhosts, tbinfo, localhost, creds_all_duts):
@@ -67,7 +40,11 @@ def test_snmp_loopback(duthosts, enum_rand_one_per_hwsku_frontend_hostname,
6740
result = get_snmp_output(loip, duthost, nbr, creds_all_duts)
6841
assert result is not None, 'No result from snmpget'
6942
assert len(result['stdout_lines']) > 0, 'No result from snmpget'
70-
assert "SONiC Software Version" in result['stdout_lines'][0][0],\
43+
if isinstance(nbr["host"], EosHost):
44+
stdout_lines = result['stdout_lines'][0][0]
45+
else:
46+
stdout_lines = result['stdout_lines'][0]
47+
assert "SONiC Software Version" in stdout_lines,\
7148
"Sysdescr not found in SNMP result from IP {}".format(ip)
72-
assert snmp_facts['ansible_sysdescr'] in result['stdout_lines'][0][
73-
0], "Sysdescr from IP{} not matching with result from Mgmt IPv4.".format(ip)
49+
assert snmp_facts['ansible_sysdescr'] in stdout_lines,\
50+
"Sysdescr from IP{} not matching with result from Mgmt IPv4.".format(ip)

0 commit comments

Comments
 (0)