]>
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
)
141 if ifupdownConfig
.config
.get('adjust_logical_dev_mtu', '1') != '0' and len(ifaceobj
.lowerifaces
):
142 lower_iface_mtu
= self
.ipcmd
.link_get_mtu(ifaceobj
.lowerifaces
[0], refresh
=True)
143 if not lower_iface_mtu
== self
.ipcmd
.link_get_mtu(ifaceobj
.name
):
144 self
.ipcmd
.link_set_mtu(ifaceobj
.name
, lower_iface_mtu
)
146 netlink
.link_add_vlan(vlanrawdevice
, ifaceobj
.name
, vlanid
)
147 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
)
148 if ifaceobj
.addr_method
== 'manual':
149 netlink
.link_set_updown(ifaceobj
.name
, "up")
151 def _down(self
, ifaceobj
):
152 vlanid
= self
._get
_vlan
_id
(ifaceobj
)
154 raise Exception('could not determine vlanid')
155 vlanrawdevice
= self
._get
_vlan
_raw
_device
(ifaceobj
)
156 if not vlanrawdevice
:
157 raise Exception('could not determine vlan raw device')
158 if (not ifupdownflags
.flags
.PERFMODE
and
159 not self
.ipcmd
.link_exists(ifaceobj
.name
)):
162 self
.ipcmd
.link_delete(ifaceobj
.name
)
163 self
._bridge
_vid
_add
_del
(ifaceobj
, vlanrawdevice
, vlanid
, add
=False)
165 self
.log_warn(str(e
))
167 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
168 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
170 if not '.' in ifaceobj
.name
:
171 # if vlan name is not in the dot format, check its running state
172 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobj
.name
)
173 if vlanrawdev
!= ifaceobj
.get_attr_value_first('vlan-raw-device'):
174 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
177 ifaceobjcurr
.update_config_with_status('vlan-raw-device',
179 vlanid_config
= ifaceobj
.get_attr_value_first('vlan-id')
180 if not vlanid_config
:
181 vlanid_config
= str(self
._get
_vlan
_id
(ifaceobj
))
182 if vlanid
!= vlanid_config
:
183 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 1)
185 ifaceobjcurr
.update_config_with_status('vlan-id', vlanid
, 0)
186 self
._bridge
_vid
_check
(ifaceobj
, ifaceobjcurr
, vlanrawdev
, vlanid
)
188 def _query_running(self
, ifaceobjrunning
):
189 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
191 if not self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
):
193 # If vlan name is not in the dot format, get the
194 # vlan dev and vlan id
195 if not '.' in ifaceobjrunning
.name
:
196 (vlanrawdev
, vlanid
) = self
.ipcmd
.get_vlandev_attrs(ifaceobjrunning
.name
)
197 ifaceobjrunning
.update_config_dict({(k
, v
) for k
, v
in
198 {'vlan-raw-device' : vlanrawdev
,
199 'vlan-id' : vlanid
}.items()
202 _run_ops
= {'pre-up' : _up
,
204 'query-checkcurr' : _query_check
,
205 'query-running' : _query_running
}
208 """ returns list of ops supported by this module """
209 return self
._run
_ops
.keys()
211 def _init_command_handlers(self
):
213 self
.ipcmd
= iproute2()
215 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
216 """ run vlan configuration on the interface object passed as argument
219 **ifaceobj** (object): iface object
221 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
224 **query_ifaceobj** (object): query check ifaceobject. This is only
225 valid when op is 'query-checkcurr'. It is an object same as
226 ifaceobj, but contains running attribute values and its config
227 status. The modules can use it to return queried running state
228 of interfaces. status is success if the running state is same
229 as user required state in ifaceobj. error otherwise.
231 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
233 op_handler
= self
._run
_ops
.get(operation
)
236 if (operation
!= 'query-running' and
237 not self
._is
_vlan
_device
(ifaceobj
)):
239 self
._init
_command
_handlers
()
240 if operation
== 'query-checkcurr':
241 op_handler(self
, ifaceobj
, query_ifaceobj
)
243 op_handler(self
, ifaceobj
)