]>
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
:
132 if not self
.ipcmd
.link_exists(vlanrawdevice
):
133 raise Exception('rawdevice %s not present' %vlanrawdevice
)
134 if self
.ipcmd
.link_exists(ifaceobj
.name
):
135 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
138 netlink
.link_add_vlan(vlanrawdevice
, ifaceobj
.name
, vlanid
, vlan_protocol
)
139 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
141 def _down(self
, ifaceobj
):
142 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
144 raise Exception('could not determine vlanid')
145 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
146 if not vlanrawdevice
:
147 raise Exception('could not determine vlan raw device')
148 if (not ifupdownflags
.flags
.PERFMODE
and
149 not self
.ipcmd
.link_exists(ifaceobj
.name
)):
152 self
.ipcmd
.link_delete(ifaceobj
.name
)
153 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
, add
=False)
155 self
.log_warn(str(e
))
157 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
158 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
160 if not '.' in ifaceobj
.name
:
161 # if vlan name is not in the dot format, check its running state
162 (vlanrawdev
, vlanid
, protocol
) = self
.ipcmd
.get_vlandev_attrs(ifaceobj
.name
)
163 if vlanrawdev
!= ifaceobj
.get_attr_value_first('vlan-raw-device'):
164 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
167 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
169 vlanid_config
= ifaceobj
.get_attr_value_first('vlan-id')
170 if not vlanid_config
:
171 vlanid_config
= str(self
._get
_vlan
_id
(ifaceobj
))
172 if vlanid
!= vlanid_config
:
173 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
175 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 0)
176 protocol_config
= ifaceobj
.get_attr_value_first('vlan-protocol')
178 if protocol_config
.upper() != protocol
.upper():
179 ifaceobjcurr
.update_config_with_status('vlan-protocol',
182 ifaceobjcurr
.update_config_with_status('vlan-protocol',
184 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, int(vlanid
))
186 def _query_running(self
, ifaceobjrunning
):
187 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
189 (vlanrawdev
, vlanid
, protocol
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
192 # If vlan name is not in the dot format, get the
193 # vlan dev and vlan id
194 if not '.' in ifaceobjrunning
.name
:
195 ifaceobjrunning
.update_config_dict({k
: [v
] for k
, v
in
196 {'vlan-raw-device' : vlanrawdev
,
198 'vlan-protocol' : protocol
}.items()
201 _run_ops
= {'pre-up' : _up
,
203 'query-checkcurr' : _query_check
,
204 'query-running' : _query_running
}
207 """ returns list of ops supported by this module """
208 return self
._run
_ops
.keys()
210 def _init_command_handlers(self
):
212 self
.ipcmd
= LinkUtils()
214 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
215 """ run vlan configuration on the interface object passed as argument
218 **ifaceobj** (object): iface object
220 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
223 **query_ifaceobj** (object): query check ifaceobject. This is only
224 valid when op is 'query-checkcurr'. It is an object same as
225 ifaceobj, but contains running attribute values and its config
226 status. The modules can use it to return queried running state
227 of interfaces. status is success if the running state is same
228 as user required state in ifaceobj. error otherwise.
230 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
232 op_handler
= self
._run
_ops
.get(operation
)
235 if (operation
!= 'query-running' and
236 not self
._is
_vlan
_device
(ifaceobj
)):
238 self
._init
_command
_handlers
()
239 if operation
== 'query-checkcurr':
240 op_handler(self
, ifaceobj
, query_ifaceobj
)
242 op_handler(self
, ifaceobj
)