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