]> git.proxmox.com Git - mirror_ifupdown2.git/blame - ifupdown2/addons/addressvirtual.py
addons: addressvirtual: new attribute: address-virtual-ipv6-addrgen [on|off]
[mirror_ifupdown2.git] / ifupdown2 / addons / addressvirtual.py
CommitLineData
15ef32ea
RP
1#!/usr/bin/python
2#
d486dd0d 3# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
15ef32ea
RP
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6
15ef32ea
RP
7import os
8import glob
9
d486dd0d
JF
10from ipaddr import IPNetwork, IPv6Network
11
12try:
13 from ifupdown2.ifupdown.iface import *
7b711dc5 14 from ifupdown2.ifupdown.utils import utils
d486dd0d
JF
15 from ifupdown2.ifupdown.netlink import netlink
16
17 from ifupdown2.ifupdownaddons.LinkUtils import LinkUtils
18 from ifupdown2.ifupdownaddons.modulebase import moduleBase
19
20 import ifupdown2.ifupdown.statemanager as statemanager
21 import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
22 import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
23except ImportError:
24 from ifupdown.iface import *
7b711dc5 25 from ifupdown.utils import utils
d486dd0d
JF
26 from ifupdown.netlink import netlink
27
28 from ifupdownaddons.LinkUtils import LinkUtils
29 from ifupdownaddons.modulebase import moduleBase
30
31 import ifupdown.statemanager as statemanager
32 import ifupdown.ifupdownflags as ifupdownflags
33 import ifupdown.ifupdownconfig as ifupdownconfig
34
35
15ef32ea
RP
36class addressvirtual(moduleBase):
37 """ ifupdown2 addon module to configure virtual addresses """
38
39 _modinfo = {'mhelp' : 'address module configures virtual addresses for ' +
40 'interfaces. It creates a macvlan interface for ' +
41 'every mac ip address-virtual line',
42 'attrs' : {
43 'address-virtual' :
482b2fab 44 { 'help' : 'bridge router virtual mac and ips',
100ab3ea 45 'multivalue' : True,
2c592263 46 'validvals' : ['<mac-ip/prefixlen-list>',],
7b711dc5
JF
47 'example': ['address-virtual 00:11:22:33:44:01 11.0.1.1/24 11.0.1.2/24']
48 },
49 'address-virtual-ipv6-addrgen': {
50 'help': 'enable disable ipv6 link addrgenmode',
51 'validvals': ['on', 'off'],
52 'default': 'on',
53 'example': [
54 'address-virtual-ipv6-addrge on',
55 'address-virtual-ipv6-addrge off'
56 ]
57 }
58 }}
15ef32ea 59
8e113d63 60
15ef32ea
RP
61 def __init__(self, *args, **kargs):
62 moduleBase.__init__(self, *args, **kargs)
63 self.ipcmd = None
8e113d63 64 self._bridge_fdb_query_cache = {}
15ef32ea 65
42e85fc8
RP
66 def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None):
67 if ifaceobj.get_attr_value('address-virtual'):
68 ifaceobj.link_privflags |= ifaceLinkPrivFlags.ADDRESS_VIRTUAL_SLAVE
15ef32ea 69
aaef0a79
RP
70 def _get_macvlan_prefix(self, ifaceobj):
71 return '%s-v' %ifaceobj.name[0:13].replace('.', '-')
72
e1601369 73 def _add_addresses_to_bridge(self, ifaceobj, hwaddress):
8e113d63 74 # XXX: batch the addresses
d486dd0d
JF
75 if ifaceobj.link_kind & ifaceLinkKind.VLAN:
76 bridgename = ifaceobj.lowerifaces[0]
77 vlan = self._get_vlan_id(ifaceobj)
e1601369
RP
78 if self.ipcmd.bridge_is_vlan_aware(bridgename):
79 [self.ipcmd.bridge_fdb_add(bridgename, addr,
80 vlan) for addr in hwaddress]
8e113d63
RP
81 elif self.ipcmd.is_bridge(ifaceobj.name):
82 [self.ipcmd.bridge_fdb_add(ifaceobj.name, addr)
83 for addr in hwaddress]
e1601369
RP
84
85 def _remove_addresses_from_bridge(self, ifaceobj, hwaddress):
8e113d63 86 # XXX: batch the addresses
d486dd0d
JF
87 if ifaceobj.link_kind & ifaceLinkKind.VLAN:
88 bridgename = ifaceobj.lowerifaces[0]
89 vlan = self._get_vlan_id(ifaceobj)
e1601369 90 if self.ipcmd.bridge_is_vlan_aware(bridgename):
55072bd1
ST
91 for addr in hwaddress:
92 try:
93 self.ipcmd.bridge_fdb_del(bridgename, addr, vlan)
94 except Exception, e:
95 self.logger.debug("%s: %s" %(ifaceobj.name, str(e)))
96 pass
8e113d63 97 elif self.ipcmd.is_bridge(ifaceobj.name):
55072bd1
ST
98 for addr in hwaddress:
99 try:
100 self.ipcmd.bridge_fdb_del(ifaceobj.name, addr)
101 except Exception, e:
102 self.logger.debug("%s: %s" %(ifaceobj.name, str(e)))
103 pass
8e113d63
RP
104
105 def _get_bridge_fdbs(self, bridgename, vlan):
106 fdbs = self._bridge_fdb_query_cache.get(bridgename)
107 if not fdbs:
108 fdbs = self.ipcmd.bridge_fdb_show_dev(bridgename)
109 if not fdbs:
110 return
111 self._bridge_fdb_query_cache[bridgename] = fdbs
112 return fdbs.get(vlan)
113
114 def _check_addresses_in_bridge(self, ifaceobj, hwaddress):
115 """ If the device is a bridge, make sure the addresses
116 are in the bridge """
d486dd0d
JF
117 if ifaceobj.link_kind & ifaceLinkKind.VLAN:
118 bridgename = ifaceobj.lowerifaces[0]
119 vlan = self._get_vlan_id(ifaceobj)
8e113d63 120 if self.ipcmd.bridge_is_vlan_aware(bridgename):
d486dd0d 121 fdb_addrs = self._get_bridge_fdbs(bridgename, str(vlan))
8e113d63
RP
122 if not fdb_addrs or hwaddress not in fdb_addrs:
123 return False
124 return True
e1601369 125
00f6105d
RP
126 def _fix_connected_route(self, ifaceobj, vifacename, addr):
127 #
d486dd0d 128 # XXX: Hack to make sure the primary address
00f6105d
RP
129 # is the first in the routing table.
130 #
131 # We use `ip route get` on the vrr network to see which
132 # device the kernel returns. if it is the mac vlan device,
133 # flap the macvlan device to adjust the routing table entry.
d486dd0d 134 #
00f6105d
RP
135 # flapping the macvlan device makes sure the macvlan
136 # connected route goes through delete + add, hence adjusting
137 # the order in the routing table.
138 #
139 try:
140 self.logger.info('%s: checking route entry ...' %ifaceobj.name)
141 ip = IPNetwork(addr)
d486dd0d
JF
142
143 # we don't support ip6 route fix yet
144 if type(ip) == IPv6Network:
145 return
146
00f6105d
RP
147 route_prefix = '%s/%d' %(ip.network, ip.prefixlen)
148
aa895ecd
JF
149 if ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE:
150 vrf_master = self.ipcmd.link_get_master(ifaceobj.name)
151 else:
152 vrf_master = None
153
154 dev = self.ipcmd.ip_route_get_dev(route_prefix, vrf_master=vrf_master)
155
d486dd0d 156 if dev and dev != ifaceobj.name:
00f6105d
RP
157 self.logger.info('%s: preferred routing entry ' %ifaceobj.name +
158 'seems to be of the macvlan dev %s'
159 %vifacename +
160 ' .. flapping macvlan dev to fix entry.')
161 self.ipcmd.link_down(vifacename)
162 self.ipcmd.link_up(vifacename)
163 except Exception, e:
164 self.logger.debug('%s: fixing route entry failed (%s)'
d486dd0d 165 % (ifaceobj.name, str(e)))
00f6105d
RP
166 pass
167
1b284018
RP
168 def _handle_vrf_slaves(self, macvlan_ifacename, ifaceobj):
169 vrfname = self.ipcmd.link_get_master(ifaceobj.name)
170 if vrfname:
d486dd0d 171 self.ipcmd.link_set(macvlan_ifacename, 'master', vrfname)
1b284018 172
55072bd1
ST
173 def _get_macs_from_old_config(self, ifaceobj=None):
174 """ This method returns a list of the mac addresses
175 in the address-virtual attribute for the bridge. """
176 maclist = []
177 saved_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name)
178 if not saved_ifaceobjs:
179 return maclist
180 # we need the old saved configs from the statemanager
181 for oldifaceobj in saved_ifaceobjs:
182 if not oldifaceobj.get_attr_value('address-virtual'):
183 continue
184 for av in oldifaceobj.get_attr_value('address-virtual'):
185 macip = av.split()
186 if len(macip) < 2:
187 self.logger.debug("%s: incorrect old address-virtual attrs '%s'"
188 %(oldifaceobj.name, av))
189 continue
190 maclist.append(macip[0])
191 return maclist
192
7b711dc5
JF
193 def get_addressvirtual_ipv6_addrgen_user_conf(self, ifaceobj):
194 ipv6_addrgen = ifaceobj.get_attr_value_first('address-virtual-ipv6-addrgen')
195
196 if ipv6_addrgen:
197 return True, utils.get_boolean_from_string(ipv6_addrgen)
198
199 return False, None
200
e1601369 201 def _apply_address_config(self, ifaceobj, address_virtual_list):
fc5e1735 202 purge_existing = False if ifupdownflags.flags.PERFMODE else True
15ef32ea 203
9e0be374 204 lower_iface_mtu = update_mtu = None
d486dd0d 205 if ifupdownconfig.config.get('adjust_logical_dev_mtu', '1') != '0':
9e0be374
JF
206 if ifaceobj.lowerifaces and address_virtual_list:
207 update_mtu = True
208
7b711dc5
JF
209 should_configure_ipv6_addrgen, ipv6_addrgen_user_value = self.get_addressvirtual_ipv6_addrgen_user_conf(ifaceobj)
210
e1601369 211 hwaddress = []
15ef32ea
RP
212 self.ipcmd.batch_start()
213 av_idx = 0
aaef0a79 214 macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
15ef32ea
RP
215 for av in address_virtual_list:
216 av_attrs = av.split()
217 if len(av_attrs) < 2:
bf3eda91
RP
218 self.log_error("%s: incorrect address-virtual attrs '%s'"
219 %(ifaceobj.name, av), ifaceobj,
220 raise_error=False)
15ef32ea
RP
221 av_idx += 1
222 continue
223
4d3dc0f7
N
224 mac = av_attrs[0]
225 if not self.check_mac_address(ifaceobj, mac):
226 continue
15ef32ea
RP
227 # Create a macvlan device on this device and set the virtual
228 # router mac and ip on it
00f6105d 229 link_created = False
cb46a208 230 macvlan_ifacename = '%s%d' %(macvlan_prefix, av_idx)
e74d01e1 231 if not self.ipcmd.link_exists(macvlan_ifacename):
d486dd0d
JF
232 try:
233 netlink.link_add_macvlan(ifaceobj.name, macvlan_ifacename)
234 except:
235 self.ipcmd.link_add_macvlan(ifaceobj.name, macvlan_ifacename)
00f6105d 236 link_created = True
d486dd0d
JF
237
238 # first thing we need to handle vrf enslavement
239 if (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE):
240 self._handle_vrf_slaves(macvlan_ifacename, ifaceobj)
241
7b711dc5
JF
242 if should_configure_ipv6_addrgen:
243 self.ipcmd.ipv6_addrgen(macvlan_ifacename, ipv6_addrgen_user_value)
244
5df79763
ST
245 ips = av_attrs[1:]
246 if mac != 'None':
247 mac = mac.lower()
248 # customer could have used UPPERCASE for MAC
249 self.ipcmd.link_set_hwaddress(macvlan_ifacename, mac)
250 hwaddress.append(mac)
dfaa8a2d
JF
251 self.ipcmd.addr_add_multiple(
252 ifaceobj,
253 macvlan_ifacename,
254 ips,
255 purge_existing,
256 metric=self.ipcmd.get_default_ip_metric() if self.ipcmd.addr_metric_support() else None
257 )
9e0be374 258
00f6105d
RP
259 # If link existed before, flap the link
260 if not link_created:
261 self._fix_connected_route(ifaceobj, macvlan_ifacename,
5df79763 262 ips[0])
9e0be374 263 if update_mtu:
0493bac6 264 lower_iface_mtu = self.ipcmd.link_get_mtu(ifaceobj.name, refresh=True)
9e0be374
JF
265 update_mtu = False
266
d486dd0d 267 if lower_iface_mtu and lower_iface_mtu != self.ipcmd.link_get_mtu(macvlan_ifacename, refresh=True):
0493bac6
JF
268 try:
269 self.ipcmd.link_set_mtu(macvlan_ifacename,
270 lower_iface_mtu)
271 except Exception as e:
272 self.logger.info('%s: failed to set mtu %s: %s' %
273 (macvlan_ifacename, lower_iface_mtu, e))
9e0be374 274
dc3f4c45
RP
275 # set macvlan device to up in anycase.
276 # since we auto create them here..we are responsible
277 # to bring them up here in the case they were brought down
278 # by some other entity in the system.
279 netlink.link_set_updown(macvlan_ifacename, "up")
d486dd0d
JF
280 else:
281 try:
dfaa8a2d
JF
282 if not self.ipcmd.addr_metric_support():
283 # if the system doesn't support ip addr set METRIC
284 # we need to do manually check the ordering of the ip6 routes
285 self.ipcmd.fix_ipv6_route_metric(ifaceobj, macvlan_ifacename, ips)
d486dd0d
JF
286 except Exception as e:
287 self.logger.debug('fix_vrf_slave_ipv6_route_metric: failed: %s' % e)
1b284018 288
f8ad40ce
SE
289 # Disable IPv6 duplicate address detection on VRR interfaces
290 for key, sysval in { 'accept_dad' : '0', 'dad_transmits' : '0' }.iteritems():
291 syskey = 'net.ipv6.conf.%s.%s' % (macvlan_ifacename, key)
292 if self.sysctl_get(syskey) != sysval:
293 self.sysctl_set(syskey, sysval)
294
15ef32ea
RP
295 av_idx += 1
296 self.ipcmd.batch_commit()
297
55072bd1
ST
298 # check the statemanager for old configs.
299 # We need to remove only the previously configured FDB entries
300 oldmacs = self._get_macs_from_old_config(ifaceobj)
301 # get a list of fdbs in old that are not in new config meaning they should
302 # be removed since they are gone from the config
5df79763 303 removed_macs = [mac for mac in oldmacs if mac.lower() not in hwaddress]
55072bd1 304 self._remove_addresses_from_bridge(ifaceobj, removed_macs)
e1601369
RP
305 # if ifaceobj is a bridge and bridge is a vlan aware bridge
306 # add the vid to the bridge
307 self._add_addresses_to_bridge(ifaceobj, hwaddress)
308
309 def _remove_running_address_config(self, ifaceobj):
310 if not self.ipcmd.link_exists(ifaceobj.name):
15ef32ea 311 return
e1601369 312 hwaddress = []
15ef32ea 313 self.ipcmd.batch_start()
aaef0a79 314 macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
55072bd1 315 for macvlan_ifacename in glob.glob("/sys/class/net/%s*" %macvlan_prefix):
e1601369
RP
316 macvlan_ifacename = os.path.basename(macvlan_ifacename)
317 if not self.ipcmd.link_exists(macvlan_ifacename):
318 continue
319 hwaddress.append(self.ipcmd.link_get_hwaddress(macvlan_ifacename))
15ef32ea 320 self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
e1601369
RP
321 # XXX: Also delete any fdb addresses. This requires, checking mac address
322 # on individual macvlan interfaces and deleting the vlan from that.
15ef32ea 323 self.ipcmd.batch_commit()
e1601369
RP
324 if any(hwaddress):
325 self._remove_addresses_from_bridge(ifaceobj, hwaddress)
15ef32ea 326
e1601369
RP
327 def _remove_address_config(self, ifaceobj, address_virtual_list=None):
328 if not address_virtual_list:
329 self._remove_running_address_config(ifaceobj)
330 return
331
332 if not self.ipcmd.link_exists(ifaceobj.name):
333 return
334 hwaddress = []
335 self.ipcmd.batch_start()
336 av_idx = 0
aaef0a79 337 macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
e1601369
RP
338 for av in address_virtual_list:
339 av_attrs = av.split()
340 if len(av_attrs) < 2:
bf3eda91
RP
341 self.log_error("%s: incorrect address-virtual attrs '%s'"
342 %(ifaceobj.name, av), ifaceobj,
343 raise_error=False)
e1601369
RP
344 av_idx += 1
345 continue
346
347 # Delete the macvlan device on this device
cb46a208 348 macvlan_ifacename = '%s%d' %(macvlan_prefix, av_idx)
e1601369
RP
349 self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
350 if av_attrs[0] != 'None':
351 hwaddress.append(av_attrs[0])
352 av_idx += 1
353 self.ipcmd.batch_commit()
354 self._remove_addresses_from_bridge(ifaceobj, hwaddress)
15ef32ea 355
4d3dc0f7
N
356 def check_mac_address(self, ifaceobj, mac):
357 if mac == 'None':
d486dd0d 358 return True
4d3dc0f7
N
359 mac = mac.lower()
360 try:
586535e8 361 if int(mac.split(":")[0], 16) & 1 :
4d3dc0f7
N
362 self.logger.error("%s: Multicast bit is set in the virtual mac address '%s'" %(ifaceobj.name, mac))
363 return False
364 return True
42e85fc8 365 except Exception:
4d3dc0f7
N
366 return False
367
42e85fc8
RP
368 def _fixup_vrf_enslavements(self, ifaceobj, ifaceobj_getfunc=None):
369 """ This function fixes up address virtual interfaces
370 (macvlans) on vrf slaves. Since this fixup is an overhead,
371 this must be called only in cases when ifupdown2 is
372 called on the vrf device or its slave and not when
373 ifupdown2 is called for all devices. When all
374 interfaces are brought up, the expectation is that
375 the normal path will fix up a vrf device or its slaves"""
376
377 if not ifaceobj_getfunc:
378 return
379 if ((ifaceobj.link_kind & ifaceLinkKind.VRF) and
380 self.ipcmd.link_exists(ifaceobj.name)):
381 # if I am a vrf device and I have slaves
382 # that have address virtual config,
383 # enslave the slaves 'address virtual
384 # interfaces (macvlans)' to myself:
385 running_slaves = self.ipcmd.link_get_lowers(ifaceobj.name)
386 if running_slaves:
387 # pick up any existing slaves of a vrf device and
388 # look for their upperdevices and enslave them to the
389 # vrf device:
390 for s in running_slaves:
391 sobjs = ifaceobj_getfunc(s)
392 if (sobjs and
393 (sobjs[0].link_privflags & ifaceLinkPrivFlags.ADDRESS_VIRTUAL_SLAVE)):
394 # enslave all its upper devices to
395 # the vrf device
396 upperdevs = self.ipcmd.link_get_uppers(sobjs[0].name)
397 if not upperdevs:
398 continue
399 for u in upperdevs:
400 # skip vrf device which
401 # will also show up in the
402 # upper device list
403 if u == ifaceobj.name:
404 continue
d486dd0d
JF
405 self.ipcmd.link_set(u, 'master', ifaceobj.name,
406 state='up')
42e85fc8
RP
407 elif ((ifaceobj.link_privflags & ifaceLinkPrivFlags.ADDRESS_VIRTUAL_SLAVE) and
408 (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE) and
409 self.ipcmd.link_exists(ifaceobj.name)):
410 # If I am a vrf slave and I have 'address virtual'
411 # config, make sure my addrress virtual interfaces
412 # (macvlans) are also enslaved to the vrf device
413 vrfname = ifaceobj.get_attr_value_first('vrf')
414 if not vrfname or not self.ipcmd.link_exists(vrfname):
415 return
416 running_uppers = self.ipcmd.link_get_uppers(ifaceobj.name)
417 if not running_uppers:
418 return
419 macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
420 if not macvlan_prefix:
421 return
422 for u in running_uppers:
423 if u == vrfname:
424 continue
425 if u.startswith(macvlan_prefix):
d486dd0d
JF
426 self.ipcmd.link_set(u, 'master', vrfname,
427 state='up')
42e85fc8
RP
428
429 def _up(self, ifaceobj, ifaceobj_getfunc=None):
430 if not ifupdownflags.flags.ALL:
431 self._fixup_vrf_enslavements(ifaceobj, ifaceobj_getfunc)
15ef32ea
RP
432 address_virtual_list = ifaceobj.get_attr_value('address-virtual')
433 if not address_virtual_list:
434 # XXX: address virtual is not present. In which case,
00f6105d 435 # delete stale macvlan devices.
e1601369 436 self._remove_address_config(ifaceobj, address_virtual_list)
15ef32ea
RP
437 return
438
1b284018
RP
439 if (ifaceobj.upperifaces and
440 not ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE):
f466af7a
JF
441 self.log_error('%s: invalid placement of address-virtual lines (must be configured under an interface with no upper interfaces or parent interfaces)'
442 % (ifaceobj.name), ifaceobj)
443 return
444
e1601369 445 if not self.ipcmd.link_exists(ifaceobj.name):
15ef32ea 446 return
e1601369 447 self._apply_address_config(ifaceobj, address_virtual_list)
15ef32ea 448
42e85fc8 449 def _down(self, ifaceobj, ifaceobj_getfunc=None):
15ef32ea 450 try:
cb46a208
RP
451 self._remove_address_config(ifaceobj,
452 ifaceobj.get_attr_value('address-virtual'))
15ef32ea
RP
453 except Exception, e:
454 self.log_warn(str(e))
455
456 def _query_check(self, ifaceobj, ifaceobjcurr):
457 address_virtual_list = ifaceobj.get_attr_value('address-virtual')
458 if not address_virtual_list:
459 return
cb46a208
RP
460 if not self.ipcmd.link_exists(ifaceobj.name):
461 return
15ef32ea 462 av_idx = 0
aaef0a79 463 macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
15ef32ea
RP
464 for address_virtual in address_virtual_list:
465 av_attrs = address_virtual.split()
466 if len(av_attrs) < 2:
467 self.logger.warn("%s: incorrect address-virtual attrs '%s'"
468 %(ifaceobj.name, address_virtual))
469 av_idx += 1
470 continue
471
472 # Check if the macvlan device on this interface
cb46a208
RP
473 macvlan_ifacename = '%s%d' %(macvlan_prefix, av_idx)
474 if not self.ipcmd.link_exists(macvlan_ifacename):
475 ifaceobjcurr.update_config_with_status('address-virtual',
476 '', 1)
477 av_idx += 1
478 continue
479 # Check mac and ip address
480 rhwaddress = self.ipcmd.link_get_hwaddress(macvlan_ifacename)
d486dd0d
JF
481 raddrs = self.ipcmd.get_running_addrs(
482 ifname=macvlan_ifacename,
483 details=False,
484 addr_virtual_ifaceobj=ifaceobj
485 )
cb46a208
RP
486 if not raddrs or not rhwaddress:
487 ifaceobjcurr.update_config_with_status('address-virtual', '', 1)
488 av_idx += 1
489 continue
b6688146
JF
490 try:
491 av_attrs[0] = ':'.join([i if len(i) == 2 else '0%s' % i
492 for i in av_attrs[0].split(':')])
493 except:
494 self.logger.info('%s: %s: invalid value for address-virtual (%s)'
495 % (ifaceobj.name,
496 macvlan_ifacename,
497 ' '.join(av_attrs)))
90649d37 498 try:
d486dd0d
JF
499 if (rhwaddress == av_attrs[0].lower() and
500 self.ipcmd.compare_user_config_vs_running_state(raddrs, av_attrs[1:]) and
501 self._check_addresses_in_bridge(ifaceobj, av_attrs[0].lower())):
90649d37
JF
502 ifaceobjcurr.update_config_with_status('address-virtual',
503 address_virtual, 0)
504 else:
505 raddress_virtual = '%s %s' % (rhwaddress, ' '.join(raddrs))
506 ifaceobjcurr.update_config_with_status('address-virtual',
507 raddress_virtual, 1)
508 except:
509 raddress_virtual = '%s %s' % (rhwaddress, ' '.join(raddrs))
510 ifaceobjcurr.update_config_with_status('address-virtual',
511 raddress_virtual, 1)
15ef32ea
RP
512 av_idx += 1
513 return
514
42e85fc8 515 def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
aaef0a79 516 macvlan_prefix = self._get_macvlan_prefix(ifaceobjrunning)
8e113d63
RP
517 address_virtuals = glob.glob("/sys/class/net/%s*" %macvlan_prefix)
518 for av in address_virtuals:
519 macvlan_ifacename = os.path.basename(av)
520 rhwaddress = self.ipcmd.link_get_hwaddress(macvlan_ifacename)
d486dd0d 521 raddress = self.ipcmd.get_running_addrs(None, macvlan_ifacename)
8e113d63
RP
522 if not raddress:
523 self.logger.warn('%s: no running addresses'
524 %ifaceobjrunning.name)
525 raddress = []
526 ifaceobjrunning.update_config('address-virtual',
527 '%s %s' %(rhwaddress, ''.join(raddress)))
15ef32ea
RP
528 return
529
530 _run_ops = {'up' : _up,
531 'down' : _down,
532 'query-checkcurr' : _query_check,
533 'query-running' : _query_running}
534
535 def get_ops(self):
536 """ returns list of ops supported by this module """
537 return self._run_ops.keys()
538
539 def _init_command_handlers(self):
540 if not self.ipcmd:
d486dd0d 541 self.ipcmd = LinkUtils()
15ef32ea 542
42e85fc8
RP
543 def run(self, ifaceobj, operation, query_ifaceobj=None,
544 ifaceobj_getfunc=None, **extra_args):
15ef32ea
RP
545 """ run vlan configuration on the interface object passed as argument
546
547 Args:
548 **ifaceobj** (object): iface object
549
550 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
551 'query-running'
552 Kwargs:
553 **query_ifaceobj** (object): query check ifaceobject. This is only
554 valid when op is 'query-checkcurr'. It is an object same as
555 ifaceobj, but contains running attribute values and its config
556 status. The modules can use it to return queried running state
557 of interfaces. status is success if the running state is same
558 as user required state in ifaceobj. error otherwise.
559 """
84ca006f
RP
560 if ifaceobj.type == ifaceType.BRIDGE_VLAN:
561 return
15ef32ea
RP
562 op_handler = self._run_ops.get(operation)
563 if not op_handler:
564 return
565 self._init_command_handlers()
566 if operation == 'query-checkcurr':
567 op_handler(self, ifaceobj, query_ifaceobj)
568 else:
42e85fc8 569 op_handler(self, ifaceobj, ifaceobj_getfunc=ifaceobj_getfunc)