]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/bridgevlan.py
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
8 from ifupdown2
.lib
.addon
import Addon
10 from ifupdown2
.ifupdown
.iface
import ifaceType
, ifaceLinkKind
, ifaceStatus
12 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
14 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
15 except (ImportError, ModuleNotFoundError
):
16 from lib
.addon
import Addon
18 from ifupdown
.iface
import ifaceType
, ifaceLinkKind
, ifaceStatus
20 from ifupdownaddons
.modulebase
import moduleBase
22 import ifupdown
.ifupdownflags
as ifupdownflags
25 class bridgevlan(Addon
, moduleBase
):
26 """ ifupdown2 addon module to configure vlan attributes on a vlan
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",
35 "bridge-igmp-querier-src": {
36 "help": "bridge igmp querier src. Must be specified under "
38 "validvals": ["<ipv4>"],
39 "example": ["bridge-igmp-querier-src 172.16.101.1"]
44 def __init__(self
, *args
, **kargs
):
46 moduleBase
.__init
__(self
, *args
, **kargs
)
49 def _is_bridge_vlan_device(ifaceobj
):
50 return ifaceobj
.type == ifaceType
.BRIDGE_VLAN
53 def _get_bridge_n_vlan(ifaceobj
):
54 vlist
= ifaceobj
.name
.split('.', 1)
56 return vlist
[0], vlist
[1]
60 def _get_bridgename(ifaceobj
):
61 vlist
= ifaceobj
.name
.split('.', 1)
66 def get_dependent_ifacenames(self
, ifaceobj
, ifaceobjs_all
=None, old_ifaceobjs
=False):
67 if not self
._is
_bridge
_vlan
_device
(ifaceobj
):
69 return [self
._get
_bridgename
(ifaceobj
)]
71 def _up(self
, ifaceobj
):
73 (bridgename
, vlan
) = self
._get
_bridge
_n
_vlan
(ifaceobj
)
74 vlanid
= int(vlan
, 10)
76 self
.log_error("%s: bridge vlan interface name does not correspond "
77 "to format (eg. br0.100)" % ifaceobj
.name
, ifaceobj
)
80 if not self
.cache
.link_exists(bridgename
):
81 #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
86 if not ifupdownflags
.flags
.PERFMODE
:
87 running_mcqv4src
= self
.sysfs
.bridge_get_mcqv4src(bridgename
)
89 r_mcqv4src
= running_mcqv4src
.get(vlan
)
92 mcqv4src
= ifaceobj
.get_attr_value_first('bridge-igmp-querier-src')
95 self
.iproute2
.bridge_del_mcqv4src(bridgename
, vlanid
)
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
)
102 self
.iproute2
.bridge_set_mcqv4src(bridgename
, vlanid
, mcqv4src
)
104 def _down(self
, ifaceobj
):
106 (bridgename
, vlan
) = self
._get
_bridge
_n
_vlan
(ifaceobj
)
107 vlanid
= int(vlan
, 10)
109 self
.logger
.warning("%s: bridge vlan interface name does not "
110 "correspond to format (eg. br0.100)" % ifaceobj
.name
)
113 if not self
.cache
.link_exists(bridgename
):
114 #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
117 mcqv4src
= ifaceobj
.get_attr_value_first('bridge-igmp-querier-src')
119 self
.iproute2
.bridge_del_mcqv4src(bridgename
, vlanid
)
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
)
125 return running_mcqv4src
.get(vlanid
)
128 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
129 attrval
= ifaceobj
.get_attr_value_first('bridge-igmp-querier-src')
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)
136 ifaceobjcurr
.update_config_with_status(
137 'bridge-igmp-querier-src', attrval
, 0)
138 ifaceobjcurr
.status
= ifaceStatus
.SUCCESS
141 def syntax_check(self
, ifaceobj
, ifaceobj_getfunc
):
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
)
152 "query-checkcurr": _query_check
,
156 """ returns list of ops supported by this module """
157 return list(self
._run
_ops
.keys())
159 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
160 """ run vlan configuration on the interface object passed as argument
163 **ifaceobj** (object): iface object
165 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
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.
175 op_handler
= self
._run
_ops
.get(operation
)
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
187 if operation
== 'query-checkcurr':
188 op_handler(self
, ifaceobj
, query_ifaceobj
)
190 op_handler(self
, ifaceobj
)