summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos/ifconfig')
-rw-r--r--python/vyos/ifconfig/bond.py12
-rw-r--r--python/vyos/ifconfig/bridge.py20
-rw-r--r--python/vyos/ifconfig/ethernet.py30
-rw-r--r--python/vyos/ifconfig/pppoe.py37
-rw-r--r--python/vyos/ifconfig/section.py12
5 files changed, 95 insertions, 16 deletions
diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py
index 98bf6162b..0edd17055 100644
--- a/python/vyos/ifconfig/bond.py
+++ b/python/vyos/ifconfig/bond.py
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -405,10 +405,12 @@ class BondIf(Interface):
# Remove ALL bond member interfaces
for interface in self.get_slaves():
self.del_port(interface)
- # Removing an interface from a bond will always place the underlaying
- # physical interface in admin-down state! If physical interface is
- # not disabled, re-enable it.
- if not dict_search(f'member.interface_remove.{interface}.disable', config):
+
+ # Restore correct interface status based on config
+ if dict_search(f'member.interface.{interface}.disable', config) is not None or \
+ dict_search(f'member.interface_remove.{interface}.disable', config) is not None:
+ Interface(interface).set_admin_state('down')
+ else:
Interface(interface).set_admin_state('up')
# Bonding policy/mode - default value, always present
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index 758967fbc..aa818bc5f 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -295,8 +295,24 @@ class BridgeIf(Interface):
self.del_port(member)
# enable/disable Vlan Filter
- vlan_filter = '1' if 'enable_vlan' in config else '0'
- self.set_vlan_filter(vlan_filter)
+ tmp = '1' if 'enable_vlan' in config else '0'
+ self.set_vlan_filter(tmp)
+
+ # add VLAN interfaces to local 'parent' bridge to allow forwarding
+ if 'enable_vlan' in config:
+ for vlan in config.get('vif_remove', {}):
+ # Remove old VLANs from the bridge
+ cmd = f'bridge vlan del dev {self.ifname} vid {vlan} self'
+ self._cmd(cmd)
+
+ for vlan in config.get('vif', {}):
+ cmd = f'bridge vlan add dev {self.ifname} vid {vlan} self'
+ self._cmd(cmd)
+
+ # VLAN of bridge parent interface is always 1. VLAN 1 is the default
+ # VLAN for all unlabeled packets
+ cmd = f'bridge vlan add dev {self.ifname} vid 1 pvid untagged self'
+ self._cmd(cmd)
tmp = dict_search('member.interface', config)
if tmp:
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 1280fc238..32e667038 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -16,6 +16,7 @@
import os
import re
+from glob import glob
from vyos.ethtool import Ethtool
from vyos.ifconfig.interface import Interface
from vyos.util import run
@@ -74,6 +75,10 @@ class EthernetIf(Interface):
'convert': lambda cpus: cpus if cpus else '0',
'location': '/sys/class/net/{ifname}/queues/rx-0/rps_cpus',
},
+ 'rfs': {
+ 'convert': lambda num: num if num else '0',
+ 'location': '/proc/sys/net/core/rps_sock_flow_entries',
+ },
}}
def __init__(self, ifname, **kargs):
@@ -236,7 +241,7 @@ class EthernetIf(Interface):
enabled, fixed = self.ethtool.get_large_receive_offload()
if enabled != state:
if not fixed:
- return self.set_interface('gro', 'on' if state else 'off')
+ return self.set_interface('lro', 'on' if state else 'off')
else:
print('Adapter does not support changing large-receive-offload settings!')
return False
@@ -258,6 +263,20 @@ class EthernetIf(Interface):
# send bitmask representation as hex string without leading '0x'
return self.set_interface('rps', rps_cpus)
+ def set_rfs(self, state):
+ rfs_flow = 0
+ global_rfs_flow = 0
+ queues = len(glob(f'/sys/class/net/{self.ifname}/queues/rx-*'))
+ if state:
+ global_rfs_flow = 32768
+ rfs_flow = int(global_rfs_flow/queues)
+
+ self.set_interface('rfs', global_rfs_flow)
+ for i in range(0, queues):
+ self._write_sysfs(f'/sys/class/net/{self.ifname}/queues/rx-{i}/rps_flow_cnt', rfs_flow)
+
+ return True
+
def set_sg(self, state):
"""
Enable Scatter-Gather support. State can be either True or False.
@@ -273,7 +292,7 @@ class EthernetIf(Interface):
enabled, fixed = self.ethtool.get_scatter_gather()
if enabled != state:
if not fixed:
- return self.set_interface('gro', 'on' if state else 'off')
+ return self.set_interface('sg', 'on' if state else 'off')
else:
print('Adapter does not support changing scatter-gather settings!')
return False
@@ -293,7 +312,7 @@ class EthernetIf(Interface):
enabled, fixed = self.ethtool.get_tcp_segmentation_offload()
if enabled != state:
if not fixed:
- return self.set_interface('gro', 'on' if state else 'off')
+ return self.set_interface('tso', 'on' if state else 'off')
else:
print('Adapter does not support changing tcp-segmentation-offload settings!')
return False
@@ -342,6 +361,9 @@ class EthernetIf(Interface):
# RPS - Receive Packet Steering
self.set_rps(dict_search('offload.rps', config) != None)
+ # RFS - Receive Flow Steering
+ self.set_rfs(dict_search('offload.rfs', config) != None)
+
# scatter-gather option
self.set_sg(dict_search('offload.sg', config) != None)
@@ -359,5 +381,5 @@ class EthernetIf(Interface):
for rx_tx, size in config['ring_buffer'].items():
self.set_ring_buffer(rx_tx, size)
- # call base class first
+ # call base class last
super().update(config)
diff --git a/python/vyos/ifconfig/pppoe.py b/python/vyos/ifconfig/pppoe.py
index 63ffc8069..437fe0cae 100644
--- a/python/vyos/ifconfig/pppoe.py
+++ b/python/vyos/ifconfig/pppoe.py
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2020-2022 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -14,6 +14,7 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
from vyos.ifconfig.interface import Interface
+from vyos.validate import assert_range
from vyos.util import get_interface_config
@Interface.register
@@ -27,6 +28,21 @@ class PPPoEIf(Interface):
},
}
+ _sysfs_get = {
+ **Interface._sysfs_get,**{
+ 'accept_ra_defrtr': {
+ 'location': '/proc/sys/net/ipv6/conf/{ifname}/accept_ra_defrtr',
+ }
+ }
+ }
+
+ _sysfs_set = {**Interface._sysfs_set, **{
+ 'accept_ra_defrtr': {
+ 'validate': lambda value: assert_range(value, 0, 2),
+ 'location': '/proc/sys/net/ipv6/conf/{ifname}/accept_ra_defrtr',
+ },
+ }}
+
def _remove_routes(self, vrf=None):
# Always delete default routes when interface is removed
vrf_cmd = ''
@@ -70,6 +86,21 @@ class PPPoEIf(Interface):
""" Get a synthetic MAC address. """
return self.get_mac_synthetic()
+ def set_accept_ra_defrtr(self, enable):
+ """
+ Learn default router in Router Advertisement.
+ 1: enabled
+ 0: disable
+
+ Example:
+ >>> from vyos.ifconfig import PPPoEIf
+ >>> PPPoEIf('pppoe1').set_accept_ra_defrtr(0)
+ """
+ tmp = self.get_interface('accept_ra_defrtr')
+ if tmp == enable:
+ return None
+ self.set_interface('accept_ra_defrtr', enable)
+
def update(self, config):
""" General helper function which works on a dictionary retrived by
get_config_dict(). It's main intention is to consolidate the scattered
@@ -107,6 +138,10 @@ class PPPoEIf(Interface):
tmp = config['vrf']
vrf = f'-c "vrf {tmp}"'
+ # learn default router in Router Advertisement.
+ tmp = '0' if 'no_default_route' in config else '1'
+ self.set_accept_ra_defrtr(tmp)
+
if 'no_default_route' not in config:
# Set default route(s) pointing to PPPoE interface
distance = config['default_route_distance']
diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py
index 91f667b65..5e98cd510 100644
--- a/python/vyos/ifconfig/section.py
+++ b/python/vyos/ifconfig/section.py
@@ -88,7 +88,7 @@ class Section:
raise ValueError(f'No type found for interface name: {name}')
@classmethod
- def _intf_under_section (cls,section=''):
+ def _intf_under_section (cls,section='',vlan=True):
"""
return a generator with the name of the configured interface
which are under a section
@@ -103,6 +103,9 @@ class Section:
if section and ifsection != section:
continue
+ if vlan == False and '.' in ifname:
+ continue
+
yield ifname
@classmethod
@@ -135,13 +138,14 @@ class Section:
return l
@classmethod
- def interfaces(cls, section=''):
+ def interfaces(cls, section='', vlan=True):
"""
return a list of the name of the configured interface which are under a section
- if no section is provided, then it returns all configured interfaces
+ if no section is provided, then it returns all configured interfaces.
+ If vlan is True, also Vlan subinterfaces will be returned
"""
- return cls._sort_interfaces(cls._intf_under_section(section))
+ return cls._sort_interfaces(cls._intf_under_section(section, vlan))
@classmethod
def _intf_with_feature(cls, feature=''):