]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - addons/vlan.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
7 from ifupdown
.iface
import *
8 from ifupdownaddons
.modulebase
import moduleBase
9 from ifupdownaddons
.iproute2
import iproute2
10 import ifupdown
.ifupdownconfig
as ifupdownConfig
12 from ifupdown
.netlink
import netlink
13 import ifupdown
.ifupdownflags
as ifupdownflags
17 class vlan(moduleBase
):
18 """ ifupdown2 addon module to configure vlans """
20 _modinfo
= {'mhelp' : 'vlan module configures vlan interfaces.' +
21 'This module understands vlan interfaces with dot ' +
22 'notations. eg swp1.100. Vlan interfaces with any ' +
23 'other names need to have raw device and vlan id ' +
27 {'help' : 'vlan raw device',
28 'validvals': ['<interface>']},
31 'validrange' : ['0', '4096']}}}
34 def __init__(self
, *args
, **kargs
):
35 moduleBase
.__init
__(self
, *args
, **kargs
)
37 self
._bridge
_vids
_query
_cache
= {}
38 self
._resv
_vlan
_range
= self
._get
_reserved
_vlan
_range
()
39 self
.logger
.debug('%s: using reserved vlan range %s'
40 %(self
.__class
__.__name
__, str(self
._resv
_vlan
_range
)))
42 def _is_vlan_device(self
, ifaceobj
):
43 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
46 elif '.' in ifaceobj
.name
:
50 def _get_vlan_id(self
, ifaceobj
):
51 """ Derives vlanid from iface name
54 Returns 1 for ifname vlan0001 returns 1
55 Returns 1 for ifname vlan1
56 Returns 1 for ifname eth0.1
58 Returns -1 if vlan id cannot be determined
60 vid_str
= ifaceobj
.get_attr_value_first('vlan-id')
62 if vid_str
: return int(vid_str
)
66 if '.' in ifaceobj
.name
:
67 vid_str
= ifaceobj
.name
.split('.', 1)[1]
68 elif ifaceobj
.name
.startswith('vlan'):
69 vid_str
= ifaceobj
.name
[4:]
78 def _is_vlan_by_name(self
, ifacename
):
79 return '.' in ifacename
81 def _get_vlan_raw_device_from_ifacename(self
, ifacename
):
82 """ Returns vlan raw device from ifname
84 Returns eth0 for ifname eth0.100
86 Returns None if vlan raw device name cannot
89 vlist
= ifacename
.split('.', 1)
94 def _get_vlan_raw_device(self
, ifaceobj
):
95 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
97 return vlan_raw_device
98 return self
._get
_vlan
_raw
_device
_from
_ifacename
(ifaceobj
.name
)
100 def get_dependent_ifacenames(self
, ifaceobj
, ifaceobjs_all
=None):
101 if not self
._is
_vlan
_device
(ifaceobj
):
103 ifaceobj
.link_kind |
= ifaceLinkKind
.VLAN
104 return [self
._get
_vlan
_raw
_device
(ifaceobj
)]
106 def _bridge_vid_add_del(self
, ifaceobj
, bridgename
, vlanid
,
108 """ If the lower device is a vlan aware bridge, add/del the vlanid
110 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
112 netlink
.link_add_bridge_vlan(bridgename
, vlanid
)
114 netlink
.link_del_bridge_vlan(bridgename
, vlanid
)
116 def _bridge_vid_check(self
, ifaceobj
, ifaceobjcurr
, bridgename
, vlanid
):
117 """ If the lower device is a vlan aware bridge, check if the vlanid
118 is configured on the bridge """
119 if not self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
121 vids
= self
._bridge
_vids
_query
_cache
.get(bridgename
)
123 vids
= self
.ipcmd
.bridge_port_vids_get(bridgename
)
124 self
._bridge
_vids
_query
_cache
[bridgename
] = vids
125 if not vids
or vlanid
not in vids
:
126 ifaceobjcurr
.status
= ifaceStatus
.ERROR
127 ifaceobjcurr
.status_str
= 'bridge vid error'
129 def _up(self
, ifaceobj
):
130 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
132 raise Exception('could not determine vlanid')
133 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
134 if not vlanrawdevice
:
135 raise Exception('could not determine vlan raw device')
136 if not ifupdownflags
.flags
.PERFMODE
:
137 if not self
.ipcmd
.link_exists(vlanrawdevice
):
138 raise Exception('rawdevice %s not present' %vlanrawdevice
)
139 if self
.ipcmd
.link_exists(ifaceobj
.name
):
140 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
142 netlink
.link_add_vlan(vlanrawdevice
, ifaceobj
.name
, vlanid
)
143 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
145 def _down(self
, ifaceobj
):
146 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
148 raise Exception('could not determine vlanid')
149 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
150 if not vlanrawdevice
:
151 raise Exception('could not determine vlan raw device')
152 if (not ifupdownflags
.flags
.PERFMODE
and
153 not self
.ipcmd
.link_exists(ifaceobj
.name
)):
156 self
.ipcmd
.link_delete(ifaceobj
.name
)
157 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
, add
=False)
159 self
.log_warn(str(e
))
161 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
162 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
164 if not '.' in ifaceobj
.name
:
165 # if vlan name is not in the dot format, check its running state
166 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobj
.name
)
167 if vlanrawdev
!= ifaceobj
.get_attr_value_first('vlan-raw-device'):
168 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
171 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
173 vlanid_config
= ifaceobj
.get_attr_value_first('vlan-id')
174 if not vlanid_config
:
175 vlanid_config
= str(self
._get
_vlan
_id
(ifaceobj
))
176 if vlanid
!= vlanid_config
:
177 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
179 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 0)
180 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, vlanid
)
182 def _query_running(self
, ifaceobjrunning
):
183 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
185 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
188 # If vlan name is not in the dot format, get the
189 # vlan dev and vlan id
190 if not '.' in ifaceobjrunning
.name
:
191 ifaceobjrunning
.update_config_dict({(k
, v
) for k
, v
in
192 {'vlan-raw-device' : vlanrawdev
,
193 'vlan-id' : vlanid
}.items()
196 _run_ops
= {'pre-up' : _up
,
198 'query-checkcurr' : _query_check
,
199 'query-running' : _query_running
}
202 """ returns list of ops supported by this module """
203 return self
._run
_ops
.keys()
205 def _init_command_handlers(self
):
207 self
.ipcmd
= iproute2()
209 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
210 """ run vlan configuration on the interface object passed as argument
213 **ifaceobj** (object): iface object
215 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
218 **query_ifaceobj** (object): query check ifaceobject. This is only
219 valid when op is 'query-checkcurr'. It is an object same as
220 ifaceobj, but contains running attribute values and its config
221 status. The modules can use it to return queried running state
222 of interfaces. status is success if the running state is same
223 as user required state in ifaceobj. error otherwise.
225 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
227 op_handler
= self
._run
_ops
.get(operation
)
230 if (operation
!= 'query-running' and
231 not self
._is
_vlan
_device
(ifaceobj
)):
233 self
._init
_command
_handlers
()
234 if operation
== 'query-checkcurr':
235 op_handler(self
, ifaceobj
, query_ifaceobj
)
237 op_handler(self
, ifaceobj
)