From 90dc2546564611b5897f540ed187afda41b54e23 Mon Sep 17 00:00:00 2001
From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com>
Date: Wed, 6 Dec 2023 13:23:02 -0800
Subject: [PATCH] [SNMP]: Modify minigraph parser to update
SNMP_AGENT_ADDRESS_CONFIG table (#17045)
#### Why I did it
SNMP query over IPv6 does not work due to issue in net-snmp where IPv6 query does not work on multi-nic environment.
To get around this, if snmpd listens on specific ipv4 or ipv6 address, then the issue is not seen.
We plan to configure Management IP and Loopback IP configured in minigraph.xml as SNMP_AGENT_ADDRESS in config_db., based on changes discussed in https://github.com/sonic-net/SONiC/pull/1457.
##### Work item tracking
- Microsoft ADO **(number only)**:26091228
#### How I did it
Modify minigraph parser to update SNMP_AGENT_ADDRESS_CONFIG with management and Loopback0 IP addresses.
Modify snmpd.conf.j2 to use SNMP_AGENT_ADDRESS_CONFIG table if it is present in config_db, if not listen on any IP.
Main change:
1. if minigraph.xml is used to configure the device, then snmpd will listen on mgmt and loopback IP addresses,
2. if config_db is used to configure the device, snmpd will listen IP present in SNMP_AGENT_ADDRESS_CONFIG if that table is present, if table is not present snmpd will listen on any IP.
#### How to verify it
config_db.json created from minigraph.xml for single asic VS image with mgmt and Loopback IP addresses.
```
"SNMP_AGENT_ADDRESS_CONFIG": {
"10.1.0.32|161|": {},
"10.250.0.101|161|": {},
"FC00:1::32|161|": {},
"fec0::ffff:afa:1|161|": {}
},
.....
snmpd listening on the above IP addresses:
admin@vlab-01:~$ sudo netstat -tulnp | grep 161
tcp 0 0 127.0.0.1:3161 0.0.0.0:* LISTEN 71522/snmpd
udp 0 0 10.250.0.101:161 0.0.0.0:* 71522/snmpd
udp 0 0 10.1.0.32:161 0.0.0.0:* 71522/snmpd
udp6 0 0 fec0::ffff:afa:1:161 :::* 71522/snmpd
udp6 0 0 fc00:1::32:161 :::* 71522/snmpd
```
---
dockers/docker-snmp/snmpd.conf.j2 | 26 -------------------
dockers/docker-snmp/start.sh | 3 ---
src/sonic-config-engine/minigraph.py | 16 ++++++++++++
.../tests/sample_graph.xml | 8 ++++++
src/sonic-config-engine/tests/test_cfggen.py | 7 ++++-
5 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/dockers/docker-snmp/snmpd.conf.j2 b/dockers/docker-snmp/snmpd.conf.j2
index 182056b636..aa04901f00 100644
--- a/dockers/docker-snmp/snmpd.conf.j2
+++ b/dockers/docker-snmp/snmpd.conf.j2
@@ -28,32 +28,6 @@
{% for (agentip, port, vrf) in SNMP_AGENT_ADDRESS_CONFIG %}
agentAddress {{ protocol(agentip) }}:[{{ agentip }}]{% if port %}:{{ port }}{% endif %}{% if vrf %}%{{ vrf }}{% endif %}{{ "" }}
{% endfor %}
-{% elif NAMESPACE_COUNT is not defined or NAMESPACE_COUNT|int <= 1 %}
-{% if MGMT_INTERFACE is defined %}
-{% for intf, ip in MGMT_INTERFACE %}
-{% set agentip = ip.split('/')[0]|lower %}
-{% set zoneid = '' %}
-# Use interface as zoneid for link local ipv6
-{% if agentip.startswith('fe80') %}
-{% set zoneid = '%' + intf %}
-{% endif %}
-agentAddress {{ protocol(agentip) }}:[{{ agentip }}{{ zoneid }}]:161
-{% endfor %}
-{% endif %}
-{% if LOOPBACK_INTERFACE is defined %}
-{% for lo in LOOPBACK_INTERFACE %}
-{% if lo | length == 2 %}
-{% set intf = lo[0] %}
-{% set agentip = lo[1].split('/')[0]|lower %}
-{% set zoneid = '' %}
-# Use interface as zoneid for link local ipv6
-{% if agentip.startswith('fe80') %}
-{% set zoneid = '%' + intf %}
-{% endif %}
-agentAddress {{ protocol(agentip) }}:[{{ agentip }}{{ zoneid }}]:161
-{% endif %}
-{% endfor %}
-{% endif %}
{% else %}
agentAddress udp:161
agentAddress udp6:161
diff --git a/dockers/docker-snmp/start.sh b/dockers/docker-snmp/start.sh
index 1d4c3b935a..6de6f740b0 100755
--- a/dockers/docker-snmp/start.sh
+++ b/dockers/docker-snmp/start.sh
@@ -16,14 +16,11 @@ mkdir -p /etc/ssw /etc/snmp
# Parse snmp.yml and insert the data in Config DB
/usr/bin/snmp_yml_to_configdb.py
-ADD_PARAM=$(printf '%s {"NAMESPACE_COUNT":"%s"}' "-a" "$NAMESPACE_COUNT")
-
SONIC_CFGGEN_ARGS=" \
-d \
-y /etc/sonic/sonic_version.yml \
-t /usr/share/sonic/templates/sysDescription.j2,/etc/ssw/sysDescription \
-t /usr/share/sonic/templates/snmpd.conf.j2,/etc/snmp/snmpd.conf \
- $ADD_PARAM \
"
sonic-cfggen $SONIC_CFGGEN_ARGS
diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py
index 1cadd297e5..bd7cb163d4 100644
--- a/src/sonic-config-engine/minigraph.py
+++ b/src/sonic-config-engine/minigraph.py
@@ -16,6 +16,7 @@ from natsort import natsorted, ns as natsortns
from portconfig import get_port_config, get_fabric_port_config, get_fabric_monitor_config
from sonic_py_common.interface import backplane_prefix
+from sonic_py_common.multi_asic import is_multi_asic
# TODO: Remove this once we no longer support Python 2
if sys.version_info.major == 3:
@@ -1730,6 +1731,21 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
results['MGMT_VRF_CONFIG'] = mvrf
+ # Update SNMP_AGENT_ADDRESS_CONFIG with Management IP and Loopback IP
+ # if available.
+ if not is_multi_asic() and asic_name is None:
+ results['SNMP_AGENT_ADDRESS_CONFIG'] = {}
+ port = '161'
+ for mgmt_intf in mgmt_intf.keys():
+ snmp_key = mgmt_intf[1].split('/')[0] + '|' + port + '|'
+ results['SNMP_AGENT_ADDRESS_CONFIG'][snmp_key] = {}
+ # Add Loopback IP as agent address for single asic
+ for loip in lo_intfs.keys():
+ snmp_key = loip[1].split('/')[0] + '|' + port + '|'
+ results['SNMP_AGENT_ADDRESS_CONFIG'][snmp_key] = {}
+ else:
+ results['SNMP_AGENT_ADDRESS_CONFIG'] = {}
+
phyport_intfs = {}
vlan_intfs = {}
pc_intfs = {}
diff --git a/src/sonic-config-engine/tests/sample_graph.xml b/src/sonic-config-engine/tests/sample_graph.xml
index 478fdd5ba8..35247671fa 100644
--- a/src/sonic-config-engine/tests/sample_graph.xml
+++ b/src/sonic-config-engine/tests/sample_graph.xml
@@ -63,6 +63,14 @@
100.0.0.6/32
+
+ HostIP
+ Loopback1
+
+ 100.0.0.7/32
+
+ 100.0.0.7/32
+
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py
index 77c95c4967..b8480cf81f 100644
--- a/src/sonic-config-engine/tests/test_cfggen.py
+++ b/src/sonic-config-engine/tests/test_cfggen.py
@@ -1145,4 +1145,9 @@ class TestCfgGen(TestCase):
)
)
-
+ def testsnmp_agent_address_config(self):
+ argument = ['-m', self.sample_graph, '-p', self.port_config, '-v', 'SNMP_AGENT_ADDRESS_CONFIG.keys()|list']
+ output = self.run_script(argument)
+ self.assertEqual(
+ utils.liststr_to_dict(output.strip()),
+ utils.liststr_to_dict("['192.168.200.15|161|', '100.0.0.6|161|', '100.0.0.7|161|']"))