summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos/ifconfig')
-rw-r--r--python/vyos/ifconfig/bond.py8
-rw-r--r--python/vyos/ifconfig/bridge.py77
-rw-r--r--python/vyos/ifconfig/ethernet.py12
-rw-r--r--python/vyos/ifconfig/interface.py40
-rw-r--r--python/vyos/ifconfig/l2tpv3.py25
-rw-r--r--python/vyos/ifconfig/tunnel.py2
-rw-r--r--python/vyos/ifconfig/vtun.py44
-rw-r--r--python/vyos/ifconfig/wireguard.py2
8 files changed, 164 insertions, 46 deletions
diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py
index 9108fc180..709222b09 100644
--- a/python/vyos/ifconfig/bond.py
+++ b/python/vyos/ifconfig/bond.py
@@ -17,7 +17,7 @@ import os
from vyos.ifconfig.interface import Interface
from vyos.util import cmd
-from vyos.util import vyos_dict_search
+from vyos.util import dict_search
from vyos.validate import assert_list
from vyos.validate import assert_positive
@@ -360,7 +360,7 @@ class BondIf(Interface):
self.set_arp_ip_target('-' + addr)
# Add configured ARP target addresses
- value = vyos_dict_search('arp_monitor.target', config)
+ value = dict_search('arp_monitor.target', config)
if isinstance(value, str):
value = [value]
if value:
@@ -384,7 +384,7 @@ class BondIf(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 vyos_dict_search(f'member.interface_remove.{interface}.disable', config):
+ if not dict_search(f'member.interface_remove.{interface}.disable', config):
Interface(interface).set_admin_state('up')
# Bonding policy/mode
@@ -392,7 +392,7 @@ class BondIf(Interface):
if value: self.set_mode(value)
# Add (enslave) interfaces to bond
- value = vyos_dict_search('member.interface', config)
+ value = dict_search('member.interface', config)
for interface in (value or []):
# if we've come here we already verified the interface
# does not have an addresses configured so just flush
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index bf78f8972..7eac9b886 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -19,7 +19,7 @@ from vyos.ifconfig.interface import Interface
from vyos.validate import assert_boolean
from vyos.validate import assert_positive
from vyos.util import cmd
-from vyos.util import vyos_dict_search
+from vyos.util import dict_search
@Interface.register
class BridgeIf(Interface):
@@ -41,6 +41,7 @@ class BridgeIf(Interface):
'section': 'bridge',
'prefixes': ['br', ],
'broadcast': True,
+ 'vlan': True,
},
}
@@ -73,6 +74,10 @@ class BridgeIf(Interface):
'validate': assert_boolean,
'location': '/sys/class/net/{ifname}/bridge/stp_state',
},
+ 'vlan_filter': {
+ 'validate': assert_boolean,
+ 'location': '/sys/class/net/{ifname}/bridge/vlan_filtering',
+ },
'multicast_querier': {
'validate': assert_boolean,
'location': '/sys/class/net/{ifname}/bridge/multicast_querier',
@@ -152,6 +157,16 @@ class BridgeIf(Interface):
>>> BridgeIf('br0').set_stp(1)
"""
self.set_interface('stp', state)
+
+ def set_vlan_filter(self, state):
+ """
+ Set bridge Vlan Filter state. 0 -> Vlan Filter disabled, 1 -> Vlan Filter enabled
+
+ Example:
+ >>> from vyos.ifconfig import BridgeIf
+ >>> BridgeIf('br0').set_vlan_filter(1)
+ """
+ self.set_interface('vlan_filter', state)
def set_multicast_querier(self, enable):
"""
@@ -177,8 +192,13 @@ class BridgeIf(Interface):
>>> BridgeIf('br0').add_port('eth0')
>>> BridgeIf('br0').add_port('eth1')
"""
+ # Bridge port handling of wireless interfaces is done by hostapd.
+ if 'wlan' in interface:
+ return
+
return self.set_interface('add_port', interface)
+
def del_port(self, interface):
"""
Remove member port from bridge instance.
@@ -197,6 +217,8 @@ class BridgeIf(Interface):
# call base class first
super().update(config)
+
+ ifname = config['ifname']
# Set ageing time
value = config.get('aging')
@@ -223,17 +245,18 @@ class BridgeIf(Interface):
self.set_stp(value)
# enable or disable IGMP querier
- tmp = vyos_dict_search('igmp.querier', config)
+ tmp = dict_search('igmp.querier', config)
value = '1' if (tmp != None) else '0'
self.set_multicast_querier(value)
# remove interface from bridge
- tmp = vyos_dict_search('member.interface_remove', config)
+ tmp = dict_search('member.interface_remove', config)
for member in (tmp or []):
if member in interfaces():
self.del_port(member)
+ vlan_filter = 0
- tmp = vyos_dict_search('member.interface', config)
+ tmp = dict_search('member.interface', config)
if tmp:
for interface, interface_config in tmp.items():
# if interface does yet not exist bail out early and
@@ -260,7 +283,51 @@ class BridgeIf(Interface):
if 'priority' in interface_config:
value = interface_config.get('priority')
lower.set_path_priority(value)
-
+
+ tmp = dict_search('native_vlan_removed', interface_config)
+
+ if tmp and 'native_vlan_removed' not in interface_config:
+ vlan_id = tmp
+ cmd = f'bridge vlan add dev {interface} vid 1 pvid untagged master'
+ self._cmd(cmd)
+ cmd = f'bridge vlan del dev {interface} vid {vlan_id}'
+ self._cmd(cmd)
+
+ tmp = dict_search('allowed_vlan_removed', interface_config)
+
+
+ for vlan_id in (tmp or []):
+ cmd = f'bridge vlan del dev {interface} vid {vlan_id}'
+ self._cmd(cmd)
+
+ if 'native_vlan' in interface_config:
+ vlan_filter = 1
+ cmd = f'bridge vlan del dev {interface} vid 1'
+ self._cmd(cmd)
+ vlan_id = interface_config['native_vlan']
+ cmd = f'bridge vlan add dev {interface} vid {vlan_id} pvid untagged master'
+ self._cmd(cmd)
+ else:
+ cmd = f'bridge vlan del dev {interface} vid 1'
+ self._cmd(cmd)
+
+ if 'allowed_vlan' in interface_config:
+ vlan_filter = 1
+ for vlan in interface_config['allowed_vlan']:
+ cmd = f'bridge vlan add dev {interface} vid {vlan} master'
+ self._cmd(cmd)
+
+
+ vif = dict_search('vif', config)
+ if vif:
+ for vlan_id,vif_config in vif.items():
+ cmd = f'bridge vlan add dev {ifname} vid {vlan_id} self master'
+ self._cmd(cmd)
+
+ # enable/disable Vlan Filter
+ self.set_vlan_filter(vlan_filter)
+
+
# Enable/Disable of an interface must always be done at the end of the
# derived class to make use of the ref-counting set_admin_state()
# function. We will only enable the interface if 'up' was called as
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 1d48941f9..12d1ec265 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -19,7 +19,7 @@ import re
from vyos.ifconfig.interface import Interface
from vyos.validate import assert_list
from vyos.util import run
-from vyos.util import vyos_dict_search
+from vyos.util import dict_search
@Interface.register
class EthernetIf(Interface):
@@ -282,27 +282,27 @@ class EthernetIf(Interface):
self.set_flow_control(value)
# GRO (generic receive offload)
- tmp = vyos_dict_search('offload_options.generic_receive', config)
+ tmp = dict_search('offload_options.generic_receive', config)
value = tmp if (tmp != None) else 'off'
self.set_gro(value)
# GSO (generic segmentation offload)
- tmp = vyos_dict_search('offload_options.generic_segmentation', config)
+ tmp = dict_search('offload_options.generic_segmentation', config)
value = tmp if (tmp != None) else 'off'
self.set_gso(value)
# scatter-gather option
- tmp = vyos_dict_search('offload_options.scatter_gather', config)
+ tmp = dict_search('offload_options.scatter_gather', config)
value = tmp if (tmp != None) else 'off'
self.set_sg(value)
# TSO (TCP segmentation offloading)
- tmp = vyos_dict_search('offload_options.udp_fragmentation', config)
+ tmp = dict_search('offload_options.udp_fragmentation', config)
value = tmp if (tmp != None) else 'off'
self.set_tso(value)
# UDP fragmentation offloading
- tmp = vyos_dict_search('offload_options.udp_fragmentation', config)
+ tmp = dict_search('offload_options.udp_fragmentation', config)
value = tmp if (tmp != None) else 'off'
self.set_ufo(value)
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index ae747e87c..893623284 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -34,9 +34,9 @@ from vyos.configdict import list_diff
from vyos.configdict import dict_merge
from vyos.template import render
from vyos.util import mac2eui64
-from vyos.util import vyos_dict_search
-from vyos.validate import is_ipv4
-from vyos.validate import is_ipv6
+from vyos.util import dict_search
+from vyos.template import is_ipv4
+from vyos.template import is_ipv6
from vyos.validate import is_intf_addr_assigned
from vyos.validate import assert_boolean
from vyos.validate import assert_list
@@ -880,7 +880,7 @@ class Interface(Control):
lease_file = f'{config_base}_{ifname}.leases'
if enable and 'disable' not in self._config:
- if vyos_dict_search('dhcp_options.host_name', self._config) == None:
+ if dict_search('dhcp_options.host_name', self._config) == None:
# read configured system hostname.
# maybe change to vyos hostd client ???
hostname = 'vyos'
@@ -959,7 +959,7 @@ class Interface(Control):
# always ensure DHCPv6 client is stopped (when not configured as client
# for IPv6 address or prefix delegation
- dhcpv6pd = vyos_dict_search('dhcpv6_options.pd', config)
+ dhcpv6pd = dict_search('dhcpv6_options.pd', config)
if 'dhcpv6' not in new_addr or dhcpv6pd == None:
self.del_addr('dhcpv6')
@@ -987,64 +987,64 @@ class Interface(Control):
self.set_vrf(config.get('vrf', ''))
# Configure ARP cache timeout in milliseconds - has default value
- tmp = vyos_dict_search('ip.arp_cache_timeout', config)
+ tmp = dict_search('ip.arp_cache_timeout', config)
value = tmp if (tmp != None) else '30'
self.set_arp_cache_tmo(value)
# Configure ARP filter configuration
- tmp = vyos_dict_search('ip.disable_arp_filter', config)
+ tmp = dict_search('ip.disable_arp_filter', config)
value = '0' if (tmp != None) else '1'
self.set_arp_filter(value)
# Configure ARP accept
- tmp = vyos_dict_search('ip.enable_arp_accept', config)
+ tmp = dict_search('ip.enable_arp_accept', config)
value = '1' if (tmp != None) else '0'
self.set_arp_accept(value)
# Configure ARP announce
- tmp = vyos_dict_search('ip.enable_arp_announce', config)
+ tmp = dict_search('ip.enable_arp_announce', config)
value = '1' if (tmp != None) else '0'
self.set_arp_announce(value)
# Configure ARP ignore
- tmp = vyos_dict_search('ip.enable_arp_ignore', config)
+ tmp = dict_search('ip.enable_arp_ignore', config)
value = '1' if (tmp != None) else '0'
self.set_arp_ignore(value)
# Enable proxy-arp on this interface
- tmp = vyos_dict_search('ip.enable_proxy_arp', config)
+ tmp = dict_search('ip.enable_proxy_arp', config)
value = '1' if (tmp != None) else '0'
self.set_proxy_arp(value)
# Enable private VLAN proxy ARP on this interface
- tmp = vyos_dict_search('ip.proxy_arp_pvlan', config)
+ tmp = dict_search('ip.proxy_arp_pvlan', config)
value = '1' if (tmp != None) else '0'
self.set_proxy_arp_pvlan(value)
# IPv4 forwarding
- tmp = vyos_dict_search('ip.disable_forwarding', config)
+ tmp = dict_search('ip.disable_forwarding', config)
value = '0' if (tmp != None) else '1'
self.set_ipv4_forwarding(value)
# IPv6 forwarding
- tmp = vyos_dict_search('ipv6.disable_forwarding', config)
+ tmp = dict_search('ipv6.disable_forwarding', config)
value = '0' if (tmp != None) else '1'
self.set_ipv6_forwarding(value)
# IPv6 router advertisements
- tmp = vyos_dict_search('ipv6.address.autoconf', config)
+ tmp = dict_search('ipv6.address.autoconf', config)
value = '2' if (tmp != None) else '1'
if 'dhcpv6' in new_addr:
value = '2'
self.set_ipv6_accept_ra(value)
# IPv6 address autoconfiguration
- tmp = vyos_dict_search('ipv6.address.autoconf', config)
+ tmp = dict_search('ipv6.address.autoconf', config)
value = '1' if (tmp != None) else '0'
self.set_ipv6_autoconf(value)
# IPv6 Duplicate Address Detection (DAD) tries
- tmp = vyos_dict_search('ipv6.dup_addr_detect_transmits', config)
+ tmp = dict_search('ipv6.dup_addr_detect_transmits', config)
value = tmp if (tmp != None) else '1'
self.set_ipv6_dad_messages(value)
@@ -1053,7 +1053,7 @@ class Interface(Control):
self.set_mtu(config.get('mtu'))
# Delete old IPv6 EUI64 addresses before changing MAC
- tmp = vyos_dict_search('ipv6.address.eui64_old', config)
+ tmp = dict_search('ipv6.address.eui64_old', config)
if tmp:
for addr in tmp:
self.del_ipv6_eui64_address(addr)
@@ -1068,7 +1068,7 @@ class Interface(Control):
self.set_mac(mac)
# Manage IPv6 link-local addresses
- tmp = vyos_dict_search('ipv6.address.no_default_link_local', config)
+ tmp = dict_search('ipv6.address.no_default_link_local', config)
# we must check explicitly for None type as if the key is set we will
# get an empty dict (<class 'dict'>)
if tmp is not None:
@@ -1077,7 +1077,7 @@ class Interface(Control):
self.add_ipv6_eui64_address('fe80::/64')
# Add IPv6 EUI-based addresses
- tmp = vyos_dict_search('ipv6.address.eui64', config)
+ tmp = dict_search('ipv6.address.eui64', config)
if tmp:
for addr in tmp:
self.add_ipv6_eui64_address(addr)
diff --git a/python/vyos/ifconfig/l2tpv3.py b/python/vyos/ifconfig/l2tpv3.py
index 5fd90f9cf..8ed3d5afb 100644
--- a/python/vyos/ifconfig/l2tpv3.py
+++ b/python/vyos/ifconfig/l2tpv3.py
@@ -68,8 +68,9 @@ class L2TPv3If(Interface):
cmd += ' peer_session_id {peer_session_id}'
self._cmd(cmd.format(**self.config))
- # interface is always A/D down. It needs to be enabled explicitly
- self.set_admin_state('down')
+ # No need for interface shut down. There exist no function to permanently enable tunnel.
+ # But you can disable interface permanently with shutdown/disable command.
+ self.set_admin_state('up')
def remove(self):
"""
@@ -93,4 +94,24 @@ class L2TPv3If(Interface):
if self.config['tunnel_id']:
cmd = 'ip l2tp del tunnel tunnel_id {tunnel_id}'
self._cmd(cmd.format(**self.config))
+
+
+ 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
+ interface setup code and provide a single point of entry when workin
+ on any interface. """
+
+ # call base class first
+ super().update(config)
+
+ # Enable/Disable of an interface must always be done at the end of the
+ # derived class to make use of the ref-counting set_admin_state()
+ # function. We will only enable the interface if 'up' was called as
+ # often as 'down'. This is required by some interface implementations
+ # as certain parameters can only be changed when the interface is
+ # in admin-down state. This ensures the link does not flap during
+ # reconfiguration.
+ state = 'down' if 'disable' in config else 'up'
+ self.set_admin_state(state)
diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py
index 964ffe383..4122d1a2f 100644
--- a/python/vyos/ifconfig/tunnel.py
+++ b/python/vyos/ifconfig/tunnel.py
@@ -179,7 +179,7 @@ class GRETapIf(_Tunnel):
default = {'type': 'gretap'}
required = ['local', ]
- options = ['local', 'remote', ]
+ options = ['local', 'remote', 'ttl',]
updates = ['mtu', ]
create = 'ip link add {ifname} type {type}'
diff --git a/python/vyos/ifconfig/vtun.py b/python/vyos/ifconfig/vtun.py
index b25e32d63..99a592b3e 100644
--- a/python/vyos/ifconfig/vtun.py
+++ b/python/vyos/ifconfig/vtun.py
@@ -19,6 +19,7 @@ from vyos.ifconfig.interface import Interface
class VTunIf(Interface):
default = {
'type': 'vtun',
+ 'device_type': 'tun',
}
definition = {
**Interface.definition,
@@ -28,15 +29,44 @@ class VTunIf(Interface):
'bridgeable': True,
},
}
-
- # stub this interface is created in the configure script
+ options = Interface.options + ['device_type']
def _create(self):
- # we can not create this interface as it is managed outside
- # it requires configuring OpenVPN
+ """ Depending on OpenVPN operation mode the interface is created
+ immediately (e.g. Server mode) or once the connection to the server is
+ established (client mode). The latter will only be brought up once the
+ server can be reached, thus we might need to create this interface in
+ advance for the service to be operational. """
+ try:
+ cmd = 'openvpn --mktun --dev-type {device_type} --dev {ifname}'.format(**self.config)
+ return self._cmd(cmd)
+ except PermissionError:
+ # interface created by OpenVPN daemon in the meantime ...
+ pass
+
+ def add_addr(self, addr):
+ # IP addresses are managed by OpenVPN daemon
pass
- def _delete(self):
- # we can not create this interface as it is managed outside
- # it requires configuring OpenVPN
+ def del_addr(self, addr):
+ # IP addresses are managed by OpenVPN daemon
pass
+
+ 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
+ interface setup code and provide a single point of entry when workin
+ on any interface. """
+
+ # call base class first
+ super().update(config)
+
+ # Enable/Disable of an interface must always be done at the end of the
+ # derived class to make use of the ref-counting set_admin_state()
+ # function. We will only enable the interface if 'up' was called as
+ # often as 'down'. This is required by some interface implementations
+ # as certain parameters can only be changed when the interface is
+ # in admin-down state. This ensures the link does not flap during
+ # reconfiguration.
+ state = 'down' if 'disable' in config else 'up'
+ self.set_admin_state(state)
diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py
index d8e89229d..da3bd4e89 100644
--- a/python/vyos/ifconfig/wireguard.py
+++ b/python/vyos/ifconfig/wireguard.py
@@ -24,7 +24,7 @@ from hurry.filesize import alternative
from vyos.config import Config
from vyos.ifconfig import Interface
from vyos.ifconfig import Operational
-from vyos.validate import is_ipv6
+from vyos.template import is_ipv6
class WireGuardOperational(Operational):
def _dump(self):