From a610e328750e3cfc23c29a2cafb40d7ef7082b13 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 7 Sep 2019 12:29:12 +0200 Subject: ethernet: T1637: initial rewrite in XML/Python style --- src/conf_mode/interface-ethernet.py | 298 ++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100755 src/conf_mode/interface-ethernet.py (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py new file mode 100755 index 000000000..4aed13a62 --- /dev/null +++ b/src/conf_mode/interface-ethernet.py @@ -0,0 +1,298 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os + +from copy import deepcopy +from sys import exit + +from vyos.ifconfig import EthernetIf, VLANIf +from vyos.configdict import list_diff, vlan_to_dict +from vyos.config import Config +from vyos import ConfigError + +default_config_data = { + 'address': [], + 'address_remove': [], + 'description': '', + 'deleted': False, + 'dhcp_client_id': '', + 'dhcp_hostname': '', + 'dhcpv6_prm_only': False, + 'dhcpv6_temporary': False, + 'disable': False, + 'disable_link_detect': 1, + 'hw_id': '', + 'ip_arp_cache_tmo': 30, + 'ip_proxy_arp': 0, + 'ip_proxy_arp_pvlan': 0, + 'intf': '', + 'mac': '', + 'mtu': 1500, + 'vif_s': [], + 'vif_s_remove': [], + 'vif': [], + 'vif_remove': [] +} + + +def apply_vlan_config(vlan, config): + """ + Generic function to apply a VLAN configuration from a dictionary + to a VLAN interface + """ + + if type(vlan) != type(VLANIf("lo")): + raise TypeError() + + # update interface description used e.g. within SNMP + vlan.ifalias = config['description'] + # ignore link state changes + vlan.link_detect = config['disable_link_detect'] + # Maximum Transmission Unit (MTU) + vlan.mtu = config['mtu'] + # Change VLAN interface MAC address + if config['mac']: + vlan.mac = config['mac'] + + # enable/disable VLAN interface + if config['disable']: + vlan.state = 'down' + else: + vlan.state = 'up' + + # Configure interface address(es) + # - not longer required addresses get removed first + # - newly addresses will be added second + for addr in config['address_remove']: + vlan.del_addr(addr) + for addr in config['address']: + vlan.add_addr(addr) + + +def get_config(): + eth = deepcopy(default_config_data) + conf = Config() + + # determine tagNode instance + try: + eth['intf'] = os.environ['VYOS_TAGNODE_VALUE'] + except KeyError as E: + print("Interface not specified") + + # check if ethernet interface has been removed + cfg_base = 'interfaces ethernet ' + eth['intf'] + if not conf.exists(cfg_base): + eth['deleted'] = True + # we can not bail out early as ethernet interface can not be removed + # Kernel will complain with: RTNETLINK answers: Operation not supported. + # Thus we need to remove individual settings + return eth + + # set new configuration level + conf.set_level(cfg_base) + + # retrieve configured interface addresses + if conf.exists('address'): + eth['address'] = conf.return_values('address') + + # get interface addresses (currently effective) - to determine which + # address is no longer valid and needs to be removed + eff_addr = conf.return_effective_values('address') + eth['address_remove'] = list_diff(eff_addr, eth['address']) + + # retrieve interface description + if conf.exists('description'): + eth['description'] = conf.return_value('description') + else: + eth['description'] = eth['intf'] + + # get DHCP client identifier + if conf.exists('dhcp-options client-id'): + eth['dhcp_client_id'] = conf.return_value('dhcp-options client-id') + + # DHCP client host name (overrides the system host name) + if conf.exists('dhcp-options host-name'): + eth['dhcp_hostname'] = conf.return_value('dhcp-options host-name') + + # DHCPv6 only acquire config parameters, no address + if conf.exists('dhcpv6-options parameters-only'): + eth['dhcpv6_prm_only'] = conf.return_value('dhcpv6-options parameters-only') + + # DHCPv6 temporary IPv6 address + if conf.exists('dhcpv6-options temporary'): + eth['dhcpv6_temporary'] = conf.return_value('dhcpv6-options temporary') + + # ignore link state changes + if conf.exists('disable-link-detect'): + eth['disable_link_detect'] = 2 + + # disable interface + if conf.exists('disable'): + eth['disable'] = True + + # ARP cache entry timeout in seconds + if conf.exists('ip arp-cache-timeout'): + eth['ip_arp_cache_tmo'] = int(conf.return_value('ip arp-cache-timeout')) + + # Enable proxy-arp on this interface + if conf.exists('ip enable-proxy-arp'): + eth['ip_proxy_arp'] = 1 + + # Enable private VLAN proxy ARP on this interface + if conf.exists('ip proxy-arp-pvlan'): + eth['ip_proxy_arp_pvlan'] = 1 + + # Media Access Control (MAC) address + if conf.exists('mac'): + eth['mac'] = conf.return_value('mac') + + # Maximum Transmission Unit (MTU) + if conf.exists('mtu'): + eth['mtu'] = int(conf.return_value('mtu')) + + # re-set configuration level and retrieve vif-s interfaces + conf.set_level(cfg_base) + # get vif-s interfaces (currently effective) - to determine which vif-s + # interface is no longer present and needs to be removed + eff_intf = conf.list_effective_nodes('vif-s') + act_intf = conf.list_nodes('vif-s') + eth['vif_s_remove'] = list_diff(eff_intf, act_intf) + + if conf.exists('vif-s'): + for vif_s in conf.list_nodes('vif-s'): + # set config level to vif-s interface + conf.set_level(cfg_base + ' vif-s ' + vif_s) + eth['vif_s'].append(vlan_to_dict(conf)) + + # re-set configuration level and retrieve vif-s interfaces + conf.set_level(cfg_base) + # Determine vif interfaces (currently effective) - to determine which + # vif interface is no longer present and needs to be removed + eff_intf = conf.list_effective_nodes('vif') + act_intf = conf.list_nodes('vif') + eth['vif_remove'] = list_diff(eff_intf, act_intf) + + if conf.exists('vif'): + for vif in conf.list_nodes('vif'): + # set config level to vif interface + conf.set_level(cfg_base + ' vif ' + vif) + eth['vif'].append(vlan_to_dict(conf)) + + return eth + + +def verify(eth): + 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'): + if eth['name'] in conf.return_values('interfaces bonding ' + bond + ' member interface'): + if eth['disable']: + raise ConfigError('Can not disable interface {} which is a member of {}').format(eth['intf'], bond) + + if eth['address']: + raise ConfigError('Can not assign address to interface {} which is a member of {}').format(eth['intf'], bond) + + + return None + + +def generate(eth): + import pprint + pprint.pprint(eth) + return None + + +def apply(eth): + e = EthernetIf(eth['intf']) + # update interface description used e.g. within SNMP + e.ifalias = eth['description'] + + # + # missing DHCP/DHCPv6 options go here + # + + # ignore link state changes + e.link_detect = eth['disable_link_detect'] + # configure ARP cache timeout in milliseconds + e.arp_cache_tmp = eth['ip_arp_cache_tmo'] + # Enable proxy-arp on this interface + e.proxy_arp = eth['ip_proxy_arp'] + # Enable private VLAN proxy ARP on this interface + e.proxy_arp_pvlan = eth['ip_proxy_arp_pvlan'] + + # Change interface MAC address + if eth['mac']: + e.mac = eth['mac'] + + # Maximum Transmission Unit (MTU) + e.mtu = eth['mtu'] + + # Configure interface address(es) + # - not longer required addresses get removed first + # - newly addresses will be added second + for addr in eth['address_remove']: + e.del_addr(addr) + for addr in eth['address']: + e.add_addr(addr) + + # Enable/Disable interface + if eth['disable']: + e.state = 'down' + else: + e.state = 'up' + + # remove no longer required service VLAN interfaces (vif-s) + for vif_s in eth['vif_s_remove']: + e.del_vlan(vif_s) + + # create service VLAN interfaces (vif-s) + for vif_s in eth['vif_s']: + s_vlan = e.add_vlan(vif_s['id'], ethertype=vif_s['ethertype']) + apply_vlan_config(s_vlan, vif_s) + + # remove no longer required client VLAN interfaces (vif-c) + # on lower service VLAN interface + for vif_c in vif_s['vif_c_remove']: + s_vlan.del_vlan(vif_c) + + # create client VLAN interfaces (vif-c) + # on lower service VLAN interface + for vif_c in vif_s['vif_c']: + c_vlan = s_vlan.add_vlan(vif_c['id']) + apply_vlan_config(c_vlan, vif_c) + + # remove no longer required VLAN interfaces (vif) + for vif in eth['vif_remove']: + e.del_vlan(vif) + + # create VLAN interfaces (vif) + for vif in eth['vif']: + vlan = e.add_vlan(vif['id']) + apply_vlan_config(vlan, vif) + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + exit(1) -- cgit v1.2.3 From f8d6ba647e0ef4f1c18302bfb4bebb040f2df95c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 8 Sep 2019 18:49:42 +0200 Subject: ethernet: T1637: support VLAN {ingress,egress}-qos-mapping --- src/conf_mode/interface-ethernet.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 4aed13a62..c20e551d6 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -282,7 +282,12 @@ def apply(eth): # create VLAN interfaces (vif) for vif in eth['vif']: - vlan = e.add_vlan(vif['id']) + # QoS priority mapping can only be set during interface creation + # so we delete the interface first if required. + if vif['egress_qos_changed'] or vif['ingress_qos_changed']: + e.del_vlan(vif['id']) + + vlan = e.add_vlan(vif['id'], ingress_qos=vif['ingress_qos'], egress_qos=vif['egress_qos']) apply_vlan_config(vlan, vif) return None -- cgit v1.2.3 From 735a7d663c279e25feadcfad79e17be7fc0d8c8f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 8 Sep 2019 19:53:49 +0200 Subject: ethernet: T1637: reset MAC address to read hw-id on removal --- src/conf_mode/interface-ethernet.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index c20e551d6..83459cedb 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -140,6 +140,10 @@ def get_config(): if conf.exists('disable-link-detect'): eth['disable_link_detect'] = 2 + # retrieve real hardware address + if conf.exists('hw-id'): + eth['hw_id'] = conf.return_value('hw-id') + # disable interface if conf.exists('disable'): eth['disable'] = True @@ -235,9 +239,12 @@ def apply(eth): # Enable private VLAN proxy ARP on this interface e.proxy_arp_pvlan = eth['ip_proxy_arp_pvlan'] - # Change interface MAC address + # Change interface MAC address - re-set to real hardware address (hw-id) + # if custom mac is removed if eth['mac']: e.mac = eth['mac'] + else: + e.mac = eth['hw_id'] # Maximum Transmission Unit (MTU) e.mtu = eth['mtu'] -- cgit v1.2.3 From ca9964099fe67128bd380fb6026f1631ccd89f11 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 8 Sep 2019 19:54:21 +0200 Subject: ethernet: T1637: support changing flow-control --- src/conf_mode/interface-ethernet.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 83459cedb..a12980bfe 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -35,6 +35,7 @@ default_config_data = { 'dhcpv6_temporary': False, 'disable': False, 'disable_link_detect': 1, + 'flow_control': 'on', 'hw_id': '', 'ip_arp_cache_tmo': 30, 'ip_proxy_arp': 0, @@ -140,6 +141,10 @@ def get_config(): if conf.exists('disable-link-detect'): eth['disable_link_detect'] = 2 + # disable ethernet flow control (pause frames) + if conf.exists('disable-flow-control'): + eth['flow_control'] = 'off' + # retrieve real hardware address if conf.exists('hw-id'): eth['hw_id'] = conf.return_value('hw-id') @@ -232,6 +237,8 @@ def apply(eth): # ignore link state changes e.link_detect = eth['disable_link_detect'] + # disable ethernet flow control (pause frames) + e.set_flow_control(eth['flow_control']) # configure ARP cache timeout in milliseconds e.arp_cache_tmp = eth['ip_arp_cache_tmo'] # Enable proxy-arp on this interface -- cgit v1.2.3 From 1d2bec57085303420b3e12dc61a44edd62c4c490 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 10 Sep 2019 21:40:10 +0200 Subject: ethernet: T1637: handle VLAN interface exception on system startup On system bootup the above condition is true but the interface does not exists, which throws an exception, but that's legal. Simply pass the exception! With this change VyOS boots up and configures ethernet VLAN interfaces as expected. --- src/conf_mode/interface-ethernet.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index a12980bfe..3091e0717 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -299,7 +299,12 @@ def apply(eth): # QoS priority mapping can only be set during interface creation # so we delete the interface first if required. if vif['egress_qos_changed'] or vif['ingress_qos_changed']: - e.del_vlan(vif['id']) + try: + # on system bootup the above condition is true but the interface + # does not exists, which throws an exception, but that's legal + e.del_vlan(vif['id']) + except: + pass vlan = e.add_vlan(vif['id'], ingress_qos=vif['ingress_qos'], egress_qos=vif['egress_qos']) apply_vlan_config(vlan, vif) -- cgit v1.2.3 From fc7685dcbb47a4f80a3e554efa8f60799009151b Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 13 Sep 2019 16:36:30 +0200 Subject: ethernet: T1637: change speed and duplex settings --- src/conf_mode/interface-ethernet.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 3091e0717..30e7c4b1f 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -35,6 +35,7 @@ default_config_data = { 'dhcpv6_temporary': False, 'disable': False, 'disable_link_detect': 1, + 'duplex': 'auto', 'flow_control': 'on', 'hw_id': '', 'ip_arp_cache_tmo': 30, @@ -43,6 +44,7 @@ default_config_data = { 'intf': '', 'mac': '', 'mtu': 1500, + 'speed': 'auto', 'vif_s': [], 'vif_s_remove': [], 'vif': [], @@ -153,6 +155,10 @@ def get_config(): if conf.exists('disable'): eth['disable'] = True + # interface duplex + if conf.exists('duplex'): + eth['duplex'] = conf.return_value('duplex') + # ARP cache entry timeout in seconds if conf.exists('ip arp-cache-timeout'): eth['ip_arp_cache_tmo'] = int(conf.return_value('ip arp-cache-timeout')) @@ -173,6 +179,10 @@ def get_config(): if conf.exists('mtu'): eth['mtu'] = int(conf.return_value('mtu')) + # interface speed + if conf.exists('speed'): + eth['speed'] = conf.return_value('speed') + # re-set configuration level and retrieve vif-s interfaces conf.set_level(cfg_base) # get vif-s interfaces (currently effective) - to determine which vif-s @@ -205,6 +215,14 @@ def get_config(): def verify(eth): + if eth['speed'] == 'auto': + if eth['duplex'] != 'auto': + raise ConfigError('If speed is hardcoded, duplex must be hardcoded, too') + + if eth['duplex'] == 'auto': + if eth['speed'] != 'auto': + raise ConfigError('If duplex is hardcoded, speed must be hardcoded, too') + conf = Config() # some options can not be changed when interface is enslaved to a bond for bond in conf.list_nodes('interfaces bonding'): @@ -256,6 +274,9 @@ def apply(eth): # Maximum Transmission Unit (MTU) e.mtu = eth['mtu'] + # Set physical interface speed and duplex + e.set_speed_duplex(eth['speed'], eth['duplex']) + # Configure interface address(es) # - not longer required addresses get removed first # - newly addresses will be added second -- cgit v1.2.3 From f56b4e190e741bdb2d19d14f2b7004fedc76951c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 15 Sep 2019 15:33:33 +0200 Subject: ethernet: T1637: remove debug pprint --- src/conf_mode/interface-ethernet.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 30e7c4b1f..5bfe35767 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -237,13 +237,9 @@ def verify(eth): return None - def generate(eth): - import pprint - pprint.pprint(eth) return None - def apply(eth): e = EthernetIf(eth['intf']) # update interface description used e.g. within SNMP -- cgit v1.2.3 From 738b62f0fb410daf1dbe97ad8aed9d862b44ec94 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 15 Sep 2019 15:35:27 +0200 Subject: ethernet: T1637: call remove() on interface deletion --- python/vyos/ifconfig.py | 2 +- src/conf_mode/interface-ethernet.py | 171 +++++++++++++++++++----------------- 2 files changed, 90 insertions(+), 83 deletions(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 980577965..c0d1660d1 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -130,7 +130,7 @@ class Interface: self._del_dhcpv6() # Ethernet interfaces can not be removed - if type(self) == type(EthernetIf): + if type(self) == type(EthernetIf(self._ifname)): return # NOTE (Improvement): diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 5bfe35767..3faaef96f 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -215,6 +215,9 @@ def get_config(): def verify(eth): + if eth['deleted']: + return None + if eth['speed'] == 'auto': if eth['duplex'] != 'auto': raise ConfigError('If speed is hardcoded, duplex must be hardcoded, too') @@ -242,89 +245,93 @@ def generate(eth): def apply(eth): e = EthernetIf(eth['intf']) - # update interface description used e.g. within SNMP - e.ifalias = eth['description'] - - # - # missing DHCP/DHCPv6 options go here - # - - # ignore link state changes - e.link_detect = eth['disable_link_detect'] - # disable ethernet flow control (pause frames) - e.set_flow_control(eth['flow_control']) - # configure ARP cache timeout in milliseconds - e.arp_cache_tmp = eth['ip_arp_cache_tmo'] - # Enable proxy-arp on this interface - e.proxy_arp = eth['ip_proxy_arp'] - # Enable private VLAN proxy ARP on this interface - e.proxy_arp_pvlan = eth['ip_proxy_arp_pvlan'] - - # Change interface MAC address - re-set to real hardware address (hw-id) - # if custom mac is removed - if eth['mac']: - e.mac = eth['mac'] - else: - e.mac = eth['hw_id'] - - # Maximum Transmission Unit (MTU) - e.mtu = eth['mtu'] - - # Set physical interface speed and duplex - e.set_speed_duplex(eth['speed'], eth['duplex']) - - # Configure interface address(es) - # - not longer required addresses get removed first - # - newly addresses will be added second - for addr in eth['address_remove']: - e.del_addr(addr) - for addr in eth['address']: - e.add_addr(addr) - - # Enable/Disable interface - if eth['disable']: - e.state = 'down' + if eth['deleted']: + # delete interface + e.remove() else: - e.state = 'up' - - # remove no longer required service VLAN interfaces (vif-s) - for vif_s in eth['vif_s_remove']: - e.del_vlan(vif_s) - - # create service VLAN interfaces (vif-s) - for vif_s in eth['vif_s']: - s_vlan = e.add_vlan(vif_s['id'], ethertype=vif_s['ethertype']) - apply_vlan_config(s_vlan, vif_s) - - # remove no longer required client VLAN interfaces (vif-c) - # on lower service VLAN interface - for vif_c in vif_s['vif_c_remove']: - s_vlan.del_vlan(vif_c) - - # create client VLAN interfaces (vif-c) - # on lower service VLAN interface - for vif_c in vif_s['vif_c']: - c_vlan = s_vlan.add_vlan(vif_c['id']) - apply_vlan_config(c_vlan, vif_c) - - # remove no longer required VLAN interfaces (vif) - for vif in eth['vif_remove']: - e.del_vlan(vif) - - # create VLAN interfaces (vif) - for vif in eth['vif']: - # QoS priority mapping can only be set during interface creation - # so we delete the interface first if required. - if vif['egress_qos_changed'] or vif['ingress_qos_changed']: - try: - # on system bootup the above condition is true but the interface - # does not exists, which throws an exception, but that's legal - e.del_vlan(vif['id']) - except: - pass - - vlan = e.add_vlan(vif['id'], ingress_qos=vif['ingress_qos'], egress_qos=vif['egress_qos']) - apply_vlan_config(vlan, vif) + # update interface description used e.g. within SNMP + e.ifalias = eth['description'] + + # + # missing DHCP/DHCPv6 options go here + # + + # ignore link state changes + e.link_detect = eth['disable_link_detect'] + # disable ethernet flow control (pause frames) + e.set_flow_control(eth['flow_control']) + # configure ARP cache timeout in milliseconds + e.arp_cache_tmp = eth['ip_arp_cache_tmo'] + # Enable proxy-arp on this interface + e.proxy_arp = eth['ip_proxy_arp'] + # Enable private VLAN proxy ARP on this interface + e.proxy_arp_pvlan = eth['ip_proxy_arp_pvlan'] + + # Change interface MAC address - re-set to real hardware address (hw-id) + # if custom mac is removed + if eth['mac']: + e.mac = eth['mac'] + else: + e.mac = eth['hw_id'] + + # Maximum Transmission Unit (MTU) + e.mtu = eth['mtu'] + + # Set physical interface speed and duplex + e.set_speed_duplex(eth['speed'], eth['duplex']) + + # Configure interface address(es) + # - not longer required addresses get removed first + # - newly addresses will be added second + for addr in eth['address_remove']: + e.del_addr(addr) + for addr in eth['address']: + e.add_addr(addr) + + # Enable/Disable interface + if eth['disable']: + e.state = 'down' + else: + e.state = 'up' + + # remove no longer required service VLAN interfaces (vif-s) + for vif_s in eth['vif_s_remove']: + e.del_vlan(vif_s) + + # create service VLAN interfaces (vif-s) + for vif_s in eth['vif_s']: + s_vlan = e.add_vlan(vif_s['id'], ethertype=vif_s['ethertype']) + apply_vlan_config(s_vlan, vif_s) + + # remove no longer required client VLAN interfaces (vif-c) + # on lower service VLAN interface + for vif_c in vif_s['vif_c_remove']: + s_vlan.del_vlan(vif_c) + + # create client VLAN interfaces (vif-c) + # on lower service VLAN interface + for vif_c in vif_s['vif_c']: + c_vlan = s_vlan.add_vlan(vif_c['id']) + apply_vlan_config(c_vlan, vif_c) + + # remove no longer required VLAN interfaces (vif) + for vif in eth['vif_remove']: + e.del_vlan(vif) + + # create VLAN interfaces (vif) + for vif in eth['vif']: + # QoS priority mapping can only be set during interface creation + # so we delete the interface first if required. + if vif['egress_qos_changed'] or vif['ingress_qos_changed']: + try: + # on system bootup the above condition is true but the interface + # does not exists, which throws an exception, but that's legal + e.del_vlan(vif['id']) + except: + pass + + vlan = e.add_vlan(vif['id'], ingress_qos=vif['ingress_qos'], egress_qos=vif['egress_qos']) + apply_vlan_config(vlan, vif) return None -- cgit v1.2.3 From 63a9d416092e24da02f7d180f4feb6a98bfe85f6 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 15 Sep 2019 16:41:05 +0200 Subject: ethernet: T1637: support offloading functions --- src/conf_mode/interface-ethernet.py | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 3faaef96f..72eaee905 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -44,6 +44,11 @@ default_config_data = { 'intf': '', 'mac': '', 'mtu': 1500, + 'offload_gro': 'off', + 'offload_gso': 'off', + 'offload_sg': 'off', + 'offload_tso': 'off', + 'offload_ufo': 'off', 'speed': 'auto', 'vif_s': [], 'vif_s_remove': [], @@ -179,6 +184,26 @@ def get_config(): if conf.exists('mtu'): eth['mtu'] = int(conf.return_value('mtu')) + # GRO (generic receive offload) + if conf.exists('offload-options generic-receive'): + eth['offload_gro'] = conf.return_value('offload-options generic-receive') + + # GSO (generic segmentation offload) + if conf.exists('offload-options generic-segmentation'): + eth['offload_gso'] = conf.return_value('offload-options generic-segmentation') + + # scatter-gather option + if conf.exists('offload-options scatter-gather'): + eth['offload_sg'] = conf.return_value('offload-options scatter-gather') + + # TSO (TCP segmentation offloading) + if conf.exists('offload-options tcp-segmentation'): + eth['offload_tso'] = conf.return_value('offload-options tcp-segmentation') + + # UDP fragmentation offloading + if conf.exists('offload-options udp-fragmentation'): + eth['offload_ufo'] = conf.return_value('offload-options udp-fragmentation') + # interface speed if conf.exists('speed'): eth['speed'] = conf.return_value('speed') @@ -277,6 +302,21 @@ def apply(eth): # Maximum Transmission Unit (MTU) e.mtu = eth['mtu'] + # GRO (generic receive offload) + e.set_gro(eth['offload_gro']) + + # GSO (generic segmentation offload) + e.set_gso(eth['offload_gso']) + + # scatter-gather option + e.set_sg(eth['offload_sg']) + + # TSO (TCP segmentation offloading) + e.set_tso(eth['offload_tso']) + + # UDP fragmentation offloading + e.set_ufo(eth['offload_ufo']) + # Set physical interface speed and duplex e.set_speed_duplex(eth['speed'], eth['duplex']) -- cgit v1.2.3 From 95b88584fd9239d3143adc6b7935544df208ac88 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 15 Sep 2019 19:30:55 +0200 Subject: ethernet: T1637: do not overwrite interface description with interface name --- src/conf_mode/interface-ethernet.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 72eaee905..8a72068c5 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -125,8 +125,6 @@ def get_config(): # retrieve interface description if conf.exists('description'): eth['description'] = conf.return_value('description') - else: - eth['description'] = eth['intf'] # get DHCP client identifier if conf.exists('dhcp-options client-id'): -- cgit v1.2.3 From 3bf0a5e586e9139e80cdecd14ab326cee5512fae Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 15 Sep 2019 20:40:52 +0200 Subject: ethernet: T1637: fix calling arp_cache_tmo property --- src/conf_mode/interface-ethernet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 8a72068c5..4f455e8d3 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -284,7 +284,7 @@ def apply(eth): # disable ethernet flow control (pause frames) e.set_flow_control(eth['flow_control']) # configure ARP cache timeout in milliseconds - e.arp_cache_tmp = eth['ip_arp_cache_tmo'] + e.arp_cache_tmo = eth['ip_arp_cache_tmo'] # Enable proxy-arp on this interface e.proxy_arp = eth['ip_proxy_arp'] # Enable private VLAN proxy ARP on this interface -- cgit v1.2.3 From b27482c0201a433762168abe2d369ea43a599f1c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 19 Sep 2019 22:29:11 +0200 Subject: ethernet: T1637: interfaces in a bond can be disabled --- src/conf_mode/interface-ethernet.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/conf_mode/interface-ethernet.py') diff --git a/src/conf_mode/interface-ethernet.py b/src/conf_mode/interface-ethernet.py index 4f455e8d3..f82105847 100755 --- a/src/conf_mode/interface-ethernet.py +++ b/src/conf_mode/interface-ethernet.py @@ -253,12 +253,10 @@ def verify(eth): # 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'): - if eth['name'] in conf.return_values('interfaces bonding ' + bond + ' member interface'): - if eth['disable']: - raise ConfigError('Can not disable interface {} which is a member of {}').format(eth['intf'], bond) - - if eth['address']: - raise ConfigError('Can not assign address to interface {} which is a member of {}').format(eth['intf'], bond) + bond_member = conf.return_values('interfaces bonding ' + bond + ' member interface') + if eth['name'] in bond_member: + if eth['address']: + raise ConfigError('Can not assign address to interface {} which is a member of {}').format(eth['intf'], bond) return None -- cgit v1.2.3