summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/snmp/etc.snmpd.conf.tmpl2
-rw-r--r--interface-definitions/snmp.xml.in20
-rwxr-xr-xsmoketest/scripts/cli/test_service_snmp.py47
-rwxr-xr-xsrc/conf_mode/snmp.py11
4 files changed, 75 insertions, 5 deletions
diff --git a/data/templates/snmp/etc.snmpd.conf.tmpl b/data/templates/snmp/etc.snmpd.conf.tmpl
index db2114fa1..30806ce8a 100644
--- a/data/templates/snmp/etc.snmpd.conf.tmpl
+++ b/data/templates/snmp/etc.snmpd.conf.tmpl
@@ -39,7 +39,7 @@ SysDescr {{ description }}
{% endif %}
# Listen
-agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},udp:161{% if ipv6_enabled %},udp6:161{% endif %}{% endif %}
+agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},{{protocol}}:161{% if ipv6_enabled %},{{protocol}}6:161{% endif %}{% endif %}
# SNMP communities
{% for c in communities %}
diff --git a/interface-definitions/snmp.xml.in b/interface-definitions/snmp.xml.in
index 3cb736bf7..1efe5e726 100644
--- a/interface-definitions/snmp.xml.in
+++ b/interface-definitions/snmp.xml.in
@@ -129,6 +129,26 @@
<constraintErrorMessage>Location is limited to 255 characters or less</constraintErrorMessage>
</properties>
</leafNode>
+ <leafNode name="protocol">
+ <properties>
+ <help>Listen protocol for SNMP</help>
+ <completionHelp>
+ <list>udp tcp</list>
+ </completionHelp>
+ <valueHelp>
+ <format>udp</format>
+ <description>Listen protocol UDP (default)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>tcp</format>
+ <description>Listen protocol TCP</description>
+ </valueHelp>
+ <constraint>
+ <regex>^(udp|tcp)$</regex>
+ </constraint>
+ </properties>
+ <defaultValue>udp</defaultValue>
+ </leafNode>
<leafNode name="smux-peer">
<properties>
<help>Register a subtree for SMUX-based processing</help>
diff --git a/smoketest/scripts/cli/test_service_snmp.py b/smoketest/scripts/cli/test_service_snmp.py
index 00754e668..864097771 100755
--- a/smoketest/scripts/cli/test_service_snmp.py
+++ b/smoketest/scripts/cli/test_service_snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -94,6 +94,51 @@ class TestSNMPService(VyOSUnitTestSHIM.TestCase):
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(['interfaces', 'dummy', dummy_if])
+ def test_snmp_tcp(self):
+ dummy_if = 'dum123'
+ dummy_addr = '100.64.0.1/32'
+ self.cli_set(['interfaces', 'dummy', dummy_if, 'address', dummy_addr])
+
+ # Check if SNMP can be configured and service runs
+ clients = ['192.0.2.1', '2001:db8::1']
+ networks = ['192.0.2.128/25', '2001:db8:babe::/48']
+ listen = ['127.0.0.1', '::1', address_from_cidr(dummy_addr)]
+ port = '2325'
+
+ for auth in ['ro', 'rw']:
+ community = 'VyOS' + auth
+ self.cli_set(base_path + ['community', community, 'authorization', auth])
+ for client in clients:
+ self.cli_set(base_path + ['community', community, 'client', client])
+ for network in networks:
+ self.cli_set(base_path + ['community', community, 'network', network])
+
+ for addr in listen:
+ self.cli_set(base_path + ['listen-address', addr, 'port', port])
+
+ self.cli_set(base_path + ['contact', 'maintainers@vyos.io'])
+ self.cli_set(base_path + ['location', 'qemu'])
+ self.cli_set(base_path + ['protocol', 'tcp'])
+
+ self.cli_commit()
+
+ # verify listen address, it will be returned as
+ # ['unix:/run/snmpd.socket,tcp:127.0.0.1:161,tcp6:[::1]:161']
+ # thus we need to transfor this into a proper list
+ config = get_config_value('agentaddress')
+ expected = 'unix:/run/snmpd.socket'
+ self.assertIn(expected, config)
+
+ for addr in listen:
+ if is_ipv4(addr):
+ expected = f'tcp:{addr}:{port}'
+ else:
+ expected = f'tcp6:[{addr}]:{port}'
+ self.assertIn(expected, config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+ self.cli_delete(['interfaces', 'dummy', dummy_if])
def test_snmpv3_sha(self):
# Check if SNMPv3 can be configured with SHA authentication
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 6d22d06f1..25ff9d0dd 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -56,6 +56,7 @@ default_config_data = {
'communities': [],
'smux_peers': [],
'location' : '',
+ 'protocol' : 'udp',
'description' : '',
'contact' : '',
'trap_source': '',
@@ -154,6 +155,9 @@ def get_config():
if conf.exists('location'):
snmp['location'] = conf.return_value('location')
+ if conf.exists('protocol'):
+ snmp['protocol'] = conf.return_value('protocol')
+
if conf.exists('smux-peer'):
snmp['smux_peers'] = conf.return_values('smux-peer')
@@ -404,14 +408,15 @@ def verify(snmp):
for listen in snmp['listen_address']:
addr = listen[0]
port = listen[1]
+ protocol = snmp['protocol']
tmp = None
if is_ipv4(addr):
# example: udp:127.0.0.1:161
- tmp = f'udp:{addr}:{port}'
+ tmp = f'{protocol}:{addr}:{port}'
elif snmp['ipv6_enabled']:
# example: udp6:[::1]:161
- tmp = f'udp6:[{addr}]:{port}'
+ tmp = f'{protocol}6:[{addr}]:{port}'
# We only wan't to configure addresses that exist on the system.
# Hint the user if they don't exist