summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorThomas Mangin <thomas.mangin@exa.net.uk>2020-03-24 18:14:49 +0000
committerThomas Mangin <thomas.mangin@exa.net.uk>2020-03-24 18:14:49 +0000
commit8a4dd6c2816bf2289ad4af37ba301b31efdf30a8 (patch)
tree5974407307b60984e2b1c71ecf949b1ca182c0f2 /python
parent09f8e57535849aab83df6947fbe94a0e7228ed40 (diff)
downloadvyos-1x-8a4dd6c2816bf2289ad4af37ba301b31efdf30a8.tar.gz
vyos-1x-8a4dd6c2816bf2289ad4af37ba301b31efdf30a8.zip
ifconfig: T2057: add class Register
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/bond.py18
-rw-r--r--python/vyos/ifconfig/bridge.py17
-rw-r--r--python/vyos/ifconfig/control.py4
-rw-r--r--python/vyos/ifconfig/dummy.py8
-rw-r--r--python/vyos/ifconfig/ethernet.py20
-rw-r--r--python/vyos/ifconfig/geneve.py9
-rw-r--r--python/vyos/ifconfig/interface.py8
-rw-r--r--python/vyos/ifconfig/l2tpv3.py14
-rw-r--r--python/vyos/ifconfig/loopback.py11
-rw-r--r--python/vyos/ifconfig/macvlan.py11
-rw-r--r--python/vyos/ifconfig/register.py96
-rw-r--r--python/vyos/ifconfig/tunnel.py8
-rw-r--r--python/vyos/ifconfig/vxlan.py24
-rw-r--r--python/vyos/ifconfig/wireguard.py14
-rw-r--r--python/vyos/ifconfig/wireless.py26
-rw-r--r--python/vyos/ifconfig_vlan.py2
16 files changed, 260 insertions, 30 deletions
diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py
index c9dac891f..af4082f8f 100644
--- a/python/vyos/ifconfig/bond.py
+++ b/python/vyos/ifconfig/bond.py
@@ -21,6 +21,7 @@ from vyos.ifconfig.vlan import VLANIf
from vyos.validate import *
+@Interface.register
class BondIf(VLANIf):
"""
The Linux bonding driver provides a method for aggregating multiple network
@@ -30,6 +31,19 @@ class BondIf(VLANIf):
monitoring may be performed.
"""
+ default = {
+ 'type': 'bond',
+ }
+ definition = {
+ **Interface.definition,
+ ** {
+ 'section': 'bonding',
+ 'prefixes': ['bond', ],
+ 'broadcast': True,
+ 'bridgeable': True,
+ },
+ }
+
_sysfs_set = {**VLANIf._sysfs_set, **{
'bond_hash_policy': {
'validate': lambda v: assert_list(v, ['layer2', 'layer2+3', 'layer3+4', 'encap2+3', 'encap3+4']),
@@ -69,10 +83,6 @@ class BondIf(VLANIf):
}
}}
- default = {
- 'type': 'bond',
- }
-
def remove(self):
"""
Remove interface from operating system. Removing the interface
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index 90c44af13..94b0075d8 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -18,6 +18,8 @@ from vyos.ifconfig.interface import Interface
from vyos.validate import *
+
+@Interface.register
class BridgeIf(Interface):
"""
A bridge is a way to connect two Ethernet segments together in a protocol
@@ -28,6 +30,18 @@ class BridgeIf(Interface):
The Linux bridge code implements a subset of the ANSI/IEEE 802.1d standard.
"""
+ default = {
+ 'type': 'bridge',
+ }
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'bridge',
+ 'prefixes': ['br', ],
+ 'broadcast': True,
+ },
+ }
+
_sysfs_set = {**Interface._sysfs_set, **{
'ageing_time': {
'validate': assert_positive,
@@ -72,9 +86,6 @@ class BridgeIf(Interface):
},
}}
- default = {
- 'type': 'bridge',
- }
def set_ageing_time(self, time):
"""
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py
index 89deba40a..28adc80d1 100644
--- a/python/vyos/ifconfig/control.py
+++ b/python/vyos/ifconfig/control.py
@@ -17,8 +17,10 @@
import os
from subprocess import Popen, PIPE, STDOUT
+from vyos.ifconfig.register import Register
-class Control:
+
+class Control(Register):
_command_get = {}
_command_set = {}
diff --git a/python/vyos/ifconfig/dummy.py b/python/vyos/ifconfig/dummy.py
index 58b89fe68..404c490c7 100644
--- a/python/vyos/ifconfig/dummy.py
+++ b/python/vyos/ifconfig/dummy.py
@@ -17,6 +17,7 @@
from vyos.ifconfig.interface import Interface
+@Interface.register
class DummyIf(Interface):
"""
A dummy interface is entirely virtual like, for example, the loopback
@@ -27,3 +28,10 @@ class DummyIf(Interface):
default = {
'type': 'dummy',
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'dummy',
+ 'prefixes': ['dum', ],
+ },
+ }
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 30e3a3bef..606161121 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -17,15 +17,31 @@ import os
import re
from vyos.ifconfig.vlan import VLANIf
+from vyos.ifconfig.interface import Interface
from vyos.validate import *
+@Interface.register
class EthernetIf(VLANIf):
"""
Abstraction of a Linux Ethernet Interface
"""
+ default = {
+ 'type': 'ethernet',
+ }
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'ethernet',
+ 'prefixes': ['lan', 'eth', 'eno', 'ens', 'enp', 'enx'],
+ 'bondable': True,
+ 'broadcast': True,
+ 'bridgeable': True,
+ }
+ }
+
_command_set = {**VLANIf._command_set, **{
'gro': {
'validate': lambda v: assert_list(v, ['on', 'off']),
@@ -49,10 +65,6 @@ class EthernetIf(VLANIf):
},
}}
- default = {
- 'type': 'ethernet',
- }
-
def _delete(self):
# Ethernet interfaces can not be removed
pass
diff --git a/python/vyos/ifconfig/geneve.py b/python/vyos/ifconfig/geneve.py
index a3b3a4c4a..f27786417 100644
--- a/python/vyos/ifconfig/geneve.py
+++ b/python/vyos/ifconfig/geneve.py
@@ -18,6 +18,7 @@ from copy import deepcopy
from vyos.ifconfig.interface import Interface
+@Interface.register
class GeneveIf(Interface):
"""
Geneve: Generic Network Virtualization Encapsulation
@@ -34,6 +35,14 @@ class GeneveIf(Interface):
'vni': 0,
'remote': '',
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'geneve',
+ 'prefixes': ['gnv', ],
+ 'bridgeable': True,
+ }
+ }
def _create(self):
cmd = 'ip link add name {ifname} type geneve id {vni} remote {remote}'.format(**self.config)
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index a1f8198c7..1759e3545 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -42,6 +42,14 @@ class Interface(DHCP):
default = {
'type': '',
}
+ definition = {
+ 'section': '',
+ 'prefixes': [],
+ 'vlan': False,
+ 'bondable': False,
+ 'broadcast': False,
+ 'bridgeable': False,
+ }
_command_set = {
'state': {
diff --git a/python/vyos/ifconfig/l2tpv3.py b/python/vyos/ifconfig/l2tpv3.py
index a87535277..fbfab4c6e 100644
--- a/python/vyos/ifconfig/l2tpv3.py
+++ b/python/vyos/ifconfig/l2tpv3.py
@@ -19,6 +19,7 @@ import os
from vyos.ifconfig.interface import Interface
+@Interface.register
class L2TPv3If(Interface):
"""
The Linux bonding driver provides a method for aggregating multiple network
@@ -28,12 +29,19 @@ class L2TPv3If(Interface):
monitoring may be performed.
"""
- options = Interface.options + \
- ['tunnel_id', 'peer_tunnel_id', 'local_port', 'remote_port',
- 'encapsulation', 'local_address', 'remote_address']
default = {
'type': 'l2tp',
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'l2tpeth',
+ 'prefixes': ['l2tpeth', ],
+ 'bridgeable': True,
+ }
+ }
+ options = Interface.options + \
+ ['tunnel_id', 'peer_tunnel_id', 'local_port', 'remote_port', 'encapsulation', 'local_address', 'remote_address']
def _create(self):
# create tunnel interface
diff --git a/python/vyos/ifconfig/loopback.py b/python/vyos/ifconfig/loopback.py
index 37b8e9e3b..8e4438662 100644
--- a/python/vyos/ifconfig/loopback.py
+++ b/python/vyos/ifconfig/loopback.py
@@ -17,6 +17,7 @@
from vyos.ifconfig.interface import Interface
+@Interface.register
class LoopbackIf(Interface):
"""
The loopback device is a special, virtual network interface that your router
@@ -26,6 +27,16 @@ class LoopbackIf(Interface):
default = {
'type': 'loopback',
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'loopback',
+ 'prefixes': ['lo', ],
+ 'bridgeable': True,
+ }
+ }
+
+ name = 'loopback'
def remove(self):
"""
diff --git a/python/vyos/ifconfig/macvlan.py b/python/vyos/ifconfig/macvlan.py
index da3beea8b..a1dca5e41 100644
--- a/python/vyos/ifconfig/macvlan.py
+++ b/python/vyos/ifconfig/macvlan.py
@@ -14,18 +14,27 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+from vyos.ifconfig.interface import Interface
from vyos.ifconfig.vlan import VLANIf
+@Interface.register
class MACVLANIf(VLANIf):
"""
Abstraction of a Linux MACvlan interface
"""
- options = VLANIf.options + ['link', 'mode']
default = {
'type': 'macvlan',
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'pseudo-ethernet',
+ 'prefixes': ['peth', ],
+ },
+ }
+ options = Interface.options + ['link', 'mode']
def _create(self):
cmd = 'ip link add {ifname} link {link} type macvlan mode {mode}'.format(
diff --git a/python/vyos/ifconfig/register.py b/python/vyos/ifconfig/register.py
new file mode 100644
index 000000000..2d4b0d4c0
--- /dev/null
+++ b/python/vyos/ifconfig/register.py
@@ -0,0 +1,96 @@
+# Copyright 2020 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+import netifaces
+
+
+class Register:
+ # the known interface prefixes
+ _prefixes = {}
+
+ # class need to define: definition['prefixes']
+ # the interface prefixes declared by a class used to name interface with
+ # prefix[0-9]*(\.[0-9]+)?(\.[0-9]+)?, such as lo, eth0 or eth0.1.2
+
+ @classmethod
+ def register(cls, klass):
+ if not klass.definition.get('prefixes',[]):
+ raise RuntimeError(f'valid interface prefixes not defined for {klass.__name__}')
+
+ for ifprefix in klass.definition['prefixes']:
+ if ifprefix in cls._prefixes:
+ raise RuntimeError(f'only one class can be registered for prefix "{ifprefix}" type')
+ cls._prefixes[ifprefix] = klass
+
+ return klass
+
+ @classmethod
+ def _basename (cls, name, vlan):
+ # remove number from interface name
+ name = name.rstrip('0123456789')
+ name = name.rstrip('.')
+ if vlan:
+ name = name.rstrip('0123456789')
+ return name
+
+ @classmethod
+ def section(cls, name, vlan=True):
+ # return the name of a section an interface should be under
+ name = cls._basename(name, vlan)
+
+ # XXX: To leave as long as vti and input are not moved to vyos
+ if name == 'vti':
+ return 'vti'
+ if name == 'ifb':
+ return 'input'
+
+ if name in cls._prefixes:
+ return cls._prefixes[name].defintion['section']
+ return ''
+
+ @classmethod
+ def klass(cls, name, vlan=True):
+ name = cls._basename(name, vlan)
+ if name in cls._prefixes:
+ return cls._prefixes[name]
+ raise ValueError(f'No type found for interface name: {name}')
+
+ @classmethod
+ def _listing (cls):
+ interfaces = netifaces.interfaces()
+
+ for ifname in interfaces:
+ if '@' in ifname:
+ # Tunnels: sit0@NONE, gre0@NONE, gretap0@NONE, erspan0@NONE, tunl0@NONE, ip6tnl0@NONE, ip6gre0@NONE
+ continue
+
+ # XXX: Temporary hack as vti and input are not yet moved from vyatta to vyos
+ if ifname.startswith('vti') or ifname.startswith('input'):
+ yield ifname
+ continue
+
+ if not cls.section(ifname):
+ continue
+ yield ifname
+
+ @classmethod
+ def listing(cls, section=''):
+ if not section:
+ return list(cls._listing())
+ return [_ for _ in cls._listing() if cls._basename(_,False) in self.prefixes]
+
+
+# XXX: TODO - limit name for VRF interfaces
+
diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py
index c82727eee..a49bdd51c 100644
--- a/python/vyos/ifconfig/tunnel.py
+++ b/python/vyos/ifconfig/tunnel.py
@@ -38,6 +38,14 @@ class _Tunnel(Interface):
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/ip/tunnel.c
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/ip/ip6tunnel.c
"""
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'tunnel',
+ 'prefixes': ['tun',],
+ 'bridgeable': True,
+ },
+ }
# TODO: This is surely used for more than tunnels
# TODO: could be refactored elsewhere
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py
index 75cdf8957..5678ad62e 100644
--- a/python/vyos/ifconfig/vxlan.py
+++ b/python/vyos/ifconfig/vxlan.py
@@ -19,6 +19,7 @@ from vyos import ConfigError
from vyos.ifconfig.interface import Interface
+@Interface.register
class VXLANIf(Interface):
"""
The VXLAN protocol is a tunnelling protocol designed to solve the
@@ -40,14 +41,6 @@ class VXLANIf(Interface):
https://www.kernel.org/doc/Documentation/networking/vxlan.txt
"""
- options = ['group', 'remote', 'dev', 'port', 'vni']
-
- mapping = {
- 'ifname': 'add',
- 'vni': 'id',
- 'port': 'dstport',
- }
-
default = {
'type': 'vxlan',
'vni': 0,
@@ -57,6 +50,21 @@ class VXLANIf(Interface):
'port': 8472, # The Linux implementation of VXLAN pre-dates
# the IANA's selection of a standard destination port
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'vxlan',
+ 'prefixes': ['vxlan', ],
+ 'bridgeable': True,
+ }
+ }
+ options = ['group', 'remote', 'dev', 'port', 'vni']
+
+ mapping = {
+ 'ifname': 'add',
+ 'vni': 'id',
+ 'port': 'dstport',
+ }
def _create(self):
cmdline = set()
diff --git a/python/vyos/ifconfig/wireguard.py b/python/vyos/ifconfig/wireguard.py
index 71ee67c98..8cf1ff58c 100644
--- a/python/vyos/ifconfig/wireguard.py
+++ b/python/vyos/ifconfig/wireguard.py
@@ -22,10 +22,8 @@ from datetime import timedelta
import time
from hurry.filesize import size,alternative
+@Interface.register
class WireGuardIf(Interface):
- options = ['port', 'private-key', 'pubkey', 'psk',
- 'allowed-ips', 'fwmark', 'endpoint', 'keepalive']
-
default = {
'type': 'wireguard',
'port': 0,
@@ -37,6 +35,16 @@ class WireGuardIf(Interface):
'endpoint': None,
'keepalive': 0
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'wireguard',
+ 'prefixes': ['wg', ],
+ 'bridgeable': True,
+ }
+ }
+ options = ['port', 'private-key', 'pubkey', 'psk',
+ 'allowed-ips', 'fwmark', 'endpoint', 'keepalive']
"""
Wireguard interface class, contains a comnfig dictionary since
diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py
index 7f507ff6e..f94509c80 100644
--- a/python/vyos/ifconfig/wireless.py
+++ b/python/vyos/ifconfig/wireless.py
@@ -15,19 +15,29 @@
import os
+from vyos.ifconfig.interface import Interface
from vyos.ifconfig.vlan import VLANIf
+
+@Interface.register
class WiFiIf(VLANIf):
"""
Handle WIFI/WLAN interfaces.
"""
- options = ['phy', 'op_mode']
-
default = {
'type': 'wifi',
'phy': 'phy0'
}
+ definition = {
+ **Interface.definition,
+ **{
+ 'section': 'wireless',
+ 'prefixes': ['wlan', ],
+ 'bridgeable': True,
+ }
+ }
+ options = ['phy', 'op_mode']
def _create(self):
# all interfaces will be added in monitor mode
@@ -54,3 +64,15 @@ class WiFiIf(VLANIf):
'phy': 'phy0'
}
return config
+
+
+
+@Interface.register
+class WiFiModemIf(WiFiIf):
+ definition = {
+ **WiFiIf.definition,
+ **{
+ 'section': 'wirelessmodem',
+ 'prefixes': ['wlm', ],
+ }
+ }
diff --git a/python/vyos/ifconfig_vlan.py b/python/vyos/ifconfig_vlan.py
index fe94a5af4..245453307 100644
--- a/python/vyos/ifconfig_vlan.py
+++ b/python/vyos/ifconfig_vlan.py
@@ -23,7 +23,7 @@ def apply_vlan_config(vlan, config):
to a VLAN interface
"""
- if vlan.__class__ != VLANIf:
+ if not vlan.definition['vlan']:
raise TypeError()
# get DHCP config dictionary and update values