]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/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
.rtnetlink_api
as rtnetlink_api
14 class vlan(moduleBase
):
15 """ ifupdown2 addon module to configure vlans """
17 _modinfo
= {'mhelp' : 'vlan module configures vlan interfaces.' +
18 'This module understands vlan interfaces with dot ' +
19 'notations. eg swp1.100. Vlan interfaces with any ' +
20 'other names need to have raw device and vlan id ' +
24 {'help' : 'vlan raw device'},
26 {'help' : 'vlan id'}}}
29 def __init__(self
, *args
, **kargs
):
30 moduleBase
.__init
__(self
, *args
, **kargs
)
32 self
._bridge
_vids
_query
_cache
= {}
33 self
._resv
_vlan
_range
= self
._get
_reserved
_vlan
_range
()
34 self
.logger
.debug('%s: using reserved vlan range %s'
35 %(self
.__class
__.__name
__, str(self
._resv
_vlan
_range
)))
37 def _is_vlan_device(self
, ifaceobj
):
38 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
41 elif '.' in ifaceobj
.name
:
45 def _get_vlan_id(self
, ifaceobj
):
46 """ Derives vlanid from iface name
49 Returns 1 for ifname vlan0001 returns 1
50 Returns 1 for ifname vlan1
51 Returns 1 for ifname eth0.1
53 Returns -1 if vlan id cannot be determined
55 vid_str
= ifaceobj
.get_attr_value_first('vlan-id')
57 if vid_str
: return int(vid_str
)
61 if '.' in ifaceobj
.name
:
62 vid_str
= ifaceobj
.name
.split('.', 1)[1]
63 elif ifaceobj
.name
.startswith('vlan'):
64 vid_str
= ifaceobj
.name
[4:]
73 def _is_vlan_by_name(self
, ifacename
):
74 return '.' in ifacename
76 def _get_vlan_raw_device_from_ifacename(self
, ifacename
):
77 """ Returns vlan raw device from ifname
79 Returns eth0 for ifname eth0.100
81 Returns None if vlan raw device name cannot
84 vlist
= ifacename
.split('.', 1)
89 def _get_vlan_raw_device(self
, ifaceobj
):
90 vlan_raw_device
= ifaceobj
.get_attr_value_first('vlan-raw-device')
92 return vlan_raw_device
93 return self
._get
_vlan
_raw
_device
_from
_ifacename
(ifaceobj
.name
)
95 def get_dependent_ifacenames(self
, ifaceobj
, ifaceobjs_all
=None):
96 if not self
._is
_vlan
_device
(ifaceobj
):
98 return [self
._get
_vlan
_raw
_device
(ifaceobj
)]
100 def _bridge_vid_add_del(self
, ifaceobj
, bridgename
, vlanid
,
102 """ If the lower device is a vlan aware bridge, add/del the vlanid
104 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
106 rtnetlink_api
.rtnl_api
.bridge_vlan(add
=True, dev
=bridgename
,
107 vid
=vlanid
, master
=False)
109 rtnetlink_api
.rtnl_api
.bridge_vlan(add
=False, dev
=bridgename
,
110 vid
=vlanid
, master
=False)
112 def _bridge_vid_check(self
, ifaceobj
, ifaceobjcurr
, bridgename
, vlanid
):
113 """ If the lower device is a vlan aware bridge, check if the vlanid
114 is configured on the bridge """
115 if not self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
117 vids
= self
._bridge
_vids
_query
_cache
.get(bridgename
)
119 vids
= self
.ipcmd
.bridge_port_vids_get(bridgename
)
120 self
._bridge
_vids
_query
_cache
[bridgename
] = vids
121 if not vids
or vlanid
not in vids
:
122 ifaceobjcurr
.status
= ifaceStatus
.ERROR
123 ifaceobjcurr
.status_str
= 'bridge vid error'
125 def _up(self
, ifaceobj
):
126 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
128 raise Exception('could not determine vlanid')
129 if self
._handle
_reserved
_vlan
(vlanid
, ifaceobj
.name
):
131 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
132 if not vlanrawdevice
:
133 raise Exception('could not determine vlan raw device')
134 if not self
.PERFMODE
:
135 if not self
.ipcmd
.link_exists(vlanrawdevice
):
136 raise Exception('rawdevice %s not present' %vlanrawdevice
)
137 if self
.ipcmd
.link_exists(ifaceobj
.name
):
138 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
140 rtnetlink_api
.rtnl_api
.create_vlan(vlanrawdevice
,
141 ifaceobj
.name
, vlanid
)
142 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
143 if ifaceobj
.addr_method
== 'manual':
144 rtnetlink_api
.rtnl_api
.link_set(ifaceobj
.name
, "up")
146 def _down(self
, ifaceobj
):
147 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
149 raise Exception('could not determine vlanid')
150 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
151 if not vlanrawdevice
:
152 raise Exception('could not determine vlan raw device')
153 if not self
.PERFMODE
and 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 if vlanid
!= ifaceobj
.get_attr_value_first('vlan-id'):
174 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
176 ifaceobjcurr
.update_config_with_status('vlan-id',
178 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, vlanid
)
180 def _query_running(self
, ifaceobjrunning
):
181 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
183 if not self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
):
185 # If vlan name is not in the dot format, get the
186 # vlan dev and vlan id
187 if not '.' in ifaceobjrunning
.name
:
188 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
189 ifaceobjrunning
.update_config_dict({(k
, v
) for k
, v
in
190 {'vlan-raw-device' : vlanrawdev
,
191 'vlan-id' : vlanid
}.items()
194 _run_ops
= {'pre-up' : _up
,
196 'query-checkcurr' : _query_check
,
197 'query-running' : _query_running
}
200 """ returns list of ops supported by this module """
201 return self
._run
_ops
.keys()
203 def _init_command_handlers(self
):
205 self
.ipcmd
= iproute2(**self
.get_flags())
208 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
209 """ run vlan configuration on the interface object passed as argument
212 **ifaceobj** (object): iface object
214 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
217 **query_ifaceobj** (object): query check ifaceobject. This is only
218 valid when op is 'query-checkcurr'. It is an object same as
219 ifaceobj, but contains running attribute values and its config
220 status. The modules can use it to return queried running state
221 of interfaces. status is success if the running state is same
222 as user required state in ifaceobj. error otherwise.
224 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
226 op_handler
= self
._run
_ops
.get(operation
)
229 if (operation
!= 'query-running' and
230 not self
._is
_vlan
_device
(ifaceobj
)):
232 self
._init
_command
_handlers
()
233 if operation
== 'query-checkcurr':
234 op_handler(self
, ifaceobj
, query_ifaceobj
)
236 op_handler(self
, ifaceobj
)