]> git.proxmox.com Git - mirror_ifupdown2.git/blame - ifupdown2/addons/bridgevlan.py
netlink: nlpacket AttributeMACAddress
[mirror_ifupdown2.git] / ifupdown2 / addons / bridgevlan.py
CommitLineData
84ca006f
RP
1#!/usr/bin/python
2#
d486dd0d 3# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
84ca006f
RP
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6
d486dd0d
JF
7try:
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
14except 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
84ca006f
RP
22
23class 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' :
da1eb143
RP
34 { 'help' : 'bridge igmp querier src. Must be ' +
35 'specified under the vlan interface',
482b2fab 36 'validvals' : ['<ipv4>', ],
da1eb143 37 'example' : ['bridge-igmp-querier-src 172.16.101.1']}}}
84ca006f
RP
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:
bf3eda91
RP
71 self.log_error('%s: bridge vlan interface name ' %ifaceobj.name +
72 'does not correspond to format (eg. br0.100)', ifaceobj)
84ca006f
RP
73 raise
74
75 if not self.ipcmd.link_exists(bridgename):
e1601369
RP
76 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
77 # bridgename))
84ca006f
RP
78 return
79
80 running_mcqv4src = {}
fc5e1735 81 if not ifupdownflags.flags.PERFMODE:
d486dd0d 82 running_mcqv4src = self.brctlcmd.bridge_get_mcqv4src(bridgename)
84ca006f
RP
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:
d486dd0d 90 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
84ca006f
RP
91 return
92
93 if r_mcqv4src and r_mcqv4src != mcqv4src:
d486dd0d
JF
94 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
95 self.brctlcmd.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
84ca006f 96 else:
d486dd0d 97 self.brctlcmd.bridge_set_mcqv4src(bridgename, vlanid, mcqv4src)
84ca006f
RP
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):
e1601369
RP
109 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
110 # bridgename))
84ca006f 111 return
84ca006f
RP
112 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
113 if mcqv4src:
d486dd0d 114 self.brctlcmd.bridge_del_mcqv4src(bridgename, vlanid)
84ca006f 115
da1eb143
RP
116 def _query_running_bridge_igmp_querier_src(self, ifaceobj):
117 (bridgename, vlanid) = ifaceobj.name.split('.')
d486dd0d 118 running_mcqv4src = self.brctlcmd.bridge_get_mcqv4src(bridgename)
da1eb143
RP
119 if running_mcqv4src:
120 return running_mcqv4src.get(vlanid)
121 return None
122
84ca006f 123 def _query_check(self, ifaceobj, ifaceobjcurr):
da1eb143
RP
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)
16d854b4 133 ifaceobjcurr.status = ifaceStatus.SUCCESS
84ca006f
RP
134 return
135
136 def _query_running(self, ifaceobjrunning):
137 # XXX not supported
138 return
139
d486dd0d
JF
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
84ca006f
RP
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:
d486dd0d 160 self.ipcmd = self.brctlcmd = LinkUtils()
84ca006f
RP
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)):
d486dd0d
JF
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
84ca006f
RP
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)