diff --git a/dockers/docker-snmp/snmpd.conf.j2 b/dockers/docker-snmp/snmpd.conf.j2 index 182056b636e1..855063dad265 100644 --- a/dockers/docker-snmp/snmpd.conf.j2 +++ b/dockers/docker-snmp/snmpd.conf.j2 @@ -13,52 +13,10 @@ # AGENT BEHAVIOUR # -# Listen for connections on all ip addresses, including eth0, ipv4 lo for multi-asic platform -# Listen on managment and loopback0 ips for single asic platform -# -{% macro protocol(ip_addr) %} -{%- if ip_addr|ipv6 -%} -{{ 'udp6' }} -{%- else -%} -{{ 'udp' }} -{%- endif -%} -{% endmacro %} - -{% if SNMP_AGENT_ADDRESS_CONFIG %} -{% 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 %} +# Listen for connections on all ip addresses, including eth0, ipv4 and ipv6 lo +# agentAddress udp:161 agentAddress udp6:161 -{% endif %} - ############################################################################### # # ACCESS CONTROL diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index c64053a4a3c8..75f5fe224ce5 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -486,7 +486,12 @@ start() { {%- endif %} if [ -z "$DEV" ]; then + {%- if docker_container_name == "snmp" %} + NET="bridge" + {%- else %} NET="host" + {%- endif %} + # For Multi-ASIC platform we have to mount the redis paths for database instances running in different # namespaces, into the single instance dockers like snmp, pmon on linux host. These global dockers @@ -526,6 +531,8 @@ start() { {%- if docker_container_name == "database" %} NET="bridge" DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " + {%- elif docker_container_name == "snmp" %} + NET="bridge" {%- else %} NET="container:database$DEV" DB_OPT="" @@ -541,10 +548,45 @@ start() { {%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version +{%- endif %} +{%- if docker_container_name == "snmp" %} +# get snmp listening address and port list from redis +addr_port_values=$(python3 -c 'from swsscommon.swsscommon import ConfigDBConnector; cfg_db = ConfigDBConnector(); cfg_db.connect(wait_for_init=True, retry_on=True); [print(k[0] + "|" + k[1]) for k in cfg_db.get_keys("SNMP_AGENT_ADDRESS_CONFIG|*")]') +NAMESPACE_COUNT=$NUM_ASIC +if [ -z $addr_port_values ]; then +if [ -z $NAMESPACE_COUNT ] || [ $NAMESPACE_COUNT -lt 2 ]; then +addr_port_values=$(python3 -c 'from swsscommon.swsscommon import ConfigDBConnector; cfg_db = ConfigDBConnector(); cfg_db.connect(wait_for_init=True, retry_on=True); [print(k[1].split("/")[0].lower() + "%" + k[0]) if len(k) == 2 and k[1].split('/')[0].lower().startswith("fe80") else print(k[1].split("/")[0].lower()) for k in cfg_db.get_keys("LOOPBACK_INTERFACE|*")+cfg_db.get_keys("MGMT_INTERFACE|*") if len(k) == 2]') +fi +fi +fwd_port_values="" +# Loop over each value in the list +while read -r value; do + # Split the value and port number (if any) + parts=(${value//|/ }) + value="${parts[0]}" + port="${parts[1]:-}" + if [ -z $port ]; then + port=161 + fi + # Check if the value is an IPv4 address + if [ "$fwd_port_values" != "" ]; then + fwd_port_values="$fwd_port_values"$'\n' + fi + if [[ $value =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # IPv4 address, use as is + fwd_port_values="$fwd_port_values$value:$port:161/udp" + else + # Not an IPv4 address, wrap in [] + fwd_port_values="$fwd_port_values[$value]:$port:161/udp" + fi +done <<< "$addr_port_values" + {%- endif %} docker create {{docker_image_run_opt}} \ {%- if docker_container_name != "dhcp_server" %} --net=$NET \ +{%- elif docker_container_name == "snmp" %} + $(echo "$fwd_port_values" | sed 's/^/-p /' | tr '\n' ' ') \ {%- endif %} -e RUNTIME_OWNER=local \ --uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} @@ -660,6 +702,9 @@ stop() { /usr/local/bin/container stop -t 60 $DOCKERNAME {%- else %} /usr/local/bin/container stop $DOCKERNAME + {%- if docker_container_name == "snmp" %} + docker rm $DOCKERNAME + {%- endif %} {%- endif %} }