]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/vlan.py
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
8 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
10 from ifupdown2
.ifupdown
.iface
import *
11 from ifupdown2
.ifupdown
.netlink
import netlink
13 from ifupdown2
.ifupdownaddons
.LinkUtils
import LinkUtils
14 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
16 import ifupdown
.ifupdownflags
as ifupdownflags
18 from ifupdown
.iface
import *
19 from ifupdown
.netlink
import netlink
21 from ifupdownaddons
.LinkUtils
import LinkUtils
22 from ifupdownaddons
.modulebase
import moduleBase
26 class vlan(moduleBase
):
27 """ ifupdown2 addon module to configure vlans """
29 _modinfo
= {'mhelp' : 'vlan module configures vlan interfaces.' +
30 'This module understands vlan interfaces with dot ' +
31 'notations. eg swp1.100. Vlan interfaces with any ' +
32 'other names need to have raw device and vlan id ' +
36 {'help' : 'vlan raw device',
37 'validvals': ['<interface>']},
40 'validrange' : ['0', '4096']},
42 {'help' : 'vlan protocol',
44 'validvals': ['802.1q', '802.1ad'],
45 'example' : ['vlan-protocol 802.1q']},
49 def __init__(self
, *args
, **kargs
):
50 moduleBase
.__init
__(self
, *args
, **kargs
)
53 def _is_vlan_device(self
, ifaceobj
):
54 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
57 elif '.' in ifaceobj
.name
:
61 def _is_vlan_by_name(self
, ifacename
):
62 return '.' in ifacename
64 def _get_vlan_raw_device_from_ifacename(self
, ifacename
):
65 """ Returns vlan raw device from ifname
67 Returns eth0 for ifname eth0.100
68 Returns eth0.100 for ifname eth0.100.200
69 Returns None if vlan raw device name cannot
72 vlist
= ifacename
.split('.', 2)
76 return vlist
[0] + "." + vlist
[1]
79 def _get_vlan_raw_device(self
, ifaceobj
):
80 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
82 return vlan_raw_device
83 return self
._get
_vlan
_raw
_device
_from
_ifacename
(ifaceobj
.name
)
85 def get_dependent_ifacenames(self
, ifaceobj
, ifaceobjs_all
=None):
86 if not self
._is
_vlan
_device
(ifaceobj
):
88 ifaceobj
.link_kind |
= ifaceLinkKind
.VLAN
89 return [self
._get
_vlan
_raw
_device
(ifaceobj
)]
91 def _bridge_vid_add_del(self
, ifaceobj
, bridgename
, vlanid
,
93 """ If the lower device is a vlan aware bridge, add/del the vlanid
95 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
97 netlink
.link_add_bridge_vlan(bridgename
, vlanid
)
99 netlink
.link_del_bridge_vlan(bridgename
, vlanid
)
101 def _bridge_vid_check(self
, ifaceobj
, ifaceobjcurr
, bridgename
, vlanid
):
102 """ If the lower device is a vlan aware bridge, check if the vlanid
103 is configured on the bridge """
104 if not self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
106 vids
= self
.ipcmd
.bridge_vlan_get_vids(bridgename
)
107 if not vids
or vlanid
not in vids
:
108 ifaceobjcurr
.status
= ifaceStatus
.ERROR
109 ifaceobjcurr
.status_str
= 'bridge vid error'
111 def _up(self
, ifaceobj
):
112 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
114 raise Exception('could not determine vlanid')
115 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
116 if not vlanrawdevice
:
117 raise Exception('could not determine vlan raw device')
119 vlan_protocol
= ifaceobj
.get_attr_value_first('vlan-protocol')
120 cached_vlan_protocol
= self
.ipcmd
.get_vlan_protocol(ifaceobj
.name
)
122 if not vlan_protocol
:
123 vlan_protocol
= self
.get_attr_default_value('vlan-protocol')
125 if cached_vlan_protocol
and vlan_protocol
.lower() != cached_vlan_protocol
.lower():
126 raise Exception('%s: cannot change vlan-protocol to %s: operation not supported. '
127 'Please delete the device with \'ifdown %s\' and recreate it to '
129 % (ifaceobj
.name
, vlan_protocol
, ifaceobj
.name
))
131 if not ifupdownflags
.flags
.PERFMODE
:
133 vlan_exists
= self
.ipcmd
.link_exists(ifaceobj
.name
)
136 user_vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
137 cached_vlan_raw_device
= self
.ipcmd
.cache_get('link', [ifaceobj
.name
, 'link'])
139 if cached_vlan_raw_device
!= user_vlan_raw_device
:
140 raise Exception('%s: cannot change vlan-raw-device from %s to %s: operation not supported. '
141 'Please delete the device with \'ifdown %s\' and recreate it to apply the change.'
142 % (ifaceobj
.name
, cached_vlan_raw_device
, user_vlan_raw_device
, ifaceobj
.name
))
144 if not self
.ipcmd
.link_exists(vlanrawdevice
):
145 raise Exception('rawdevice %s not present' %vlanrawdevice
)
147 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
150 netlink
.link_add_vlan(vlanrawdevice
, ifaceobj
.name
, vlanid
, vlan_protocol
)
151 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
153 def _down(self
, ifaceobj
):
154 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
156 raise Exception('could not determine vlanid')
157 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
158 if not vlanrawdevice
:
159 raise Exception('could not determine vlan raw device')
160 if (not ifupdownflags
.flags
.PERFMODE
and
161 not self
.ipcmd
.link_exists(ifaceobj
.name
)):
164 self
.ipcmd
.link_delete(ifaceobj
.name
)
165 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
, add
=False)
167 self
.log_warn(str(e
))
169 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
170 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
172 if not '.' in ifaceobj
.name
:
173 # if vlan name is not in the dot format, check its running state
174 (vlanrawdev
, vlanid
, protocol
) = self
.ipcmd
.get_vlandev_attrs(ifaceobj
.name
)
175 if vlanrawdev
!= ifaceobj
.get_attr_value_first('vlan-raw-device'):
176 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
179 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
181 vlanid_config
= ifaceobj
.get_attr_value_first('vlan-id')
182 if not vlanid_config
:
183 vlanid_config
= str(self
._get
_vlan
_id
(ifaceobj
))
184 if vlanid
!= vlanid_config
:
185 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
187 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 0)
188 protocol_config
= ifaceobj
.get_attr_value_first('vlan-protocol')
190 if protocol_config
.upper() != protocol
.upper():
191 ifaceobjcurr
.update_config_with_status('vlan-protocol',
194 ifaceobjcurr
.update_config_with_status('vlan-protocol',
196 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, int(vlanid
))
198 def _query_running(self
, ifaceobjrunning
):
199 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
201 (vlanrawdev
, vlanid
, protocol
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
204 # If vlan name is not in the dot format, get the
205 # vlan dev and vlan id
206 if not '.' in ifaceobjrunning
.name
:
207 ifaceobjrunning
.update_config_dict({k
: [v
] for k
, v
in
208 {'vlan-raw-device' : vlanrawdev
,
210 'vlan-protocol' : protocol
}.items()
213 _run_ops
= {'pre-up' : _up
,
215 'query-checkcurr' : _query_check
,
216 'query-running' : _query_running
}
219 """ returns list of ops supported by this module """
220 return self
._run
_ops
.keys()
222 def _init_command_handlers(self
):
224 self
.ipcmd
= LinkUtils()
226 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
227 """ run vlan configuration on the interface object passed as argument
230 **ifaceobj** (object): iface object
232 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
235 **query_ifaceobj** (object): query check ifaceobject. This is only
236 valid when op is 'query-checkcurr'. It is an object same as
237 ifaceobj, but contains running attribute values and its config
238 status. The modules can use it to return queried running state
239 of interfaces. status is success if the running state is same
240 as user required state in ifaceobj. error otherwise.
242 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
244 op_handler
= self
._run
_ops
.get(operation
)
247 if (operation
!= 'query-running' and
248 not self
._is
_vlan
_device
(ifaceobj
)):
250 self
._init
_command
_handlers
()
251 if operation
== 'query-checkcurr':
252 op_handler(self
, ifaceobj
, query_ifaceobj
)
254 op_handler(self
, ifaceobj
)