]> git.proxmox.com Git - mirror_ifupdown2.git/blob - addons/vlan.py
Move ifupdown2addons into ifupdown2 pacakge
[mirror_ifupdown2.git] / addons / vlan.py
1 #!/usr/bin/python
2 #
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
5 #
6
7 from ifupdown.iface import *
8 from ifupdownaddons.modulebase import moduleBase
9 from ifupdownaddons.iproute2 import iproute2
10 import logging
11
12 class vlan(moduleBase):
13 """ ifupdown2 addon module to configure vlans """
14
15 _modinfo = {'mhelp' : 'vlan module configures vlan interfaces.' +
16 'This module understands vlan interfaces with dot ' +
17 'notations. eg swp1.100. Vlan interfaces with any ' +
18 'other names need to have raw device and vlan id ' +
19 'attributes',
20 'attrs' : {
21 'vlan-raw-device' :
22 {'help' : 'vlan raw device'},
23 'vlan-id' :
24 {'help' : 'vlan id'}}}
25
26 def __init__(self, *args, **kargs):
27 moduleBase.__init__(self, *args, **kargs)
28 self.ipcmd = None
29
30 def _is_vlan_device(self, ifaceobj):
31 vlan_raw_device = ifaceobj.get_attr_value_first('vlan-raw-device')
32 if vlan_raw_device:
33 return True
34 elif '.' in ifaceobj.name:
35 return True
36 return False
37
38 def _get_vlan_id(self, ifaceobj):
39 """ Derives vlanid from iface name
40
41 Example:
42 Returns 1 for ifname vlan0001 returns 1
43 Returns 1 for ifname vlan1
44 Returns 1 for ifname eth0.1
45
46 Returns -1 if vlan id cannot be determined
47 """
48 vid_str = ifaceobj.get_attr_value_first('vlan-id')
49 try:
50 if vid_str: return int(vid_str)
51 except:
52 return -1
53
54 if ifaceobj.name.startswith('vlan'):
55 vid_str = ifaceobj.name[4:]
56 elif '.' in ifaceobj.name:
57 vid_str = ifaceobj.name.split('.', 1)[1]
58 else:
59 return -1
60 try:
61 vid = int(vid_str)
62 except:
63 return -1
64 return vid
65
66 def _is_vlan_by_name(self, ifacename):
67 return '.' in ifacename
68
69 def _get_vlan_raw_device_from_ifacename(self, ifacename):
70 """ Returns vlan raw device from ifname
71 Example:
72 Returns eth0 for ifname eth0.100
73
74 Returns None if vlan raw device name cannot
75 be determined
76 """
77 vlist = ifacename.split('.', 1)
78 if len(vlist) == 2:
79 return vlist[0]
80 return None
81
82 def _get_vlan_raw_device(self, ifaceobj):
83 vlan_raw_device = ifaceobj.get_attr_value_first('vlan-raw-device')
84 if vlan_raw_device:
85 return vlan_raw_device
86 return self._get_vlan_raw_device_from_ifacename(ifaceobj.name)
87
88 def get_dependent_ifacenames(self, ifaceobj, ifaceobjs_all=None):
89 if not self._is_vlan_device(ifaceobj):
90 return None
91 return [self._get_vlan_raw_device(ifaceobj)]
92
93 def _up(self, ifaceobj):
94 vlanid = self._get_vlan_id(ifaceobj)
95 if vlanid == -1:
96 raise Exception('could not determine vlanid')
97 vlanrawdevice = self._get_vlan_raw_device(ifaceobj)
98 if not vlanrawdevice:
99 raise Exception('could not determine vlan raw device')
100 self.ipcmd.link_create_vlan(ifaceobj.name,
101 vlanrawdevice, vlanid)
102
103 def _down(self, ifaceobj):
104 vlanid = self._get_vlan_id(ifaceobj)
105 if vlanid == -1:
106 raise Exception('could not determine vlanid')
107 vlan_raw_device = self._get_vlan_raw_device(ifaceobj)
108 if not vlan_raw_device:
109 raise Exception('could not determine vlan raw device')
110 if not self.PERFMODE and not self.ipcmd.link_exists(ifaceobj.name):
111 return
112 try:
113 self.ipcmd.link_delete(ifaceobj.name)
114 except Exception, e:
115 self.log_warn(str(e))
116
117 def _query_check(self, ifaceobj, ifaceobjcurr):
118 if not self.ipcmd.link_exists(ifaceobj.name):
119 ifaceobjcurr.status = ifaceStatus.NOTFOUND
120 return
121 if not '.' in ifaceobj.name:
122 # if vlan name is not in the dot format, check its running state
123 (vlanrawdev, vlanid) = self.ipcmd.get_vlandev_attrs(ifaceobj.name)
124 if vlanrawdev != ifaceobj.get_attr_value_first('vlan-raw-device'):
125 ifaceobjcurr.update_config_with_status('vlan-raw-device',
126 vlanrawdev, 1)
127 else:
128 ifaceobjcurr.update_config_with_status('vlan-raw-device',
129 vlanrawdev, 0)
130 if vlanid != ifaceobj.get_attr_value_first('vlan-id'):
131 ifaceobjcurr.update_config_with_status('vlan-id', vlanid, 1)
132 else:
133 ifaceobjcurr.update_config_with_status('vlan-id',
134 vlanid, 0)
135
136 def _query_running(self, ifaceobjrunning):
137 if not self.ipcmd.link_exists(ifaceobjrunning.name):
138 if self._is_vlan_by_name(ifaceobjrunning.name):
139 ifaceobjcurr.status = ifaceStatus.NOTFOUND
140 return
141 if not self.ipcmd.get_vlandev_attrs(ifaceobjrunning.name):
142 return
143 # If vlan name is not in the dot format, get the
144 # vlan dev and vlan id
145 if not '.' in ifaceobjrunning.name:
146 (vlanrawdev, vlanid) = self.ipcmd.get_vlandev_attrs(ifaceobjrunning.name)
147 ifaceobjrunning.update_config_dict({(k, v) for k, v in
148 {'vlan-raw-device' : vlanrawdev,
149 'vlan-id' : vlanid}.items()
150 if v})
151
152 _run_ops = {'pre-up' : _up,
153 'post-down' : _down,
154 'query-checkcurr' : _query_check,
155 'query-running' : _query_running}
156
157 def get_ops(self):
158 """ returns list of ops supported by this module """
159 return self._run_ops.keys()
160
161 def _init_command_handlers(self):
162 if not self.ipcmd:
163 self.ipcmd = iproute2(**self.get_flags())
164
165 def run(self, ifaceobj, operation, query_ifaceobj=None):
166 """ run vlan configuration on the interface object passed as argument
167
168 Args:
169 **ifaceobj** (object): iface object
170
171 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
172 'query-running'
173 Kwargs:
174 **query_ifaceobj** (object): query check ifaceobject. This is only
175 valid when op is 'query-checkcurr'. It is an object same as
176 ifaceobj, but contains running attribute values and its config
177 status. The modules can use it to return queried running state
178 of interfaces. status is success if the running state is same
179 as user required state in ifaceobj. error otherwise.
180 """
181 op_handler = self._run_ops.get(operation)
182 if not op_handler:
183 return
184 if (operation != 'query-running' and
185 not self._is_vlan_device(ifaceobj)):
186 return
187 self._init_command_handlers()
188 if operation == 'query-checkcurr':
189 op_handler(self, ifaceobj, query_ifaceobj)
190 else:
191 op_handler(self, ifaceobj)