]>
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 ifaceobj
.link_kind |
= ifaceLinkKind
.VLAN
99 return [self
._get
_vlan
_raw
_device
(ifaceobj
)]
101 def _bridge_vid_add_del(self
, ifaceobj
, bridgename
, vlanid
,
103 """ If the lower device is a vlan aware bridge, add/del the vlanid
105 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
107 rtnetlink_api
.rtnl_api
.bridge_vlan(add
=True, dev
=bridgename
,
108 vid
=vlanid
, master
=False)
110 rtnetlink_api
.rtnl_api
.bridge_vlan(add
=False, dev
=bridgename
,
111 vid
=vlanid
, master
=False)
113 def _bridge_vid_check(self
, ifaceobj
, ifaceobjcurr
, bridgename
, vlanid
):
114 """ If the lower device is a vlan aware bridge, check if the vlanid
115 is configured on the bridge """
116 if not self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
118 vids
= self
._bridge
_vids
_query
_cache
.get(bridgename
)
120 vids
= self
.ipcmd
.bridge_port_vids_get(bridgename
)
121 self
._bridge
_vids
_query
_cache
[bridgename
] = vids
122 if not vids
or vlanid
not in vids
:
123 ifaceobjcurr
.status
= ifaceStatus
.ERROR
124 ifaceobjcurr
.status_str
= 'bridge vid error'
126 def _up(self
, ifaceobj
):
127 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
129 raise Exception('could not determine vlanid')
130 if self
._handle
_reserved
_vlan
(vlanid
, ifaceobj
.name
):
132 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
133 if not vlanrawdevice
:
134 raise Exception('could not determine vlan raw device')
135 if not self
.PERFMODE
:
136 if not self
.ipcmd
.link_exists(vlanrawdevice
):
137 raise Exception('rawdevice %s not present' %vlanrawdevice
)
138 if self
.ipcmd
.link_exists(ifaceobj
.name
):
139 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
141 rtnetlink_api
.rtnl_api
.create_vlan(vlanrawdevice
,
142 ifaceobj
.name
, vlanid
)
143 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
144 if ifaceobj
.addr_method
== 'manual':
145 rtnetlink_api
.rtnl_api
.link_set(ifaceobj
.name
, "up")
147 def _down(self
, ifaceobj
):
148 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
150 raise Exception('could not determine vlanid')
151 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
152 if not vlanrawdevice
:
153 raise Exception('could not determine vlan raw device')
154 if not self
.PERFMODE
and not self
.ipcmd
.link_exists(ifaceobj
.name
):
157 self
.ipcmd
.link_delete(ifaceobj
.name
)
158 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
, add
=False)
160 self
.log_warn(str(e
))
162 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
163 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
165 if not '.' in ifaceobj
.name
:
166 # if vlan name is not in the dot format, check its running state
167 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobj
.name
)
168 if vlanrawdev
!= ifaceobj
.get_attr_value_first('vlan-raw-device'):
169 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
172 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
174 if vlanid
!= ifaceobj
.get_attr_value_first('vlan-id'):
175 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
177 ifaceobjcurr
.update_config_with_status('vlan-id',
179 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, vlanid
)
181 def _query_running(self
, ifaceobjrunning
):
182 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
184 if not self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
):
186 # If vlan name is not in the dot format, get the
187 # vlan dev and vlan id
188 if not '.' in ifaceobjrunning
.name
:
189 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
190 ifaceobjrunning
.update_config_dict({(k
, v
) for k
, v
in
191 {'vlan-raw-device' : vlanrawdev
,
192 'vlan-id' : vlanid
}.items()
195 _run_ops
= {'pre-up' : _up
,
197 'query-checkcurr' : _query_check
,
198 'query-running' : _query_running
}
201 """ returns list of ops supported by this module """
202 return self
._run
_ops
.keys()
204 def _init_command_handlers(self
):
206 self
.ipcmd
= iproute2(**self
.get_flags())
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
)