summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-07-19 13:55:51 +0200
committerChristian Poessinger <christian@poessinger.com>2020-07-25 15:35:33 +0200
commit2b1c3dc86fe4033030855d61bf453aa730b6c230 (patch)
treee424d489285918207772bfea1d623b10bf9a97ba /python
parentebefa38b9fa946fde82a4c9b55122c037598143b (diff)
downloadvyos-1x-2b1c3dc86fe4033030855d61bf453aa730b6c230.tar.gz
vyos-1x-2b1c3dc86fe4033030855d61bf453aa730b6c230.zip
vlan: ifconfig: T2653: only enable interface when lower interface is up
A VLAN interface can only be placed in admin up state when the lower interface is up, too. If this is not the case the operating system will throw and exception.
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/interface.py32
1 files changed, 30 insertions, 2 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 689faa22b..be3617f7d 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -17,7 +17,9 @@ import os
import re
import json
import jmespath
+
from copy import deepcopy
+from glob import glob
from ipaddress import IPv4Network
from ipaddress import IPv6Address
@@ -73,8 +75,12 @@ class Interface(Control):
_command_get = {
'admin_state': {
'shellcmd': 'ip -json link show dev {ifname}',
- 'format': lambda j: 'up' if 'UP' in json.loads(j)[0]['flags'] else 'down',
- }
+ 'format': lambda j: 'up' if 'UP' in jmespath.search('[*].flags | [0]', json.loads(j)) else 'down',
+ },
+ 'vlan_protocol': {
+ 'shellcmd': 'ip -json -details link show dev {ifname}',
+ 'format': lambda j: jmespath.search('[*].linkinfo.info_data.protocol | [0]', json.loads(j)),
+ },
}
_command_set = {
@@ -544,6 +550,17 @@ class Interface(Control):
"""
self.set_interface('alias', ifalias)
+ def get_vlan_protocol(self):
+ """
+ Retrieve VLAN protocol in use, this can be 802.1Q, 802.1ad or None
+
+ Example:
+ >>> from vyos.ifconfig import Interface
+ >>> Interface('eth0.10').get_vlan_protocol()
+ '802.1Q'
+ """
+ return self.get_interface('vlan_protocol')
+
def get_admin_state(self):
"""
Get interface administrative state. Function will return 'up' or 'down'
@@ -565,6 +582,17 @@ class Interface(Control):
>>> Interface('eth0').get_admin_state()
'down'
"""
+ # A VLAN interface can only be placed in admin up state when
+ # the lower interface is up, too
+ if self.get_vlan_protocol():
+ lower_interface = glob(f'/sys/class/net/{self.ifname}/lower*/flags')[0]
+ with open(lower_interface, 'r') as f:
+ flags = f.read()
+ # If parent is not up - bail out as we can not bring up the VLAN.
+ # Flags are defined in kernel source include/uapi/linux/if.h
+ if not int(flags, 16) & 1:
+ return None
+
return self.set_interface('admin_state', state)
def set_proxy_arp(self, enable):