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