3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
11 from ipaddr
import IPNetwork
, IPv6Network
14 from ifupdown2
.ifupdown
.iface
import *
15 from ifupdown2
.ifupdown
.utils
import utils
16 from ifupdown2
.ifupdown
.netlink
import netlink
18 from ifupdown2
.ifupdownaddons
.LinkUtils
import LinkUtils
19 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
21 import ifupdown2
.ifupdown
.statemanager
as statemanager
22 import ifupdown2
.ifupdown
.policymanager
as policymanager
23 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
24 import ifupdown2
.ifupdown
.ifupdownconfig
as ifupdownconfig
26 from ifupdown
.iface
import *
27 from ifupdown
.utils
import utils
28 from ifupdown
.netlink
import netlink
30 from ifupdownaddons
.LinkUtils
import LinkUtils
31 from ifupdownaddons
.modulebase
import moduleBase
33 import ifupdown
.statemanager
as statemanager
34 import ifupdown
.policymanager
as policymanager
35 import ifupdown
.ifupdownflags
as ifupdownflags
36 import ifupdown
.ifupdownconfig
as ifupdownconfig
39 class addressvirtual(moduleBase
):
40 """ ifupdown2 addon module to configure virtual addresses """
42 _modinfo
= {'mhelp' : 'address module configures virtual addresses for ' +
43 'interfaces. It creates a macvlan interface for ' +
44 'every mac ip address-virtual line',
47 { 'help' : 'bridge router virtual mac and ips',
49 'validvals' : ['<mac-ip/prefixlen-list>',],
50 'example': ['address-virtual 00:11:22:33:44:01 11.0.1.1/24 11.0.1.2/24']
52 'address-virtual-ipv6-addrgen': {
53 'help': 'enable disable ipv6 link addrgenmode',
54 'validvals': ['on', 'off'],
57 'address-virtual-ipv6-addrgen on',
58 'address-virtual-ipv6-addrgen off'
64 def __init__(self
, *args
, **kargs
):
65 moduleBase
.__init
__(self
, *args
, **kargs
)
67 self
._bridge
_fdb
_query
_cache
= {}
68 self
.addressvirtual_with_route_metric
= utils
.get_boolean_from_string(
69 policymanager
.policymanager_api
.get_module_globals(
70 module_name
=self
.__class
__.__name
__,
71 attr
='addressvirtual_with_route_metric'
76 self
.address_virtual_ipv6_addrgen_value_dict
= {'on': 0, 'yes': 0, '0': 0, 'off': 1, 'no': 1, '1': 1}
78 def get_dependent_ifacenames(self
, ifaceobj
, ifacenames_all
=None):
79 if ifaceobj
.get_attr_value('address-virtual'):
80 ifaceobj
.link_privflags |
= ifaceLinkPrivFlags
.ADDRESS_VIRTUAL_SLAVE
82 def _get_macvlan_prefix(self
, ifaceobj
):
83 return '%s-v' %ifaceobj
.name
[0:13].replace('.', '-')
85 def _add_addresses_to_bridge(self
, ifaceobj
, hwaddress
):
86 # XXX: batch the addresses
87 if ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
:
88 bridgename
= ifaceobj
.lowerifaces
[0]
89 vlan
= self
._get
_vlan
_id
(ifaceobj
)
90 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
91 [self
.ipcmd
.bridge_fdb_add(bridgename
, addr
,
92 vlan
) for addr
in hwaddress
]
93 elif self
.ipcmd
.is_bridge(ifaceobj
.name
):
94 [self
.ipcmd
.bridge_fdb_add(ifaceobj
.name
, addr
)
95 for addr
in hwaddress
]
97 def _remove_addresses_from_bridge(self
, ifaceobj
, hwaddress
):
98 # XXX: batch the addresses
99 if ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
:
100 bridgename
= ifaceobj
.lowerifaces
[0]
101 vlan
= self
._get
_vlan
_id
(ifaceobj
)
102 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
103 for addr
in hwaddress
:
105 self
.ipcmd
.bridge_fdb_del(bridgename
, addr
, vlan
)
107 self
.logger
.debug("%s: %s" %(ifaceobj
.name
, str(e
)))
109 elif self
.ipcmd
.is_bridge(ifaceobj
.name
):
110 for addr
in hwaddress
:
112 self
.ipcmd
.bridge_fdb_del(ifaceobj
.name
, addr
)
114 self
.logger
.debug("%s: %s" %(ifaceobj
.name
, str(e
)))
117 def _get_bridge_fdbs(self
, bridgename
, vlan
):
118 fdbs
= self
._bridge
_fdb
_query
_cache
.get(bridgename
)
120 fdbs
= self
.ipcmd
.bridge_fdb_show_dev(bridgename
)
123 self
._bridge
_fdb
_query
_cache
[bridgename
] = fdbs
124 return fdbs
.get(vlan
)
126 def _check_addresses_in_bridge(self
, ifaceobj
, hwaddress
):
127 """ If the device is a bridge, make sure the addresses
128 are in the bridge """
129 if ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
:
130 bridgename
= ifaceobj
.lowerifaces
[0]
131 vlan
= self
._get
_vlan
_id
(ifaceobj
)
132 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
133 fdb_addrs
= self
._get
_bridge
_fdbs
(bridgename
, str(vlan
))
134 if not fdb_addrs
or hwaddress
not in fdb_addrs
:
138 def _fix_connected_route(self
, ifaceobj
, vifacename
, addr
):
140 # XXX: Hack to make sure the primary address
141 # is the first in the routing table.
143 # We use `ip route get` on the vrr network to see which
144 # device the kernel returns. if it is the mac vlan device,
145 # flap the macvlan device to adjust the routing table entry.
147 # flapping the macvlan device makes sure the macvlan
148 # connected route goes through delete + add, hence adjusting
149 # the order in the routing table.
152 self
.logger
.info('%s: checking route entry ...' %ifaceobj
.name
)
155 # we don't support ip6 route fix yet
156 if type(ip
) == IPv6Network
:
159 route_prefix
= '%s/%d' %(ip
.network
, ip
.prefixlen
)
161 if ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.VRF_SLAVE
:
162 vrf_master
= self
.ipcmd
.link_get_master(ifaceobj
.name
)
166 dev
= self
.ipcmd
.ip_route_get_dev(route_prefix
, vrf_master
=vrf_master
)
168 if dev
and dev
!= ifaceobj
.name
:
169 self
.logger
.info('%s: preferred routing entry ' %ifaceobj
.name
+
170 'seems to be of the macvlan dev %s'
172 ' .. flapping macvlan dev to fix entry.')
173 self
.ipcmd
.link_down(vifacename
)
174 self
.ipcmd
.link_up(vifacename
)
176 self
.logger
.debug('%s: fixing route entry failed (%s)'
177 % (ifaceobj
.name
, str(e
)))
180 def _handle_vrf_slaves(self
, macvlan_ifacename
, ifaceobj
):
181 vrfname
= self
.ipcmd
.link_get_master(ifaceobj
.name
)
183 self
.ipcmd
.link_set(macvlan_ifacename
, 'master', vrfname
)
185 def _get_macs_from_old_config(self
, ifaceobj
=None):
186 """ This method returns a list of the mac addresses
187 in the address-virtual attribute for the bridge. """
189 saved_ifaceobjs
= statemanager
.statemanager_api
.get_ifaceobjs(ifaceobj
.name
)
190 if not saved_ifaceobjs
:
192 # we need the old saved configs from the statemanager
193 for oldifaceobj
in saved_ifaceobjs
:
194 if not oldifaceobj
.get_attr_value('address-virtual'):
196 for av
in oldifaceobj
.get_attr_value('address-virtual'):
199 self
.logger
.debug("%s: incorrect old address-virtual attrs '%s'"
200 %(oldifaceobj
.name
, av
))
202 maclist
.append(macip
[0])
205 def get_addressvirtual_ipv6_addrgen_user_conf(self
, ifaceobj
):
206 ipv6_addrgen
= ifaceobj
.get_attr_value_first('address-virtual-ipv6-addrgen')
209 # IFLA_INET6_ADDR_GEN_MODE values:
212 ipv6_addrgen_nl
= self
.address_virtual_ipv6_addrgen_value_dict
.get(ipv6_addrgen
.lower(), None)
214 if ipv6_addrgen_nl
is None:
215 self
.logger
.warning('%s: invalid value "%s" for attribute address-virtual-ipv6-addrgen' % (ifaceobj
.name
, ipv6_addrgen
))
217 return True, ipv6_addrgen_nl
220 # if user didn't configure ipv6-addrgen, should we reset to default?
221 ipv6_addrgen_nl
= self
.address_virtual_ipv6_addrgen_value_dict
.get(
222 self
.get_attr_default_value('address-virtual-ipv6-addrgen'),
225 if ipv6_addrgen_nl
is not None:
226 return True, ipv6_addrgen_nl
230 def _apply_address_config(self
, ifaceobj
, address_virtual_list
):
231 purge_existing
= False if ifupdownflags
.flags
.PERFMODE
else True
233 lower_iface_mtu
= update_mtu
= None
234 if ifupdownconfig
.config
.get('adjust_logical_dev_mtu', '1') != '0':
235 if ifaceobj
.lowerifaces
and address_virtual_list
:
238 user_configured_ipv6_addrgenmode
, ipv6_addrgen_user_value
= self
.get_addressvirtual_ipv6_addrgen_user_conf(ifaceobj
)
241 self
.ipcmd
.batch_start()
243 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobj
)
244 for av
in address_virtual_list
:
245 av_attrs
= av
.split()
246 if len(av_attrs
) < 2:
247 self
.log_error("%s: incorrect address-virtual attrs '%s'"
248 %(ifaceobj
.name
, av
), ifaceobj
,
254 if not self
.check_mac_address(ifaceobj
, mac
):
256 # Create a macvlan device on this device and set the virtual
257 # router mac and ip on it
259 macvlan_ifacename
= '%s%d' %(macvlan_prefix
, av_idx
)
260 if not self
.ipcmd
.link_exists(macvlan_ifacename
):
262 netlink
.link_add_macvlan(ifaceobj
.name
, macvlan_ifacename
)
264 self
.ipcmd
.link_add_macvlan(ifaceobj
.name
, macvlan_ifacename
)
267 # first thing we need to handle vrf enslavement
268 if (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.VRF_SLAVE
):
269 self
._handle
_vrf
_slaves
(macvlan_ifacename
, ifaceobj
)
271 if user_configured_ipv6_addrgenmode
:
272 self
.ipcmd
.ipv6_addrgen(macvlan_ifacename
, ipv6_addrgen_user_value
, link_created
)
277 # customer could have used UPPERCASE for MAC
278 self
.ipcmd
.link_set_hwaddress(macvlan_ifacename
, mac
)
279 hwaddress
.append(mac
)
281 if self
.addressvirtual_with_route_metric
and self
.ipcmd
.addr_metric_support():
282 metric
= self
.ipcmd
.get_default_ip_metric()
286 self
.ipcmd
.addr_add_multiple(
294 # If link existed before, flap the link
297 if not self
.addressvirtual_with_route_metric
or not self
.ipcmd
.addr_metric_support():
298 # if the system doesn't support ip addr set METRIC
299 # we need to do manually check the ordering of the ip4 routes
300 self
._fix
_connected
_route
(ifaceobj
, macvlan_ifacename
, ips
[0])
303 lower_iface_mtu
= self
.ipcmd
.link_get_mtu(ifaceobj
.name
, refresh
=True)
306 if lower_iface_mtu
and lower_iface_mtu
!= self
.ipcmd
.link_get_mtu(macvlan_ifacename
, refresh
=True):
308 self
.ipcmd
.link_set_mtu(macvlan_ifacename
,
310 except Exception as e
:
311 self
.logger
.info('%s: failed to set mtu %s: %s' %
312 (macvlan_ifacename
, lower_iface_mtu
, e
))
314 # set macvlan device to up in anycase.
315 # since we auto create them here..we are responsible
316 # to bring them up here in the case they were brought down
317 # by some other entity in the system.
318 netlink
.link_set_updown(macvlan_ifacename
, "up")
321 if not self
.addressvirtual_with_route_metric
or not self
.ipcmd
.addr_metric_support():
322 # if the system doesn't support ip addr set METRIC
323 # we need to do manually check the ordering of the ip6 routes
324 self
.ipcmd
.fix_ipv6_route_metric(ifaceobj
, macvlan_ifacename
, ips
)
325 except Exception as e
:
326 self
.logger
.debug('fix_vrf_slave_ipv6_route_metric: failed: %s' % e
)
328 # Disable IPv6 duplicate address detection on VRR interfaces
329 for key
, sysval
in { 'accept_dad' : '0', 'dad_transmits' : '0' }.iteritems():
330 syskey
= 'net.ipv6.conf.%s.%s' % (macvlan_ifacename
, key
)
331 if self
.sysctl_get(syskey
) != sysval
:
332 self
.sysctl_set(syskey
, sysval
)
335 self
.ipcmd
.batch_commit()
337 # check the statemanager for old configs.
338 # We need to remove only the previously configured FDB entries
339 oldmacs
= self
._get
_macs
_from
_old
_config
(ifaceobj
)
340 # get a list of fdbs in old that are not in new config meaning they should
341 # be removed since they are gone from the config
342 removed_macs
= [mac
for mac
in oldmacs
if mac
.lower() not in hwaddress
]
343 self
._remove
_addresses
_from
_bridge
(ifaceobj
, removed_macs
)
344 # if ifaceobj is a bridge and bridge is a vlan aware bridge
345 # add the vid to the bridge
346 self
._add
_addresses
_to
_bridge
(ifaceobj
, hwaddress
)
348 def _remove_running_address_config(self
, ifaceobj
):
349 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
352 self
.ipcmd
.batch_start()
353 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobj
)
354 for macvlan_ifacename
in glob
.glob("/sys/class/net/%s*" %macvlan_prefix
):
355 macvlan_ifacename
= os
.path
.basename(macvlan_ifacename
)
356 if not self
.ipcmd
.link_exists(macvlan_ifacename
):
358 hwaddress
.append(self
.ipcmd
.link_get_hwaddress(macvlan_ifacename
))
359 self
.ipcmd
.link_delete(os
.path
.basename(macvlan_ifacename
))
360 # XXX: Also delete any fdb addresses. This requires, checking mac address
361 # on individual macvlan interfaces and deleting the vlan from that.
362 self
.ipcmd
.batch_commit()
364 self
._remove
_addresses
_from
_bridge
(ifaceobj
, hwaddress
)
366 def _remove_address_config(self
, ifaceobj
, address_virtual_list
=None):
367 if not address_virtual_list
:
368 self
._remove
_running
_address
_config
(ifaceobj
)
371 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
374 self
.ipcmd
.batch_start()
376 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobj
)
377 for av
in address_virtual_list
:
378 av_attrs
= av
.split()
379 if len(av_attrs
) < 2:
380 self
.log_error("%s: incorrect address-virtual attrs '%s'"
381 %(ifaceobj
.name
, av
), ifaceobj
,
386 # Delete the macvlan device on this device
387 macvlan_ifacename
= '%s%d' %(macvlan_prefix
, av_idx
)
388 self
.ipcmd
.link_delete(os
.path
.basename(macvlan_ifacename
))
389 if av_attrs
[0] != 'None':
390 hwaddress
.append(av_attrs
[0])
392 self
.ipcmd
.batch_commit()
393 self
._remove
_addresses
_from
_bridge
(ifaceobj
, hwaddress
)
395 def check_mac_address(self
, ifaceobj
, mac
):
400 if int(mac
.split(":")[0], 16) & 1 :
401 self
.log_error("%s: Multicast bit is set in the virtual mac address '%s'"
402 % (ifaceobj
.name
, mac
), ifaceobj
=ifaceobj
)
408 def _fixup_vrf_enslavements(self
, ifaceobj
, ifaceobj_getfunc
=None):
409 """ This function fixes up address virtual interfaces
410 (macvlans) on vrf slaves. Since this fixup is an overhead,
411 this must be called only in cases when ifupdown2 is
412 called on the vrf device or its slave and not when
413 ifupdown2 is called for all devices. When all
414 interfaces are brought up, the expectation is that
415 the normal path will fix up a vrf device or its slaves"""
417 if not ifaceobj_getfunc
:
419 if ((ifaceobj
.link_kind
& ifaceLinkKind
.VRF
) and
420 self
.ipcmd
.link_exists(ifaceobj
.name
)):
421 # if I am a vrf device and I have slaves
422 # that have address virtual config,
423 # enslave the slaves 'address virtual
424 # interfaces (macvlans)' to myself:
425 running_slaves
= self
.ipcmd
.link_get_lowers(ifaceobj
.name
)
427 # pick up any existing slaves of a vrf device and
428 # look for their upperdevices and enslave them to the
430 for s
in running_slaves
:
431 sobjs
= ifaceobj_getfunc(s
)
433 (sobjs
[0].link_privflags
& ifaceLinkPrivFlags
.ADDRESS_VIRTUAL_SLAVE
)):
434 # enslave all its upper devices to
436 upperdevs
= self
.ipcmd
.link_get_uppers(sobjs
[0].name
)
440 # skip vrf device which
441 # will also show up in the
443 if u
== ifaceobj
.name
:
445 self
.ipcmd
.link_set(u
, 'master', ifaceobj
.name
,
447 elif ((ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.ADDRESS_VIRTUAL_SLAVE
) and
448 (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.VRF_SLAVE
) and
449 self
.ipcmd
.link_exists(ifaceobj
.name
)):
450 # If I am a vrf slave and I have 'address virtual'
451 # config, make sure my addrress virtual interfaces
452 # (macvlans) are also enslaved to the vrf device
453 vrfname
= ifaceobj
.get_attr_value_first('vrf')
454 if not vrfname
or not self
.ipcmd
.link_exists(vrfname
):
456 running_uppers
= self
.ipcmd
.link_get_uppers(ifaceobj
.name
)
457 if not running_uppers
:
459 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobj
)
460 if not macvlan_prefix
:
462 for u
in running_uppers
:
465 if u
.startswith(macvlan_prefix
):
466 self
.ipcmd
.link_set(u
, 'master', vrfname
,
469 def _up(self
, ifaceobj
, ifaceobj_getfunc
=None):
470 if not ifupdownflags
.flags
.ALL
:
471 self
._fixup
_vrf
_enslavements
(ifaceobj
, ifaceobj_getfunc
)
472 address_virtual_list
= ifaceobj
.get_attr_value('address-virtual')
473 if not address_virtual_list
:
474 # XXX: address virtual is not present. In which case,
475 # delete stale macvlan devices.
476 self
._remove
_address
_config
(ifaceobj
, address_virtual_list
)
479 if (ifaceobj
.upperifaces
and
480 not ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.VRF_SLAVE
):
481 self
.log_error('%s: invalid placement of address-virtual lines (must be configured under an interface with no upper interfaces or parent interfaces)'
482 % (ifaceobj
.name
), ifaceobj
)
485 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
487 self
._apply
_address
_config
(ifaceobj
, address_virtual_list
)
489 def _down(self
, ifaceobj
, ifaceobj_getfunc
=None):
491 self
._remove
_address
_config
(ifaceobj
,
492 ifaceobj
.get_attr_value('address-virtual'))
494 self
.log_warn(str(e
))
496 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
497 address_virtual_list
= ifaceobj
.get_attr_value('address-virtual')
498 if not address_virtual_list
:
500 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
503 user_config_address_virtual_ipv6_addr
= ifaceobj
.get_attr_value_first('address-virtual-ipv6-addrgen')
504 if user_config_address_virtual_ipv6_addr
and user_config_address_virtual_ipv6_addr
not in utils
._string
_values
:
505 ifaceobjcurr
.update_config_with_status('address-virtual-ipv6-addrgen', user_config_address_virtual_ipv6_addr
, 1)
506 user_config_address_virtual_ipv6_addr
= None
507 macvlans_running_ipv6_addr
= []
510 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobj
)
511 for address_virtual
in address_virtual_list
:
512 av_attrs
= address_virtual
.split()
513 if len(av_attrs
) < 2:
514 self
.logger
.warn("%s: incorrect address-virtual attrs '%s'"
515 %(ifaceobj
.name
, address_virtual
))
519 # Check if the macvlan device on this interface
520 macvlan_ifacename
= '%s%d' %(macvlan_prefix
, av_idx
)
521 if not self
.ipcmd
.link_exists(macvlan_ifacename
):
522 ifaceobjcurr
.update_config_with_status('address-virtual',
527 if user_config_address_virtual_ipv6_addr
:
528 macvlans_running_ipv6_addr
.append(self
.ipcmd
.get_ipv6_addrgen_mode(macvlan_ifacename
))
530 # Check mac and ip address
531 rhwaddress
= self
.ipcmd
.link_get_hwaddress(macvlan_ifacename
)
532 raddrs
= self
.ipcmd
.get_running_addrs(
533 ifname
=macvlan_ifacename
,
535 addr_virtual_ifaceobj
=ifaceobj
537 if not raddrs
or not rhwaddress
:
538 ifaceobjcurr
.update_config_with_status('address-virtual', '', 1)
542 av_attrs
[0] = ':'.join([i
if len(i
) == 2 else '0%s' % i
543 for i
in av_attrs
[0].split(':')])
545 self
.logger
.info('%s: %s: invalid value for address-virtual (%s)'
550 if (rhwaddress
== av_attrs
[0].lower() and
551 self
.ipcmd
.compare_user_config_vs_running_state(raddrs
, av_attrs
[1:]) and
552 self
._check
_addresses
_in
_bridge
(ifaceobj
, av_attrs
[0].lower())):
553 ifaceobjcurr
.update_config_with_status('address-virtual',
556 raddress_virtual
= '%s %s' % (rhwaddress
, ' '.join(raddrs
))
557 ifaceobjcurr
.update_config_with_status('address-virtual',
560 raddress_virtual
= '%s %s' % (rhwaddress
, ' '.join(raddrs
))
561 ifaceobjcurr
.update_config_with_status('address-virtual',
565 if user_config_address_virtual_ipv6_addr
:
566 bool_user_ipv6_addrgen
= utils
.get_boolean_from_string(user_config_address_virtual_ipv6_addr
)
567 for running_ipv6_addrgen
in macvlans_running_ipv6_addr
:
568 if (not bool_user_ipv6_addrgen
) != running_ipv6_addrgen
:
569 ifaceobjcurr
.update_config_with_status('address-virtual-ipv6-addrgen', user_config_address_virtual_ipv6_addr
, 1)
571 ifaceobjcurr
.update_config_with_status('address-virtual-ipv6-addrgen', user_config_address_virtual_ipv6_addr
, 0)
573 def _query_running(self
, ifaceobjrunning
, ifaceobj_getfunc
=None):
574 macvlan_prefix
= self
._get
_macvlan
_prefix
(ifaceobjrunning
)
575 address_virtuals
= glob
.glob("/sys/class/net/%s*" %macvlan_prefix
)
576 macvlans_ipv6_addrgen_list
= []
577 for av
in address_virtuals
:
578 macvlan_ifacename
= os
.path
.basename(av
)
579 rhwaddress
= self
.ipcmd
.link_get_hwaddress(macvlan_ifacename
)
582 for obj
in ifaceobj_getfunc(ifaceobjrunning
.name
) or []:
583 raddress
.extend(self
.ipcmd
.get_running_addrs(None, macvlan_ifacename
, addr_virtual_ifaceobj
=obj
) or [])
585 raddress
= list(set(raddress
))
588 self
.logger
.warn('%s: no running addresses'
589 %ifaceobjrunning
.name
)
591 ifaceobjrunning
.update_config('address-virtual',
592 '%s %s' %(rhwaddress
, ' '.join(raddress
)))
594 macvlans_ipv6_addrgen_list
.append((macvlan_ifacename
, self
.ipcmd
.get_ipv6_addrgen_mode(macvlan_ifacename
)))
596 macvlan_count
= len(address_virtuals
)
597 if not macvlan_count
:
599 ipv6_addrgen
= macvlans_ipv6_addrgen_list
[0][1]
601 for macvlan_ifname
, macvlan_ipv6_addrgen
in macvlans_ipv6_addrgen_list
:
602 if macvlan_ipv6_addrgen
!= ipv6_addrgen
:
603 # one macvlan has a different ipv6-addrgen configuration
604 # we simply return, ifquery-running will print the macvlan
605 # stanzas with the ipv6-addrgen on/off attribute
607 ifaceobjrunning
.update_config('address-virtual-ipv6-addrgen', 'off' if ipv6_addrgen
else 'on')
610 _run_ops
= {'up' : _up
,
612 'query-checkcurr' : _query_check
,
613 'query-running' : _query_running
}
616 """ returns list of ops supported by this module """
617 return self
._run
_ops
.keys()
619 def _init_command_handlers(self
):
621 self
.ipcmd
= LinkUtils()
623 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None,
624 ifaceobj_getfunc
=None, **extra_args
):
625 """ run vlan configuration on the interface object passed as argument
628 **ifaceobj** (object): iface object
630 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
633 **query_ifaceobj** (object): query check ifaceobject. This is only
634 valid when op is 'query-checkcurr'. It is an object same as
635 ifaceobj, but contains running attribute values and its config
636 status. The modules can use it to return queried running state
637 of interfaces. status is success if the running state is same
638 as user required state in ifaceobj. error otherwise.
640 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
642 op_handler
= self
._run
_ops
.get(operation
)
645 self
._init
_command
_handlers
()
646 if operation
== 'query-checkcurr':
647 op_handler(self
, ifaceobj
, query_ifaceobj
)
649 op_handler(self
, ifaceobj
, ifaceobj_getfunc
=ifaceobj_getfunc
)