]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/bridgevlan.py
44824c760e2ee072f1e7e4ef8061bdb7a51b7758
[mirror_ifupdown2.git] / ifupdown2 / addons / bridgevlan.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 from ifupdownaddons.bridgeutils import brctl
11 import logging
12
13 class bridgevlan(moduleBase):
14 """ ifupdown2 addon module to configure vlan attributes on a vlan
15 aware bridge """
16
17 _modinfo = {'mhelp' : 'bridgevlan module configures vlan attributes ' +
18 'on a vlan aware bridge. This module only ' +
19 'understands vlan interface name ' +
20 'with dot notations. eg br0.100. where br0 is the ' +
21 'vlan aware bridge this config is for',
22 'attrs' : {
23 'bridge-igmp-querier-src' :
24 { 'help' : 'bridge igmp querier src. Must be ' +
25 'specified under the vlan interface',
26 'example' : ['bridge-igmp-querier-src 172.16.101.1']}}}
27
28 def __init__(self, *args, **kargs):
29 moduleBase.__init__(self, *args, **kargs)
30 self.brctlcmd = None
31 self.ipcmd = None
32
33 def _is_bridge_vlan_device(self, ifaceobj):
34 if ifaceobj.type == ifaceType.BRIDGE_VLAN:
35 return True
36 return False
37
38 def _get_bridge_n_vlan(self, ifaceobj):
39 vlist = ifaceobj.name.split('.', 1)
40 if len(vlist) == 2:
41 return (vlist[0], vlist[1])
42 return None
43
44 def _get_bridgename(self, ifaceobj):
45 vlist = ifaceobj.name.split('.', 1)
46 if len(vlist) == 2:
47 return vlist[0]
48 return None
49
50 def get_dependent_ifacenames(self, ifaceobj, ifaceobjs_all=None):
51 if not self._is_bridge_vlan_device(ifaceobj):
52 return None
53 return [self._get_bridgename(ifaceobj)]
54
55 def _up(self, ifaceobj):
56 try:
57 (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
58 vlanid = int(vlan, 10)
59 except:
60 self.logger.warn('%s: bridge vlan interface name ' %ifaceobj.name +
61 'does not correspond to format (eg. br0.100)')
62 raise
63
64 if not self.ipcmd.link_exists(bridgename):
65 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
66 # bridgename))
67 return
68
69 running_mcqv4src = {}
70 if not self.PERFMODE:
71 running_mcqv4src = self.brctlcmd.get_mcqv4src(bridgename)
72 if running_mcqv4src:
73 r_mcqv4src = running_mcqv4src.get(vlan)
74 else:
75 r_mcqv4src = None
76 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
77 if not mcqv4src:
78 if r_mcqv4src:
79 self.brctlcmd.del_mcqv4src(bridgename, vlanid)
80 return
81
82 if r_mcqv4src and r_mcqv4src != mcqv4src:
83 self.brctlcmd.del_mcqv4src(bridgename, vlanid)
84 self.brctlcmd.set_mcqv4src(bridgename, vlanid, mcqv4src)
85 else:
86 self.brctlcmd.set_mcqv4src(bridgename, vlanid, mcqv4src)
87
88 def _down(self, ifaceobj):
89 try:
90 (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
91 vlanid = int(vlan, 10)
92 except:
93 self.logger.warn('%s: bridge vlan interface name ' %ifaceobj.name +
94 'does not correspond to format (eg. br0.100)')
95 raise
96
97 if not self.ipcmd.link_exists(bridgename):
98 #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
99 # bridgename))
100 return
101 mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
102 if mcqv4src:
103 self.brctlcmd.del_mcqv4src(bridgename, vlanid)
104
105 def _query_running_bridge_igmp_querier_src(self, ifaceobj):
106 (bridgename, vlanid) = ifaceobj.name.split('.')
107 running_mcqv4src = self.brctlcmd.get_mcqv4src(bridgename)
108 if running_mcqv4src:
109 return running_mcqv4src.get(vlanid)
110 return None
111
112 def _query_check(self, ifaceobj, ifaceobjcurr):
113 attrval = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
114 if attrval:
115 running_mcq = self._query_running_bridge_igmp_querier_src(ifaceobj)
116 if not running_mcq or running_mcq != attrval:
117 ifaceobjcurr.update_config_with_status(
118 'bridge-igmp-querier-src', running_mcq, 1)
119 else:
120 ifaceobjcurr.update_config_with_status(
121 'bridge-igmp-querier-src', attrval, 0)
122 ifaceobjcurr.status = ifaceStatus.SUCCESS
123 return
124
125 def _query_running(self, ifaceobjrunning):
126 # XXX not supported
127 return
128
129 _run_ops = {'pre-up' : _up,
130 'post-down' : _down,
131 'query-checkcurr' : _query_check,
132 'query-running' : _query_running}
133
134 def get_ops(self):
135 """ returns list of ops supported by this module """
136 return self._run_ops.keys()
137
138 def _init_command_handlers(self):
139 if not self.ipcmd:
140 self.ipcmd = iproute2(**self.get_flags())
141 if not self.brctlcmd:
142 self.brctlcmd = brctl(**self.get_flags())
143
144 def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
145 """ run vlan configuration on the interface object passed as argument
146
147 Args:
148 **ifaceobj** (object): iface object
149
150 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
151 'query-running'
152 Kwargs:
153 **query_ifaceobj** (object): query check ifaceobject. This is only
154 valid when op is 'query-checkcurr'. It is an object same as
155 ifaceobj, but contains running attribute values and its config
156 status. The modules can use it to return queried running state
157 of interfaces. status is success if the running state is same
158 as user required state in ifaceobj. error otherwise.
159 """
160 op_handler = self._run_ops.get(operation)
161 if not op_handler:
162 return
163 if (operation != 'query-running' and
164 not self._is_bridge_vlan_device(ifaceobj)):
165 return
166 self._init_command_handlers()
167 if operation == 'query-checkcurr':
168 op_handler(self, ifaceobj, query_ifaceobj)
169 else:
170 op_handler(self, ifaceobj)