summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig/section.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/vyos/ifconfig/section.py')
-rw-r--r--python/vyos/ifconfig/section.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py
new file mode 100644
index 000000000..234c9a6cc
--- /dev/null
+++ b/python/vyos/ifconfig/section.py
@@ -0,0 +1,134 @@
+# 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 Section:
+ # the known interface prefixes
+ _prefixes = {}
+ _classes = []
+
+ # 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):
+ """
+ A function to use as decorator the interfaces classes
+ It register the prefix for the interface (eth, dum, vxlan, ...)
+ with the class which can handle it (EthernetIf, DummyIf,VXLANIf, ...)
+ """
+ if not klass.definition.get('prefixes',[]):
+ raise RuntimeError(f'valid interface prefixes not defined for {klass.__name__}')
+
+ cls._classes.append(klass)
+
+ 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 the number at the end of interface name
+ name: name of the interface
+ vlan: if vlan is True, do not stop at the vlan number
+ """
+ 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: name of the interface (eth0, dum1, ...)
+ vlan: should we try try to remove the VLAN from the number
+ """
+ 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].definition['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 _intf_under_section (cls,section=''):
+ """
+ return a generator with the name of the interface which are under a section
+ """
+ interfaces = netifaces.interfaces()
+
+ for ifname in interfaces:
+ # 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
+
+ ifsection = cls.section(ifname)
+ if not ifsection:
+ continue
+
+ if section and ifsection != section:
+ continue
+
+ yield ifname
+
+ @classmethod
+ def interfaces(cls, section=''):
+ """
+ return a list of the name of the interface which are under a section
+ if no section is provided, then it returns all configured interfaces
+ """
+ return list(cls._intf_under_section(section))
+
+ @classmethod
+ def _intf_with_feature(cls, feature=''):
+ """
+ return a generator with the name of the interface which have
+ a particular feature set in their definition such as:
+ bondable, broadcast, bridgeable, ...
+ """
+ for klass in cls._classes:
+ if klass.definition[feature]:
+ yield klass.definition['section']
+
+ @classmethod
+ def feature(cls, feature=''):
+ """
+ return list with the name of the interface which have
+ a particular feature set in their definition such as:
+ bondable, broadcast, bridgeable, ...
+ """
+ return list(cls._intf_with_feature(feature))