]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/bridgevlan.py
SONAR: fix iface.py: Import only needed names or import the module and then use its...
[mirror_ifupdown2.git] / ifupdown2 / addons / bridgevlan.py
1 #!/usr/bin/env python3
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.lib.addon import Addon
9
10 from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus
11
12 from ifupdown2.ifupdownaddons.modulebase import moduleBase
13
14 import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
15 except (ImportError, ModuleNotFoundError):
16 from lib.addon import Addon
17
18 from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus
19
20 from ifupdownaddons.modulebase import moduleBase
21
22 import ifupdown.ifupdownflags as ifupdownflags
23
24
25 class bridgevlan(Addon, moduleBase):
26 """ ifupdown2 addon module to configure vlan attributes on a vlan
27 aware bridge """
28
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 }
43
44 def __init__(self, *args, **kargs):
45 Addon.__init__(self)
46 moduleBase.__init__(self, *args, **kargs)
47
48 @staticmethod
49 def _is_bridge_vlan_device(ifaceobj):
50 return ifaceobj.type == ifaceType.BRIDGE_VLAN
51
52 @staticmethod
53 def _get_bridge_n_vlan(ifaceobj):
54 vlist = ifaceobj.name.split('.', 1)
55 if len(vlist) == 2:
56 return vlist[0], vlist[1]
57 return None
58
59 @staticmethod
60 def _get_bridgename(ifaceobj):
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, old_ifaceobjs=False):
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 Exception:
76 self.log_error("%s: bridge vlan interface name does not correspond "
77 "to format (eg. br0.100)" % ifaceobj.name, ifaceobj)
78 raise
79
80 if not self.cache.link_exists(bridgename):
81 #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
82 # bridgename))
83 return
84
85 running_mcqv4src = {}
86 if not ifupdownflags.flags.PERFMODE:
87 running_mcqv4src = self.sysfs.bridge_get_mcqv4src(bridgename)
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:
95 self.iproute2.bridge_del_mcqv4src(bridgename, vlanid)
96 return
97
98 if r_mcqv4src and r_mcqv4src != mcqv4src:
99 self.iproute2.bridge_del_mcqv4src(bridgename, vlanid)
100 self.iproute2.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
101 else:
102 self.iproute2.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
103
104 def _down(self, ifaceobj):
105 try:
106 (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
107 vlanid = int(vlan, 10)
108 except Exception:
109 self.logger.warning("%s: bridge vlan interface name does not "
110 "correspond to format (eg. br0.100)" % ifaceobj.name)
111 raise
112
113 if not self.cache.link_exists(bridgename):
114 #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
115 # bridgename))
116 return
117 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
118 if mcqv4src:
119 self.iproute2.bridge_del_mcqv4src(bridgename, vlanid)
120
121 def _query_running_bridge_igmp_querier_src(self, ifaceobj):
122 (bridgename, vlanid) = ifaceobj.name.split('.')
123 running_mcqv4src = self.sysfs.bridge_get_mcqv4src(bridgename)
124 if running_mcqv4src:
125 return running_mcqv4src.get(vlanid)
126 return None
127
128 def _query_check(self, ifaceobj, ifaceobjcurr):
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)
138 ifaceobjcurr.status = ifaceStatus.SUCCESS
139 return
140
141 def syntax_check(self, ifaceobj, ifaceobj_getfunc):
142 ret = True
143 bvlan_intf = self._is_bridge_vlan_device(ifaceobj)
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)
146 ret = False
147 return ret
148
149 _run_ops = {
150 "pre-up": _up,
151 "post-down": _down,
152 "query-checkcurr": _query_check,
153 }
154
155 def get_ops(self):
156 """ returns list of ops supported by this module """
157 return list(self._run_ops.keys())
158
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
178 if (operation != 'query-running' and not self._is_bridge_vlan_device(ifaceobj)):
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
183 if (ifaceobj.link_kind & ifaceLinkKind.BRIDGE or ifaceobj.link_kind & ifaceLinkKind.VLAN) \
184 and not self.syntax_check(ifaceobj, None):
185 ifaceobj.status = ifaceStatus.ERROR
186 return
187 if operation == 'query-checkcurr':
188 op_handler(self, ifaceobj, query_ifaceobj)
189 else:
190 op_handler(self, ifaceobj)