From c1ad2a6461fc2e767d69567be9647150c3310569 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Sun, 3 May 2020 13:28:11 +0200 Subject: configdict: T2241: get interface name in intf/vlan_from_dict This is needed as later functions depend on it --- src/conf_mode/interfaces-ethernet.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src/conf_mode/interfaces-ethernet.py') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 3ddd394d7..c7f935ca6 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -92,7 +92,6 @@ def get_config(): conf.set_level(cfg_base) eth, disabled = intf_to_dict(conf, default_config_data) - eth['intf'] = ifname # disable ethernet flow control (pause frames) if conf.exists('disable-flow-control'): -- cgit v1.2.3 From be55968dfbe66477bbef4492abc0875c5da5b797 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Fri, 1 May 2020 18:08:14 +0200 Subject: ethernet: T2241: add checks for bridge and bond membership --- src/conf_mode/interfaces-ethernet.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/conf_mode/interfaces-ethernet.py') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index c7f935ca6..cc6a824dc 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -23,6 +23,7 @@ from netifaces import interfaces from vyos.ifconfig import EthernetIf, Section from vyos.ifconfig_vlan import apply_vlan_config, verify_vlan_config from vyos.configdict import list_diff, intf_to_dict, add_to_dict +from vyos.validate import is_member from vyos.config import Config from vyos import ConfigError @@ -53,6 +54,8 @@ default_config_data = { 'ipv6_eui64_prefix_remove': [], 'ipv6_forwarding': 1, 'ipv6_dup_addr_detect': 1, + 'is_bridge_member': False, + 'is_bond_member': False, 'intf': '', 'mac': '', 'mtu': 1500, @@ -113,6 +116,9 @@ def get_config(): if conf.exists('ip proxy-arp-pvlan'): eth['ip_proxy_arp_pvlan'] = 1 + # check if we are a member of any bond + eth['is_bond_member'] = is_member(conf, eth['intf'], 'bonding') + # GRO (generic receive offload) if conf.exists('offload-options generic-receive'): eth['offload_gro'] = conf.return_value('offload-options generic-receive') -- cgit v1.2.3 From 2b002b2b2309942f3ee137e5c2e8427c44038935 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Fri, 1 May 2020 18:11:13 +0200 Subject: ethernet: T2241: make VRF and bond/bridge membership mutually exclusive --- src/conf_mode/interfaces-ethernet.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/conf_mode/interfaces-ethernet.py') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index cc6a824dc..468a9040a 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -167,9 +167,7 @@ def verify(eth): if eth['dhcpv6_prm_only'] and eth['dhcpv6_temporary']: raise ConfigError('DHCPv6 temporary and parameters-only options are mutually exclusive!') - vrf_name = eth['vrf'] - if vrf_name and vrf_name not in interfaces(): - raise ConfigError(f'VRF "{vrf_name}" does not exist') + memberof = eth['is_bridge_member'] if eth['is_bridge_member'] else eth['is_bond_member'] conf = Config() # some options can not be changed when interface is enslaved to a bond @@ -180,6 +178,15 @@ def verify(eth): if eth['address']: raise ConfigError(f"Can not assign address to interface {eth['intf']} which is a member of {bond}") + if eth['vrf']: + if eth['vrf'] not in interfaces(): + raise ConfigError(f'VRF "{eth["vrf"]}" does not exist') + + if memberof: + raise ConfigError(( + f'Interface "{eth["intf"]}" cannot be member of VRF "{eth["vrf"]}" ' + f'and "{memberof}" at the same time!')) + # use common function to verify VLAN configuration verify_vlan_config(eth) return None -- cgit v1.2.3 From 41a2e2f7de7bf281b4233d82d3b43d6039019bc7 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Fri, 1 May 2020 18:12:29 +0200 Subject: ethernet: T2241: make address and bond membership exclusive Bond members should not have any addresses assigned. --- src/conf_mode/interfaces-ethernet.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/conf_mode/interfaces-ethernet.py') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 468a9040a..314e696ca 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -143,6 +143,11 @@ def get_config(): if conf.exists('speed'): eth['speed'] = conf.return_value('speed') + # remove default IPv6 link-local address if member of a bond + if eth['is_bond_member'] and 'fe80::/64' in eth['ipv6_eui64_prefix']: + eth['ipv6_eui64_prefix'].remove('fe80::/64') + eth['ipv6_eui64_prefix_remove'].append('fe80::/64') + add_to_dict(conf, disabled, eth, 'vif', 'vif') add_to_dict(conf, disabled, eth, 'vif-s', 'vif_s') @@ -169,14 +174,13 @@ def verify(eth): memberof = eth['is_bridge_member'] if eth['is_bridge_member'] else eth['is_bond_member'] - conf = Config() - # some options can not be changed when interface is enslaved to a bond - for bond in conf.list_nodes('interfaces bonding'): - if conf.exists('interfaces bonding ' + bond + ' member interface'): - bond_member = conf.return_values('interfaces bonding ' + bond + ' member interface') - if eth['intf'] in bond_member: - if eth['address']: - raise ConfigError(f"Can not assign address to interface {eth['intf']} which is a member of {bond}") + if ( memberof + and ( eth['address'] + or eth['ipv6_eui64_prefix'] + or eth['ipv6_autoconf'] ) ): + raise ConfigError(( + f'Cannot assign address to interface "{eth["intf"]}" ' + f'as it is a member of "{memberof}"!')) if eth['vrf']: if eth['vrf'] not in interfaces(): -- cgit v1.2.3 From ad0448e6e213dd964d44fac450c4a428d035f635 Mon Sep 17 00:00:00 2001 From: Jernej Jakob Date: Fri, 1 May 2020 18:13:59 +0200 Subject: ethernet: T2241: fix falling out of bridge when changing settings Previously, set_vrf was always called, which uses the same master and nomaster commands as bridge, so it removed the interface from the bridge. - add checks to make VRF and bridge membership mutually exclusive - always re-add the interface back to any bridge it is part of --- src/conf_mode/interfaces-ethernet.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/conf_mode/interfaces-ethernet.py') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 314e696ca..9b9ae931c 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -20,7 +20,7 @@ from sys import exit from copy import deepcopy from netifaces import interfaces -from vyos.ifconfig import EthernetIf, Section +from vyos.ifconfig import EthernetIf from vyos.ifconfig_vlan import apply_vlan_config, verify_vlan_config from vyos.configdict import list_diff, intf_to_dict, add_to_dict from vyos.validate import is_member @@ -297,8 +297,14 @@ def apply(eth): for addr in eth['address']: e.add_addr(addr) - # assign/remove VRF - e.set_vrf(eth['vrf']) + # assign/remove VRF (ONLY when not a member of a bridge or bond, + # otherwise 'nomaster' removes it from it) + if not ( eth['is_bridge_member'] or eth['is_bond_member'] ): + e.set_vrf(eth['vrf']) + + # re-add ourselves to any bridge we might have fallen out of + if eth['is_bridge_member']: + e.add_to_bridge(eth['is_bridge_member']) # remove no longer required service VLAN interfaces (vif-s) for vif_s in eth['vif_s_remove']: -- cgit v1.2.3