]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/bridgevlan.py
ifupdown2 2.0.0 release
[mirror_ifupdown2.git] / ifupdown2 / addons / bridgevlan.py
1 #!/usr/bin/python
2 #
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
5 #
6
7 try:
8 from ifupdown2.ifupdown.iface import *
9
10 from ifupdown2.ifupdownaddons.LinkUtils import LinkUtils
11 from ifupdown2.ifupdownaddons.modulebase import moduleBase
12
13 import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
14 except ImportError:
15 from ifupdown.iface import *
16
17 from ifupdownaddons.LinkUtils import LinkUtils
18 from ifupdownaddons.modulebase import moduleBase
19
20 import ifupdown.ifupdownflags as ifupdownflags
21
22
23 class bridgevlan(moduleBase):
24 """ ifupdown2 addon module to configure vlan attributes on a vlan
25 aware bridge """
26
27 _modinfo = {'mhelp' : 'bridgevlan module configures vlan attributes ' +
28 'on a vlan aware bridge. This module only ' +
29 'understands vlan interface name ' +
30 'with dot notations. eg br0.100. where br0 is the ' +
31 'vlan aware bridge this config is for',
32 'attrs' : {
33 'bridge-igmp-querier-src' :
34 { 'help' : 'bridge igmp querier src. Must be ' +
35 'specified under the vlan interface',
36 'validvals' : ['<ipv4>', ],
37 'example' : ['bridge-igmp-querier-src 172.16.101.1']}}}
38
39 def __init__(self, *args, **kargs):
40 moduleBase.__init__(self, *args, **kargs)
41 self.brctlcmd = None
42 self.ipcmd = None
43
44 def _is_bridge_vlan_device(self, ifaceobj):
45 if ifaceobj.type == ifaceType.BRIDGE_VLAN:
46 return True
47 return False
48
49 def _get_bridge_n_vlan(self, ifaceobj):
50 vlist = ifaceobj.name.split('.', 1)
51 if len(vlist) == 2:
52 return (vlist[0], vlist[1])
53 return None
54
55 def _get_bridgename(self, ifaceobj):
56 vlist = ifaceobj.name.split('.', 1)
57 if len(vlist) == 2:
58 return vlist[0]
59 return None
60
61 def get_dependent_ifacenames(self, ifaceobj, ifaceobjs_all=None):
62 if not self._is_bridge_vlan_device(ifaceobj):
63 return None
64 return [self._get_bridgename(ifaceobj)]
65
66 def _up(self, ifaceobj):
67 try:
68 (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
69 vlanid = int(vlan, 10)
70 except:
71 self.log_error('%s: bridge vlan interface name ' %ifaceobj.name +
72 'does not correspond to format (eg. br0.100)', ifaceobj)
73 raise
74
75 if not self.ipcmd.link_exists(bridgename):
76 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
77 # bridgename))
78 return
79
80 running_mcqv4src = {}
81 if not ifupdownflags.flags.PERFMODE:
82 running_mcqv4src = self.brctlcmd.bridge_get_mcqv4src(bridgename)
83 if running_mcqv4src:
84 r_mcqv4src = running_mcqv4src.get(vlan)
85 else:
86 r_mcqv4src = None
87 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
88 if not mcqv4src:
89 if r_mcqv4src:
90 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
91 return
92
93 if r_mcqv4src and r_mcqv4src != mcqv4src:
94 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
95 self.brctlcmd.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
96 else:
97 self.brctlcmd.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
98
99 def _down(self, ifaceobj):
100 try:
101 (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
102 vlanid = int(vlan, 10)
103 except:
104 self.logger.warn('%s: bridge vlan interface name ' %ifaceobj.name +
105 'does not correspond to format (eg. br0.100)')
106 raise
107
108 if not self.ipcmd.link_exists(bridgename):
109 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
110 # bridgename))
111 return
112 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
113 if mcqv4src:
114 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
115
116 def _query_running_bridge_igmp_querier_src(self, ifaceobj):
117 (bridgename, vlanid) = ifaceobj.name.split('.')
118 running_mcqv4src = self.brctlcmd.bridge_get_mcqv4src(bridgename)
119 if running_mcqv4src:
120 return running_mcqv4src.get(vlanid)
121 return None
122
123 def _query_check(self, ifaceobj, ifaceobjcurr):
124 attrval = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
125 if attrval:
126 running_mcq = self._query_running_bridge_igmp_querier_src(ifaceobj)
127 if not running_mcq or running_mcq != attrval:
128 ifaceobjcurr.update_config_with_status(
129 'bridge-igmp-querier-src', running_mcq, 1)
130 else:
131 ifaceobjcurr.update_config_with_status(
132 'bridge-igmp-querier-src', attrval, 0)
133 ifaceobjcurr.status = ifaceStatus.SUCCESS
134 return
135
136 def _query_running(self, ifaceobjrunning):
137 # XXX not supported
138 return
139
140 def syntax_check(self, ifaceobj, ifaceobj_getfunc):
141 ret = True
142 bvlan_intf = self._is_bridge_vlan_device(ifaceobj)
143 if (ifaceobj.get_attr_value_first('bridge-igmp-querier-src') and
144 not bvlan_intf):
145 self.logger.error('%s: bridge-igmp-querier-src only allowed under vlan stanza' %ifaceobj.name)
146 ret = False
147 return ret
148
149 _run_ops = {'pre-up' : _up,
150 'post-down' : _down,
151 'query-checkcurr' : _query_check,
152 'query-running' : _query_running}
153
154 def get_ops(self):
155 """ returns list of ops supported by this module """
156 return self._run_ops.keys()
157
158 def _init_command_handlers(self):
159 if not self.ipcmd:
160 self.ipcmd = self.brctlcmd = LinkUtils()
161
162 def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
163 """ run vlan configuration on the interface object passed as argument
164
165 Args:
166 **ifaceobj** (object): iface object
167
168 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
169 'query-running'
170 Kwargs:
171 **query_ifaceobj** (object): query check ifaceobject. This is only
172 valid when op is 'query-checkcurr'. It is an object same as
173 ifaceobj, but contains running attribute values and its config
174 status. The modules can use it to return queried running state
175 of interfaces. status is success if the running state is same
176 as user required state in ifaceobj. error otherwise.
177 """
178 op_handler = self._run_ops.get(operation)
179 if not op_handler:
180 return
181 if (operation != 'query-running' and
182 not self._is_bridge_vlan_device(ifaceobj)):
183 # most common problem is people specify BRIDGE_VLAN
184 # attribute on a bridge or a vlan device, which
185 # is incorrect. So, catch them here and warn before
186 # giving up processing the interface
187 if ((ifaceobj.link_kind & ifaceLinkKind.BRIDGE or
188 ifaceobj.link_kind & ifaceLinkKind.VLAN) and
189 not self.syntax_check(ifaceobj, None)):
190 ifaceobj.status = ifaceStatus.ERROR
191 return
192 self._init_command_handlers()
193 if operation == 'query-checkcurr':
194 op_handler(self, ifaceobj, query_ifaceobj)
195 else:
196 op_handler(self, ifaceobj)