From f13cc56d665a91ff3fac47df260301afefb1a3a5 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 28 Feb 2021 10:50:06 +0100 Subject: vyos.util: provide single implementation for get_json_iface_options() There had been four implementations of "ip -d -j link show interface" scattered accross the codebase. Those implementations have now been combined into a new helper: vyos.util.get_json_iface_options() --- python/vyos/util.py | 10 ++++++ smoketest/scripts/cli/base_interfaces_test.py | 4 +-- smoketest/scripts/cli/test_interfaces_erspan.py | 13 +++---- smoketest/scripts/cli/test_interfaces_macsec.py | 9 ++--- smoketest/scripts/cli/test_interfaces_tunnel.py | 45 ++++--------------------- src/conf_mode/interfaces-tunnel.py | 16 +++------ 6 files changed, 28 insertions(+), 69 deletions(-) diff --git a/python/vyos/util.py b/python/vyos/util.py index ab5029c92..17a7dda91 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -645,3 +645,13 @@ def dict_search(path, dict): for p in parts[:-1]: c = c.get(p, {}) return c.get(parts[-1], None) + +def get_json_iface_options(interface): + """ Returns the used encapsulation protocol for given interface. + If interface does not exist, None is returned. + """ + if not os.path.exists(f'/sys/class/net/{interface}'): + return None + from json import loads + tmp = loads(cmd(f'ip -d -j link show {interface}'))[0] + return tmp diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 1426e80c2..0c6f43427 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -14,7 +14,6 @@ import os import unittest -import json from binascii import hexlify @@ -30,6 +29,7 @@ from vyos.util import read_file from vyos.util import cmd from vyos.util import dict_search from vyos.util import process_named_running +from vyos.util import get_json_iface_options from vyos.validate import is_intf_addr_assigned from vyos.validate import is_ipv6_link_local @@ -317,7 +317,7 @@ class BasicInterfaceTest: for interface in self._interfaces: for vif_s in self._qinq_range: - tmp = json.loads(cmd(f'ip -d -j link show dev {interface}.{vif_s}'))[0] + tmp = get_json_iface_options(f'{interface}.{vif_s}') self.assertEqual(dict_search('linkinfo.info_data.protocol', tmp), '802.1ad') for vif_c in self._vlan_range: diff --git a/smoketest/scripts/cli/test_interfaces_erspan.py b/smoketest/scripts/cli/test_interfaces_erspan.py index d0814f2fb..cbb41d0c9 100755 --- a/smoketest/scripts/cli/test_interfaces_erspan.py +++ b/smoketest/scripts/cli/test_interfaces_erspan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-2021 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 @@ -15,20 +15,15 @@ # along with this program. If not, see . import unittest -import json from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError -from vyos.util import cmd +from vyos.util import get_json_iface_options from base_interfaces_test import BasicInterfaceTest mtu = 1500 -def erspan_conf(interface): - tmp = cmd(f'ip -d -j link show {interface}') - return json.loads(tmp)[0] - class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest): def setUp(self): super().setUp() @@ -57,7 +52,7 @@ class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.session.commit() - conf = erspan_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(interface, conf['ifname']) self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) self.assertEqual(mtu, conf['mtu']) @@ -78,7 +73,7 @@ class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.session.commit() - conf = erspan_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(interface, conf['ifname']) self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) self.assertEqual(mtu, conf['mtu']) diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py index d6bef993a..2f1898b6f 100755 --- a/smoketest/scripts/cli/test_interfaces_macsec.py +++ b/smoketest/scripts/cli/test_interfaces_macsec.py @@ -25,6 +25,7 @@ from vyos.configsession import ConfigSessionError from vyos.ifconfig import Section from vyos.util import cmd from vyos.util import read_file +from vyos.util import get_json_iface_options from vyos.util import process_named_running def get_config_value(interface, key): @@ -33,13 +34,7 @@ def get_config_value(interface, key): return tmp[0] def get_cipher(interface): - """ Returns the used encapsulation protocol for given interface. - If interface does not exist, None is returned. - """ - if not os.path.exists(f'/sys/class/net/{interface}'): - return None - from json import loads - tmp = loads(cmd(f'ip -d -j link show {interface}'))[0] + tmp = get_json_iface_options(interface) return tmp['linkinfo']['info_data']['cipher_suite'].lower() class MACsecInterfaceTest(BasicInterfaceTest.BaseTest): diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py index cc8fbd527..b5ee3e412 100755 --- a/smoketest/scripts/cli/test_interfaces_tunnel.py +++ b/smoketest/scripts/cli/test_interfaces_tunnel.py @@ -15,11 +15,10 @@ # along with this program. If not, see . import unittest -import json from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError -from vyos.util import cmd +from vyos.util import get_json_iface_options from vyos.template import inc_ip from base_interfaces_test import BasicInterfaceTest @@ -29,38 +28,6 @@ remote_ip6 = '2001:db8::ffff' source_if = 'dum2222' mtu = 1476 -def tunnel_conf(interface): - tmp = cmd(f'ip -d -j link show {interface}') - # {'address': '2.2.2.2', - # 'broadcast': '192.0.2.10', - # 'flags': ['POINTOPOINT', 'NOARP', 'UP', 'LOWER_UP'], - # 'group': 'default', - # 'gso_max_segs': 65535, - # 'gso_max_size': 65536, - # 'ifindex': 10, - # 'ifname': 'tun10', - # 'inet6_addr_gen_mode': 'none', - # 'link': None, - # 'link_pointtopoint': True, - # 'link_type': 'gre', - # 'linkinfo': {'info_data': {'local': '2.2.2.2', - # 'pmtudisc': True, - # 'remote': '192.0.2.10', - # 'tos': '0x1', - # 'ttl': 255}, - # 'info_kind': 'gre'}, - # 'linkmode': 'DEFAULT', - # 'max_mtu': 65511, - # 'min_mtu': 68, - # 'mtu': 1476, - # 'num_rx_queues': 1, - # 'num_tx_queues': 1, - # 'operstate': 'UNKNOWN', - # 'promiscuity': 0, - # 'qdisc': 'noqueue', - # 'txqlen': 1000} - return json.loads(tmp)[0] - class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): @classmethod def setUpClass(cls): @@ -117,7 +84,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() - conf = tunnel_conf(interface) + conf = get_json_iface_options(interface) if encapsulation not in ['sit', 'gretap']: self.assertEqual(source_if, conf['link']) @@ -160,7 +127,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() - conf = tunnel_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(interface, conf['ifname']) self.assertEqual(mtu, conf['mtu']) self.assertEqual(source_if, conf['link']) @@ -218,7 +185,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() - conf = tunnel_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(mtu, conf['mtu']) self.assertEqual(interface, conf['ifname']) self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) @@ -240,7 +207,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() - conf = tunnel_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(mtu, conf['mtu']) self.assertEqual(interface, conf['ifname']) self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) @@ -254,7 +221,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # Check if commit is ok self.session.commit() - conf = tunnel_conf(interface) + conf = get_json_iface_options(interface) self.assertEqual(new_remote, conf['linkinfo']['info_data']['remote']) if __name__ == '__main__': diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 2d2f29f94..0ffff06a1 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -34,22 +34,12 @@ from vyos.ifconfig import Interface from vyos.ifconfig import TunnelIf from vyos.template import is_ipv4 from vyos.template import is_ipv6 -from vyos.util import cmd +from vyos.util import get_json_iface_options from vyos.util import dict_search from vyos import ConfigError from vyos import airbag airbag.enable() -def get_tunnel_encapsulation(interface): - """ Returns the used encapsulation protocol for given interface. - If interface does not exist, None is returned. - """ - if not os.path.exists(f'/sys/class/net/{interface}'): - return None - from json import loads - tmp = loads(cmd(f'ip -d -j link show {interface}'))[0] - return tmp['linkinfo']['info_kind'] - def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least @@ -111,7 +101,9 @@ def apply(tunnel): # If a gretap tunnel is already existing we can not "simply" change local or # remote addresses. This returns "Operation not supported" by the Kernel. # There is no other solution to destroy and recreate the tunnel. - encap = get_tunnel_encapsulation(interface) + encap = '' + tmp = get_json_iface_options(interface) + if tmp: encap = dict_search('linkinfo.info_kind', tmp) if 'deleted' in tunnel or 'encapsulation_changed' in tunnel or encap == 'gretap': if interface in interfaces(): -- cgit v1.2.3