From b40315b3c5051888f499961e63410e14c5d1bad7 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 13 Feb 2022 20:04:33 +0100 Subject: vyos.util: T4191: add new sysctl() helper function --- python/vyos/util.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'python/vyos/util.py') diff --git a/python/vyos/util.py b/python/vyos/util.py index 571d43754..1767ff9d3 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -997,3 +997,12 @@ def boot_configuration_complete() -> bool: if os.path.isfile(config_status): return True return False + +def sysctl(name, value): + """ Change value via sysctl() - return True if changed, False otherwise """ + tmp = cmd(f'sysctl {name}') + # last list index contains the actual value - only write if value differs + if tmp.split()[-1] != str(value): + call(f'sysctl -wq {name}={value}') + return True + return False -- cgit v1.2.3 From c3661c8d5d7e8f5c1d040cadf134e87f0d77e28e Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 21 Feb 2022 18:25:05 +0100 Subject: smoketest: vxlan: T4120: verify support for multiple remote addresses --- python/vyos/util.py | 8 ++++++ smoketest/scripts/cli/test_interfaces_vxlan.py | 34 ++++++++++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'python/vyos/util.py') diff --git a/python/vyos/util.py b/python/vyos/util.py index 1767ff9d3..4526375df 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -774,6 +774,14 @@ def dict_search_recursive(dict_object, key): for x in dict_search_recursive(j, key): yield x +def get_bridge_fdb(interface): + """ Returns the forwarding database entries for a given interface """ + if not os.path.exists(f'/sys/class/net/{interface}'): + return None + from json import loads + tmp = loads(cmd(f'bridge -j fdb show dev {interface}')) + return tmp + def get_interface_config(interface): """ Returns the used encapsulation protocol for given interface. If interface does not exist, None is returned. diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py index 12fc463ba..f34b99ea4 100755 --- a/smoketest/scripts/cli/test_interfaces_vxlan.py +++ b/smoketest/scripts/cli/test_interfaces_vxlan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020-2021 VyOS maintainers and contributors +# Copyright (C) 2020-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 @@ -18,8 +18,9 @@ import unittest from vyos.configsession import ConfigSessionError from vyos.ifconfig import Interface +from vyos.util import get_bridge_fdb from vyos.util import get_interface_config - +from vyos.template import is_ipv6 from base_interfaces_test import BasicInterfaceTest class VXLANInterfaceTest(BasicInterfaceTest.TestCase): @@ -57,21 +58,34 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase): ttl = 20 for interface in self._interfaces: options = get_interface_config(interface) + bridge = get_bridge_fdb(interface) vni = options['linkinfo']['info_data']['id'] self.assertIn(f'vni {vni}', self._options[interface]) - if any('link' in s for s in self._options[interface]): + if any('source-interface' in s for s in self._options[interface]): link = options['linkinfo']['info_data']['link'] self.assertIn(f'source-interface {link}', self._options[interface]) - if any('local6' in s for s in self._options[interface]): - remote = options['linkinfo']['info_data']['local6'] - self.assertIn(f'source-address {local6}', self._options[interface]) - - if any('remote6' in s for s in self._options[interface]): - remote = options['linkinfo']['info_data']['remote6'] - self.assertIn(f'remote {remote}', self._options[interface]) + # Verify source-address setting was properly configured on the Kernel + if any('source-address' in s for s in self._options[interface]): + for s in self._options[interface]: + if 'source-address' in s: + address = s.split()[-1] + if is_ipv6(address): + tmp = options['linkinfo']['info_data']['local6'] + else: + tmp = options['linkinfo']['info_data']['local'] + self.assertIn(f'source-address {tmp}', self._options[interface]) + + # Verify remote setting was properly configured on the Kernel + if any('remote' in s for s in self._options[interface]): + for s in self._options[interface]: + if 'remote' in s: + for fdb in bridge: + if 'mac' in fdb and fdb['mac'] == '00:00:00:00:00:00': + remote = fdb['dst'] + self.assertIn(f'remote {remote}', self._options[interface]) if any('group' in s for s in self._options[interface]): group = options['linkinfo']['info_data']['group'] -- cgit v1.2.3 From 52cb6185a4a51ffa92f10e0ded55a943bc21bc60 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 25 Mar 2022 18:54:44 +0100 Subject: vyos.util: T4319: provide generic sysctl_read() helper --- python/vyos/util.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'python/vyos/util.py') diff --git a/python/vyos/util.py b/python/vyos/util.py index 4526375df..da39ee8d1 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -1006,11 +1006,16 @@ def boot_configuration_complete() -> bool: return True return False +def sysctl_read(name): + """ Read and return current value of sysctl() option """ + tmp = cmd(f'sysctl {name}') + return tmp.split()[-1] + def sysctl(name, value): """ Change value via sysctl() - return True if changed, False otherwise """ tmp = cmd(f'sysctl {name}') # last list index contains the actual value - only write if value differs - if tmp.split()[-1] != str(value): + if sysctl_read(name) != str(value): call(f'sysctl -wq {name}={value}') return True return False -- cgit v1.2.3 From 364009e4317fb5c6732635726b511613aa2ed519 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 25 Mar 2022 19:00:36 +0100 Subject: vyos.util: T4319: rename sysctl() -> sysctl_write() --- python/vyos/util.py | 2 +- src/conf_mode/system-ip.py | 12 ++++++------ src/conf_mode/system-ipv6.py | 12 ++++++------ src/conf_mode/vrf.py | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'python/vyos/util.py') diff --git a/python/vyos/util.py b/python/vyos/util.py index da39ee8d1..f46775490 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -1011,7 +1011,7 @@ def sysctl_read(name): tmp = cmd(f'sysctl {name}') return tmp.split()[-1] -def sysctl(name, value): +def sysctl_write(name, value): """ Change value via sysctl() - return True if changed, False otherwise """ tmp = cmd(f'sysctl {name}') # last list index contains the actual value - only write if value differs diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py index 8b97725ac..05fc3a97a 100755 --- a/src/conf_mode/system-ip.py +++ b/src/conf_mode/system-ip.py @@ -20,7 +20,7 @@ from vyos.config import Config from vyos.configdict import dict_merge from vyos.util import call from vyos.util import dict_search -from vyos.util import sysctl +from vyos.util import sysctl_write from vyos.util import write_file from vyos.xml import defaults from vyos import ConfigError @@ -53,11 +53,11 @@ def apply(opt): # table_size has a default value - thus the key always exists size = int(dict_search('arp.table_size', opt)) # Amount upon reaching which the records begin to be cleared immediately - sysctl('net.ipv4.neigh.default.gc_thresh3', size) + sysctl_write('net.ipv4.neigh.default.gc_thresh3', size) # Amount after which the records begin to be cleaned after 5 seconds - sysctl('net.ipv4.neigh.default.gc_thresh2', size // 2) + sysctl_write('net.ipv4.neigh.default.gc_thresh2', size // 2) # Minimum number of stored records is indicated which is not cleared - sysctl('net.ipv4.neigh.default.gc_thresh1', size // 8) + sysctl_write('net.ipv4.neigh.default.gc_thresh1', size // 8) # enable/disable IPv4 forwarding tmp = dict_search('disable_forwarding', opt) @@ -67,11 +67,11 @@ def apply(opt): # configure multipath tmp = dict_search('multipath.ignore_unreachable_nexthops', opt) value = '1' if (tmp != None) else '0' - sysctl('net.ipv4.fib_multipath_use_neigh', value) + sysctl_write('net.ipv4.fib_multipath_use_neigh', value) tmp = dict_search('multipath.layer4_hashing', opt) value = '1' if (tmp != None) else '0' - sysctl('net.ipv4.fib_multipath_hash_policy', value) + sysctl_write('net.ipv4.fib_multipath_hash_policy', value) if __name__ == '__main__': try: diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py index 8195beaa6..7fb2dd1cf 100755 --- a/src/conf_mode/system-ipv6.py +++ b/src/conf_mode/system-ipv6.py @@ -22,7 +22,7 @@ from vyos.configdict import dict_merge from vyos.configdict import leaf_node_changed from vyos.util import call from vyos.util import dict_search -from vyos.util import sysctl +from vyos.util import sysctl_write from vyos.util import write_file from vyos.xml import defaults from vyos import ConfigError @@ -58,7 +58,7 @@ def apply(opt): # disable IPv6 globally tmp = dict_search('disable', opt) value = '1' if (tmp != None) else '0' - sysctl('net.ipv6.conf.all.disable_ipv6', value) + sysctl_write('net.ipv6.conf.all.disable_ipv6', value) if 'reboot_required' in opt: print('Changing IPv6 disable parameter will only take affect\n' \ @@ -67,17 +67,17 @@ def apply(opt): # configure multipath tmp = dict_search('multipath.layer4_hashing', opt) value = '1' if (tmp != None) else '0' - sysctl('net.ipv6.fib_multipath_hash_policy', value) + sysctl_write('net.ipv6.fib_multipath_hash_policy', value) # Apply ND threshold values # table_size has a default value - thus the key always exists size = int(dict_search('neighbor.table_size', opt)) # Amount upon reaching which the records begin to be cleared immediately - sysctl('net.ipv6.neigh.default.gc_thresh3', size) + sysctl_write('net.ipv6.neigh.default.gc_thresh3', size) # Amount after which the records begin to be cleaned after 5 seconds - sysctl('net.ipv6.neigh.default.gc_thresh2', size // 2) + sysctl_write('net.ipv6.neigh.default.gc_thresh2', size // 2) # Minimum number of stored records is indicated which is not cleared - sysctl('net.ipv6.neigh.default.gc_thresh1', size // 8) + sysctl_write('net.ipv6.neigh.default.gc_thresh1', size // 8) # enable/disable IPv6 forwarding tmp = dict_search('disable_forwarding', opt) diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index cfe0f4d8e..6a521a0dd 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -29,7 +29,7 @@ from vyos.util import dict_search from vyos.util import get_interface_config from vyos.util import popen from vyos.util import run -from vyos.util import sysctl +from vyos.util import sysctl_write from vyos import ConfigError from vyos import frr from vyos import airbag @@ -154,8 +154,8 @@ def apply(vrf): bind_all = '0' if 'bind-to-all' in vrf: bind_all = '1' - sysctl('net.ipv4.tcp_l3mdev_accept', bind_all) - sysctl('net.ipv4.udp_l3mdev_accept', bind_all) + sysctl_write('net.ipv4.tcp_l3mdev_accept', bind_all) + sysctl_write('net.ipv4.udp_l3mdev_accept', bind_all) for tmp in (dict_search('vrf_remove', vrf) or []): if os.path.isdir(f'/sys/class/net/{tmp}'): -- cgit v1.2.3