#!/usr/bin/python
#
-# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
+# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
#
+import socket
+
+from ipaddr import IPNetwork, IPv4Network, IPv6Network, _BaseV6
+
try:
- from ipaddr import IPNetwork
- from sets import Set
+ from ifupdown2.ifupdown.iface import *
+ from ifupdown2.ifupdown.utils import utils
+ from ifupdown2.ifupdown.netlink import netlink
+
+ from ifupdown2.ifupdownaddons.dhclient import dhclient
+ from ifupdown2.ifupdownaddons.LinkUtils import LinkUtils
+ from ifupdown2.ifupdownaddons.modulebase import moduleBase
+
+ import ifupdown2.ifupdown.statemanager as statemanager
+ import ifupdown2.ifupdown.policymanager as policymanager
+ import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
+ import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
+except ImportError:
from ifupdown.iface import *
- from ifupdownaddons.modulebase import moduleBase
- from ifupdownaddons.iproute2 import iproute2
+ from ifupdown.utils import utils
+ from ifupdown.netlink import netlink
+
from ifupdownaddons.dhclient import dhclient
-except ImportError, e:
- raise ImportError (str(e) + "- required module not found")
+ from ifupdownaddons.LinkUtils import LinkUtils
+ from ifupdownaddons.modulebase import moduleBase
+
+ import ifupdown.statemanager as statemanager
+ import ifupdown.policymanager as policymanager
+ import ifupdown.ifupdownflags as ifupdownflags
+ import ifupdown.ifupdownconfig as ifupdownconfig
+
class address(moduleBase):
""" ifupdown2 addon module to configure address, mtu, hwaddress, alias
'attrs': {
'address' :
{'help' : 'ipv4 or ipv6 addresses',
+ 'validvals' : ['<ipv4/prefixlen>', '<ipv6/prefixlen>'],
+ 'multiline' : True,
'example' : ['address 10.0.12.3/24',
'address 2000:1000:1000:1000:3::5/128']},
'netmask' :
'compat' : True},
'broadcast' :
{'help': 'broadcast address',
+ 'validvals' : ['<ipv4>', ],
'example' : ['broadcast 10.0.1.255']},
'scope' :
{'help': 'scope',
+ 'validvals' : ['universe', 'site', 'link', 'host', 'nowhere'],
'example' : ['scope host']},
'preferred-lifetime' :
{'help': 'preferred lifetime',
+ 'validrange' : ['0', '65535'],
'example' : ['preferred-lifetime forever',
'preferred-lifetime 10']},
'gateway' :
{'help': 'default gateway',
+ 'validvals' : ['<ipv4>', '<ipv6>'],
+ 'multiline' : True,
'example' : ['gateway 255.255.255.0']},
'mtu' :
{ 'help': 'interface mtu',
+ 'validrange' : ['552', '9216'],
'example' : ['mtu 1600'],
'default' : '1500'},
'hwaddress' :
{'help' : 'hw address',
+ 'validvals' : ['<mac>',],
'example': ['hwaddress 44:38:39:00:27:b8']},
'alias' :
{ 'help': 'description/alias',
'purged to match persistant addresses in the ' +
'interfaces file. Set this attribute to \'no\'' +
'if you want to preserve existing addresses',
+ 'validvals' : ['yes', 'no'],
'default' : 'yes',
- 'example' : ['address-purge yes/no']}}}
+ 'example' : ['address-purge yes/no']},
+ 'clagd-vxlan-anycast-ip' :
+ { 'help' : 'Anycast local IP address for ' +
+ 'dual connected VxLANs',
+ 'validvals' : ['<ipv4>', ],
+ 'example' : ['clagd-vxlan-anycast-ip 36.0.0.11']},
+ 'ip-forward' :
+ { 'help': 'ip forwarding flag',
+ 'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
+ 'default' : 'off',
+ 'example' : ['ip-forward off']},
+ 'ip6-forward' :
+ { 'help': 'ipv6 forwarding flag',
+ 'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
+ 'default' : 'off',
+ 'example' : ['ip6-forward off']},
+ 'mpls-enable' :
+ { 'help': 'mpls enable flag',
+ 'validvals': ['yes', 'no'],
+ 'default' : 'no',
+ 'example' : ['mpls-enable yes']},
+ 'ipv6-addrgen': {
+ 'help': 'enable disable ipv6 link addrgenmode',
+ 'validvals': ['on', 'off'],
+ 'default': 'on',
+ 'example': [
+ 'ipv6-addrgen on',
+ 'ipv6-addrgen off'
+ ]
+ }
+ }}
def __init__(self, *args, **kargs):
moduleBase.__init__(self, *args, **kargs)
self.ipcmd = None
self._bridge_fdb_query_cache = {}
+ self.default_mtu = policymanager.policymanager_api.get_attr_default(module_name=self.__class__.__name__, attr='mtu')
+ self.max_mtu = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='max_mtu')
+ self.ipforward = policymanager.policymanager_api.get_attr_default(module_name=self.__class__.__name__, attr='ip-forward')
+ self.ip6forward = policymanager.policymanager_api.get_attr_default(module_name=self.__class__.__name__, attr='ip6-forward')
+ self.ifaces_defaults = policymanager.policymanager_api.get_iface_defaults(module_name=self.__class__.__name__)
+ self.enable_l3_iface_forwarding_checks = utils.get_boolean_from_string(
+ policymanager.policymanager_api.get_module_globals(
+ self.__class__.__name__,
+ 'enable_l3_iface_forwarding_checks'
+ )
+ )
+
+ if not self.default_mtu:
+ self.default_mtu = '1500'
+
+ self.logger.info('address: using default mtu %s' %self.default_mtu)
+
+ if self.max_mtu:
+ self.logger.info('address: using max mtu %s' %self.max_mtu)
+
+ self.lower_iface_mtu_checked_list = list()
+
+ self.l3_intf_arp_accept = utils.get_boolean_from_string(
+ policymanager.policymanager_api.get_module_globals(
+ module_name=self.__class__.__name__,
+ attr='l3_intf_arp_accept'
+ ),
+ default=False
+ )
+
+ def syntax_check(self, ifaceobj, ifaceobj_getfunc=None):
+ return (self.syntax_check_multiple_gateway(ifaceobj)
+ and self.syntax_check_addr_allowed_on(ifaceobj, True)
+ and self.syntax_check_mtu(ifaceobj, ifaceobj_getfunc)
+ and self.syntax_check_sysctls(ifaceobj)
+ and self.syntax_check_enable_l3_iface_forwardings(ifaceobj, ifaceobj_getfunc, syntax_check=True))
+
+ def syntax_check_enable_l3_iface_forwardings(self, ifaceobj, ifaceobj_getfunc, syntax_check=False):
+ if (self.enable_l3_iface_forwarding_checks
+ and (ifaceobj.link_kind & ifaceLinkKind.VLAN
+ or ifaceobj.link_kind & ifaceLinkKind.BRIDGE)
+ and not ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT):
+
+ ifname = ifaceobj.name
+ vlan_addr = None
+ vlan_ipforward_off = None
+
+ for obj in ifaceobj_getfunc(ifname) or [ifaceobj]:
+ if not vlan_addr:
+ vlan_addr = obj.get_attr_value('address')
+
+ if not vlan_ipforward_off:
+ ip_forward_value = obj.get_attr_value_first('ip-forward')
+
+ if ip_forward_value and not utils.get_boolean_from_string(ip_forward_value):
+ vlan_ipforward_off = True
+
+ if vlan_addr and vlan_ipforward_off:
+ if syntax_check:
+ raise Exception(
+ 'configuring ip-forward off and ip address(es) (%s) is not compatible'
+ % (', '.join(vlan_addr))
+ )
+ else:
+ raise Exception(
+ '%s: configuring ip-forward off and ip address(es) (%s) is not compatible'
+ % (ifname, ', '.join(vlan_addr))
+ )
+
+ return True
+
+ def syntax_check_sysctls(self, ifaceobj):
+ result = True
+ bridge_port = (ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT)
+ ipforward = ifaceobj.get_attr_value_first('ip-forward')
+ if bridge_port and ipforward:
+ result = False
+ self.log_error('%s: \'ip-forward\' is not supported for '
+ 'bridge port' %ifaceobj.name)
+ ip6forward = ifaceobj.get_attr_value_first('ip6-forward')
+ if bridge_port and ip6forward:
+ result = False
+ self.log_error('%s: \'ip6-forward\' is not supported for '
+ 'bridge port' %ifaceobj.name)
+ return result
+
+ def syntax_check_mtu(self, ifaceobj, ifaceobj_getfunc):
+ mtu = ifaceobj.get_attr_value_first('mtu')
+ if mtu:
+ return self._check_mtu_config(ifaceobj, mtu, ifaceobj_getfunc,
+ syntaxcheck=True)
+ return True
+
+ def syntax_check_addr_allowed_on(self, ifaceobj, syntax_check=False):
+ if ifaceobj.get_attr_value('address'):
+ return utils.is_addr_ip_allowed_on(ifaceobj, syntax_check=syntax_check)
+ return True
+
+ def _syntax_check_multiple_gateway(self, family, found, addr, type_obj):
+ if type(IPNetwork(addr)) == type_obj:
+ if found:
+ raise Exception('%s: multiple gateways for %s family'
+ % (addr, family))
+ return True
+ return False
+
+ def syntax_check_multiple_gateway(self, ifaceobj):
+ result = True
+ inet = False
+ inet6 = False
+ gateways = ifaceobj.get_attr_value('gateway')
+ for addr in gateways if gateways else []:
+ try:
+ if self._syntax_check_multiple_gateway('inet', inet, addr,
+ IPv4Network):
+ inet = True
+ if self._syntax_check_multiple_gateway('inet6', inet6, addr,
+ IPv6Network):
+ inet6 = True
+ except Exception as e:
+ self.logger.warning('%s: address: %s' % (ifaceobj.name, str(e)))
+ result = False
+ return result
def _address_valid(self, addrs):
if not addrs:
return True
return False
+ def _get_hwaddress(self, ifaceobj):
+ return utils.strip_hwaddress(ifaceobj.get_attr_value_first('hwaddress'))
+
def _process_bridge(self, ifaceobj, up):
- hwaddress = ifaceobj.get_attr_value_first('hwaddress')
+ hwaddress = self._get_hwaddress(ifaceobj)
addrs = ifaceobj.get_attr_value_first('address')
is_vlan_dev_on_vlan_aware_bridge = False
is_bridge = self.ipcmd.is_bridge(ifaceobj.name)
if not is_bridge:
- if '.' in ifaceobj.name:
- (bridgename, vlan) = ifaceobj.name.split('.')
+ if ifaceobj.link_kind & ifaceLinkKind.VLAN:
+ bridgename = ifaceobj.lowerifaces[0]
+ vlan = self._get_vlan_id(ifaceobj)
is_vlan_dev_on_vlan_aware_bridge = self.ipcmd.bridge_is_vlan_aware(bridgename)
if ((is_bridge and not self.ipcmd.bridge_is_vlan_aware(ifaceobj.name))
or is_vlan_dev_on_vlan_aware_bridge):
- if self._address_valid(addrs):
- if up:
- self.write_file('/proc/sys/net/ipv4/conf/%s' %ifaceobj.name +
- '/arp_accept', '1')
- else:
- self.write_file('/proc/sys/net/ipv4/conf/%s' %ifaceobj.name +
- '/arp_accept', '0')
+ if self._address_valid(addrs):
+ if self.l3_intf_arp_accept:
+ if up:
+ self.write_file('/proc/sys/net/ipv4/conf/%s' % ifaceobj.name +
+ '/arp_accept', '1')
+ else:
+ self.write_file('/proc/sys/net/ipv4/conf/%s' % ifaceobj.name +
+ '/arp_accept', '0')
+ else:
+ self.write_file('/proc/sys/net/ipv4/conf/%s/arp_accept' % ifaceobj.name, '0')
if hwaddress and is_vlan_dev_on_vlan_aware_bridge:
if up:
self.ipcmd.bridge_fdb_add(bridgename, hwaddress, vlan)
else:
self.ipcmd.bridge_fdb_del(bridgename, hwaddress, vlan)
- def _inet_address_config(self, ifaceobj):
- purge_addresses = ifaceobj.get_attr_value_first('address-purge')
- if not purge_addresses:
- purge_addresses = 'yes'
+ def _get_anycast_addr(self, ifaceobjlist):
+ for ifaceobj in ifaceobjlist:
+ anycast_addr = ifaceobj.get_attr_value_first('clagd-vxlan-anycast-ip')
+ if anycast_addr:
+ anycast_addr = anycast_addr+'/32'
+ return anycast_addr
+ return None
+
+ def _inet_address_convert_to_cidr(self, ifaceobjlist):
newaddrs = []
- addrs = ifaceobj.get_attr_value('address')
- if addrs:
- if ifaceobj.role & ifaceRole.SLAVE:
- # we must not configure an IP address if the interface is enslaved
- self.log_warn('interface %s is enslaved and cannot have an IP Address' % \
- (ifaceobj.name))
- return
+ newaddr_attrs = {}
+
+ for ifaceobj in ifaceobjlist:
+ addrs = ifaceobj.get_attr_value('address')
+ if not addrs:
+ continue
+
+ if not self.syntax_check_addr_allowed_on(ifaceobj,
+ syntax_check=False):
+ return (False, newaddrs, newaddr_attrs)
# If user address is not in CIDR notation, convert them to CIDR
for addr_index in range(0, len(addrs)):
addr = addrs[addr_index]
+ newaddr = addr
if '/' in addr:
newaddrs.append(addr)
- continue
- netmask = ifaceobj.get_attr_value_n('netmask', addr_index)
- if netmask:
- prefixlen = IPNetwork('%s' %addr +
- '/%s' %netmask).prefixlen
- newaddrs.append(addr + '/%s' %prefixlen)
else:
- newaddrs.append(addr)
+ netmask = ifaceobj.get_attr_value_n('netmask', addr_index)
+ if netmask:
+ prefixlen = IPNetwork('%s' %addr +
+ '/%s' %netmask).prefixlen
+ newaddr = addr + '/%s' %prefixlen
+ else:
+ # we are here because there is no slash (/xx) and no netmask
+ # just let IPNetwork handle the ipv4 or ipv6 address mask
+ prefixlen = IPNetwork(addr).prefixlen
+ newaddr = addr + '/%s' %prefixlen
+ newaddrs.append(newaddr)
+
+ attrs = {}
+ for a in ['broadcast', 'pointopoint', 'scope',
+ 'preferred-lifetime']:
+ aval = ifaceobj.get_attr_value_n(a, addr_index)
+ if aval:
+ attrs[a] = aval
+
+ if attrs:
+ newaddr_attrs[newaddr]= attrs
+ return (True, newaddrs, newaddr_attrs)
+
+ def _inet_address_list_config(self, ifaceobj, newaddrs, newaddr_attrs):
+ for addr_index in range(0, len(newaddrs)):
+ try:
+ if newaddr_attrs:
+ self.ipcmd.addr_add(ifaceobj.name, newaddrs[addr_index],
+ newaddr_attrs.get(newaddrs[addr_index],
+ {}).get('broadcast'),
+ newaddr_attrs.get(newaddrs[addr_index],
+ {}).get('pointopoint'),
+ newaddr_attrs.get(newaddrs[addr_index],
+ {}).get('scope'),
+ newaddr_attrs.get(newaddrs[addr_index],
+ {}).get('preferred-lifetime'))
+ else:
+ self.ipcmd.addr_add(ifaceobj.name, newaddrs[addr_index])
+ except Exception, e:
+ self.log_error(str(e), ifaceobj)
+
+ def _inet_address_config(self, ifaceobj, ifaceobj_getfunc=None,
+ force_reapply=False):
+ squash_addr_config = (True if \
+ ifupdownconfig.config.get('addr_config_squash', \
+ '0') == '1' else False)
+
+ if (squash_addr_config and
+ not (ifaceobj.flags & ifaceobj.YOUNGEST_SIBLING)):
+ return
+
+ purge_addresses = ifaceobj.get_attr_value_first('address-purge')
+ if not purge_addresses:
+ purge_addresses = 'yes'
+
+ if squash_addr_config and ifaceobj.flags & iface.HAS_SIBLINGS:
+ ifaceobjlist = ifaceobj_getfunc(ifaceobj.name)
+ else:
+ ifaceobjlist = [ifaceobj]
+
+ module_name = self.__class__.__name__
+ ifname = ifaceobj.name
+
+ (addr_supported, newaddrs, newaddr_attrs) = self._inet_address_convert_to_cidr(ifaceobjlist)
+ newaddrs = utils.get_ip_objs(module_name, ifname, newaddrs)
- if (not self.PERFMODE and
- not (ifaceobj.flags & iface.HAS_SIBLINGS) and
- purge_addresses == 'yes'):
- # if perfmode is not set and also if iface has no sibling
- # objects, purge addresses that are not present in the new
- # config
- runningaddrs = self.ipcmd.addr_get(ifaceobj.name, details=False)
- if newaddrs == runningaddrs:
+ if not addr_supported:
+ return
+ if (not squash_addr_config and (ifaceobj.flags & iface.HAS_SIBLINGS)):
+ # if youngest sibling and squash addr is not set
+ # print a warning that addresses will not be purged
+ if (ifaceobj.flags & iface.YOUNGEST_SIBLING):
+ self.logger.warn('%s: interface has multiple ' %ifaceobj.name +
+ 'iface stanzas, skip purging existing addresses')
+ purge_addresses = 'no'
+
+ if not ifupdownflags.flags.PERFMODE and purge_addresses == 'yes':
+ # if perfmode is not set and purge addresses is not set to 'no'
+ # lets purge addresses not in the config
+ runningaddrs = self.ipcmd.get_running_addrs(ifaceobj, details=False)
+
+ # if anycast address is configured on 'lo' and is in running config
+ # add it to newaddrs so that ifreload doesn't wipe it out
+ anycast_addr = utils.get_normalized_ip_addr(ifaceobj.name, self._get_anycast_addr(ifaceobjlist))
+
+ if runningaddrs and anycast_addr and anycast_addr in runningaddrs:
+ newaddrs.append(anycast_addr)
+
+ user_ip4, user_ip6, newaddrs = self.order_user_configured_addrs(newaddrs)
+
+ if newaddrs == runningaddrs or self.compare_running_ips_and_user_config(user_ip4, user_ip6, runningaddrs):
+ if force_reapply:
+ self._inet_address_list_config(ifaceobj, newaddrs, newaddr_attrs)
return
try:
# if primary address is not same, there is no need to keep any.
# reset all addresses
- if (newaddrs and runningaddrs and
- (newaddrs[0] != runningaddrs[0])):
- self.ipcmd.del_addr_all(ifaceobj.name)
+ if newaddrs and runningaddrs and newaddrs[0] != runningaddrs[0]:
+ skip_addrs = []
else:
- self.ipcmd.del_addr_all(ifaceobj.name, newaddrs)
+ skip_addrs = newaddrs or []
+ for addr in runningaddrs or []:
+ if addr in skip_addrs:
+ continue
+ self.ipcmd.addr_del(ifaceobj.name, addr)
except Exception, e:
self.log_warn(str(e))
if not newaddrs:
return
- for addr_index in range(0, len(newaddrs)):
+ self._inet_address_list_config(ifaceobj, newaddrs, newaddr_attrs)
+
+ def compare_running_ips_and_user_config(self, user_ip4, user_ip6, running_addrs):
+ """
+ We need to compare the user config ips and the running ips.
+ ip4 ordering matters (primary etc) but ip6 order doesn't matter
+
+ this function replaces the strict comparison previously in place
+ if newaddrs == running_addrs ?
+
+ We will compare if the ip4 ordering is correct, then check if all
+ ip6 are present in the list (without checking the ordering)
+ """
+ if (user_ip4 or user_ip6) and not running_addrs:
+ return False
+ elif running_addrs and not user_ip4 and not user_ip6:
+ return False
+ elif not running_addrs and not user_ip4 and not user_ip6:
+ return True
+
+ len_ip4 = len(user_ip4)
+ len_running_addrs = len(running_addrs)
+
+ if len_ip4 > len_running_addrs:
+ return False
+
+ i = 0
+ while i < len_ip4:
+ if user_ip4[i] != running_addrs[i]:
+ return False
+ i += 1
+
+ if len_ip4 > 0:
+ running_ip6 = running_addrs[len_ip4:]
+ else:
+ running_ip6 = running_addrs
+
+ i = 0
+ len_ip6 = len(user_ip6)
+
+ for ip6 in running_ip6:
+ if ip6 not in user_ip6:
+ return False
+ i += 1
+
+ return i == len_ip6
+
+ def order_user_configured_addrs(self, user_config_addrs):
+ ip4 = []
+ ip6 = []
+
+ for a in user_config_addrs:
+ if isinstance(a, _BaseV6):
+ ip6.append(str(a))
+ else:
+ ip4.append(str(a))
+
+ return ip4, ip6, ip4 + ip6
+
+ def _delete_gateway(self, ifaceobj, gateways, vrf, metric):
+ for del_gw in gateways:
try:
- self.ipcmd.addr_add(ifaceobj.name, newaddrs[addr_index],
- ifaceobj.get_attr_value_n('broadcast', addr_index),
- ifaceobj.get_attr_value_n('pointopoint',addr_index),
- ifaceobj.get_attr_value_n('scope', addr_index),
- ifaceobj.get_attr_value_n('preferred-lifetime', addr_index))
- except Exception, e:
- self.log_error(str(e))
+ self.ipcmd.route_del_gateway(ifaceobj.name, del_gw, vrf, metric)
+ except Exception as e:
+ self.logger.debug('%s: %s' % (ifaceobj.name, str(e)))
+
+ def _add_delete_gateway(self, ifaceobj, gateways=[], prev_gw=[]):
+ vrf = ifaceobj.get_attr_value_first('vrf')
+ metric = ifaceobj.get_attr_value_first('metric')
+ self._delete_gateway(ifaceobj, list(set(prev_gw) - set(gateways)),
+ vrf, metric)
+ for add_gw in gateways:
+ try:
+ self.ipcmd.route_add_gateway(ifaceobj.name, add_gw, vrf, metric)
+ except Exception as e:
+ self.log_error('%s: %s' % (ifaceobj.name, str(e)))
+
+ def _get_prev_gateway(self, ifaceobj, gateways):
+ ipv = []
+ saved_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name)
+ if not saved_ifaceobjs:
+ return ipv
+ prev_gateways = saved_ifaceobjs[0].get_attr_value('gateway')
+ if not prev_gateways:
+ return ipv
+ return prev_gateways
+
+ def _check_mtu_config(self, ifaceobj, mtu, ifaceobj_getfunc, syntaxcheck=False):
+ retval = True
+ if (ifaceobj.link_kind & ifaceLinkKind.BRIDGE):
+ if syntaxcheck:
+ self.logger.warn('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj.name)
+ retval = False
+ else:
+ self.logger.info('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj.name)
+ elif ifaceobj_getfunc:
+ if ((ifaceobj.link_privflags & ifaceLinkPrivFlags.BOND_SLAVE) and
+ ifaceobj.upperifaces):
+ masterobj = ifaceobj_getfunc(ifaceobj.upperifaces[0])
+ if masterobj:
+ master_mtu = masterobj[0].get_attr_value_first('mtu')
+ if master_mtu and master_mtu != mtu:
+ if syntaxcheck:
+ self.logger.warn('%s: bond slave mtu %s is different from bond master %s mtu %s. There is no need to configure mtu on a bond slave.' %(ifaceobj.name, mtu, masterobj[0].name, master_mtu))
+ retval = False
+ else:
+ self.logger.info('%s: bond slave mtu %s is different from bond master %s mtu %s. There is no need to configure mtu on a bond slave.' %(ifaceobj.name, mtu, masterobj[0].name, master_mtu))
+ elif ((ifaceobj.link_kind & ifaceLinkKind.VLAN) and
+ ifaceobj.lowerifaces):
+ lowerobj = ifaceobj_getfunc(ifaceobj.lowerifaces[0])
+ if lowerobj:
+ if syntaxcheck:
+ lowerdev_mtu = lowerobj[0].get_attr_value_first('mtu')
+ else:
+ lowerdev_mtu = self.ipcmd.link_get_mtu_sysfs(lowerobj[0].name)
+ if lowerdev_mtu and int(mtu) > int(lowerdev_mtu):
+ self.logger.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
+ %(ifaceobj.name, mtu, lowerobj[0].name, lowerdev_mtu))
+ retval = False
+ elif (not lowerobj[0].link_kind and
+ not (lowerobj[0].link_privflags & ifaceLinkPrivFlags.LOOPBACK) and
+ not lowerdev_mtu and self.default_mtu and
+ (int(mtu) > int(self.default_mtu))):
+ # only check default mtu on lower device which is a physical interface
+ self.logger.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
+ %(ifaceobj.name, mtu, lowerobj[0].name, self.default_mtu))
+ retval = False
+ if self.max_mtu and mtu > self.max_mtu:
+ self.logger.warn('%s: specified mtu %s is greater than max mtu %s'
+ %(ifaceobj.name, mtu, self.max_mtu))
+ retval = False
+ return retval
+
+ def _propagate_mtu_to_upper_devs(self, ifaceobj, mtu, ifaceobj_getfunc):
+ if (not ifaceobj.upperifaces or
+ (ifaceobj.link_privflags & ifaceLinkPrivFlags.BOND_SLAVE) or
+ (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE) or
+ (ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT)):
+ return
+ for u in ifaceobj.upperifaces:
+ upperobjs = ifaceobj_getfunc(u)
+ if (not upperobjs or
+ not (upperobjs[0].link_kind & ifaceLinkKind.VLAN)):
+ continue
+ # only adjust mtu for vlan devices on ifaceobj
+ umtu = upperobjs[0].get_attr_value_first('mtu')
+ if not umtu:
+ running_mtu = self.ipcmd.link_get_mtu(upperobjs[0].name)
+ if not running_mtu or (running_mtu != mtu):
+ self.ipcmd.link_set(u, 'mtu', mtu)
+
+ def _process_mtu_config(self, ifaceobj, ifaceobj_getfunc, mtu):
+ if mtu:
+ if not self._check_mtu_config(ifaceobj, mtu, ifaceobj_getfunc):
+ return
+ cached_running_mtu = self.ipcmd.link_get_mtu(ifaceobj.name)
+ running_mtu = self.ipcmd.link_get_mtu_sysfs(ifaceobj.name)
+ if not running_mtu or (running_mtu and running_mtu != mtu):
+ force = cached_running_mtu != running_mtu
+ self.ipcmd.link_set(ifaceobj.name, 'mtu', mtu, force=force)
+ if (not ifupdownflags.flags.ALL and
+ not ifaceobj.link_kind and
+ ifupdownconfig.config.get('adjust_logical_dev_mtu', '1') != '0'):
+ # This is additional cost to us, so do it only when
+ # ifupdown2 is called on a particular interface and
+ # it is a physical interface
+ self._propagate_mtu_to_upper_devs(ifaceobj, mtu, ifaceobj_getfunc)
+ return
+
+ if ifaceobj.link_kind:
+ # bonds and vxlan devices need an explicit set of mtu.
+ # bridges don't need mtu set
+ if (ifaceobj.link_kind & ifaceLinkKind.BOND or
+ ifaceobj.link_kind & ifaceLinkKind.VXLAN):
+ running_mtu = self.ipcmd.link_get_mtu(ifaceobj.name)
+ if (self.default_mtu and running_mtu != self.default_mtu):
+ self.ipcmd.link_set(ifaceobj.name, 'mtu', self.default_mtu)
+ return
+ if (ifupdownconfig.config.get('adjust_logical_dev_mtu', '1') != '0'
+ and ifaceobj.lowerifaces):
+ # set vlan interface mtu to lower device mtu
+ if (ifaceobj.link_kind & ifaceLinkKind.VLAN):
+ lower_iface = ifaceobj.lowerifaces[0]
+ if lower_iface not in self.lower_iface_mtu_checked_list:
+ lower_iface_mtu = self.ipcmd.link_get_mtu_sysfs(lower_iface)
+ self.ipcmd.cache_update([lower_iface, 'mtu'], lower_iface_mtu)
+ self.lower_iface_mtu_checked_list.append(lower_iface)
+ else:
+ lower_iface_mtu = self.ipcmd.link_get_mtu(lower_iface)
+
+ if lower_iface_mtu != self.ipcmd.link_get_mtu_sysfs(ifaceobj.name):
+ self.ipcmd.link_set_mtu(ifaceobj.name, lower_iface_mtu)
+
+ elif (not (ifaceobj.name == 'lo') and not ifaceobj.link_kind and
+ not (ifaceobj.link_privflags & ifaceLinkPrivFlags.BOND_SLAVE) and
+ self.default_mtu):
+ # logical devices like bridges and vlan devices rely on mtu
+ # from their lower devices. ie mtu travels from
+ # lower devices to upper devices. For bonds mtu travels from
+ # upper to lower devices. running mtu depends on upper and
+ # lower device mtu. With all this implicit mtu
+ # config by the kernel in play, we try to be cautious here
+ # on which devices we want to reset mtu to default.
+ # essentially only physical interfaces which are not bond slaves
+ running_mtu = self.ipcmd.link_get_mtu(ifaceobj.name)
+ if running_mtu != self.default_mtu:
+ self.ipcmd.link_set(ifaceobj.name, 'mtu', self.default_mtu)
- def _up(self, ifaceobj):
+ def _set_bridge_forwarding(self, ifaceobj):
+ """ set ip forwarding to 0 if bridge interface does not have a
+ ip nor svi """
+ if not ifaceobj.upperifaces and not ifaceobj.get_attr_value('address'):
+ # set forwarding = 0
+ if self.sysctl_get('net.ipv4.conf.%s.forwarding' %ifaceobj.name) == '1':
+ self.sysctl_set('net.ipv4.conf.%s.forwarding' %ifaceobj.name, 0)
+ if self.sysctl_get('net.ipv6.conf.%s.forwarding' %ifaceobj.name) == '1':
+ self.sysctl_set('net.ipv6.conf.%s.forwarding' %ifaceobj.name, 0)
+ else:
+ if self.sysctl_get('net.ipv4.conf.%s.forwarding' %ifaceobj.name) == '0':
+ self.sysctl_set('net.ipv4.conf.%s.forwarding' %ifaceobj.name, 1)
+ if self.sysctl_get('net.ipv6.conf.%s.forwarding' %ifaceobj.name) == '0':
+ self.sysctl_set('net.ipv6.conf.%s.forwarding' %ifaceobj.name, 1)
+
+ def _sysctl_config(self, ifaceobj):
+ setting_default_value = False
+ mpls_enable = ifaceobj.get_attr_value_first('mpls-enable');
+ if not mpls_enable:
+ setting_default_value = True
+ mpls_enable = self.get_mod_subattr('mpls-enable', 'default')
+ mpls_enable = utils.boolean_support_binary(mpls_enable)
+ # File read has been used for better performance
+ # instead of using sysctl command
+ if ifupdownflags.flags.PERFMODE:
+ running_mpls_enable = '0'
+ else:
+ running_mpls_enable = self.read_file_oneline(
+ '/proc/sys/net/mpls/conf/%s/input'
+ % ifaceobj.name
+ )
+
+ if mpls_enable != running_mpls_enable:
+ try:
+ self.sysctl_set('net.mpls.conf.%s.input'
+ %('/'.join(ifaceobj.name.split("."))),
+ mpls_enable)
+ except Exception as e:
+ if not setting_default_value:
+ ifaceobj.status = ifaceStatus.ERROR
+ self.logger.error('%s: %s' %(ifaceobj.name, str(e)))
+
+ if (ifaceobj.link_kind & ifaceLinkKind.BRIDGE):
+ self._set_bridge_forwarding(ifaceobj)
+ return
+ if not self.syntax_check_sysctls(ifaceobj):
+ return
+ ipforward = ifaceobj.get_attr_value_first('ip-forward')
+ ip6forward = ifaceobj.get_attr_value_first('ip6-forward')
+ if ifupdownflags.flags.PERFMODE:
+ if ipforward:
+ self.sysctl_set('net.ipv4.conf.%s.forwarding'
+ %('/'.join(ifaceobj.name.split("."))),
+ utils.boolean_support_binary(ipforward))
+ if ip6forward:
+ self.sysctl_set('net.ipv6.conf.%s.forwarding'
+ %('/'.join(ifaceobj.name.split("."))),
+ utils.boolean_support_binary(ip6forward))
+ return
+ bridge_port = ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT
+ if bridge_port:
+ if ipforward:
+ self.log_error('%s: \'ip-forward\' is not supported for '
+ 'bridge port' %ifaceobj.name)
+ if ip6forward:
+ self.log_error('%s: \'ip6-forward\' is not supported for '
+ 'bridge port' %ifaceobj.name)
+ return
+ setting_default_value = False
+ if not ipforward:
+ setting_default_value = True
+ ipforward = (self.ipforward or
+ self.get_mod_subattr('ip-forward', 'default'))
+ ipforward = utils.boolean_support_binary(ipforward)
+ # File read has been used for better performance
+ # instead of using sysctl command
+ running_ipforward = self.read_file_oneline(
+ '/proc/sys/net/ipv4/conf/%s/forwarding'
+ %ifaceobj.name)
+ if ipforward != running_ipforward:
+ try:
+ self.sysctl_set('net.ipv4.conf.%s.forwarding'
+ %('/'.join(ifaceobj.name.split("."))),
+ ipforward)
+ except Exception as e:
+ if not setting_default_value:
+ ifaceobj.status = ifaceStatus.ERROR
+ self.logger.error('%s: %s' %(ifaceobj.name, str(e)))
+
+ setting_default_value = False
+ if not ip6forward:
+ setting_default_value = True
+ ip6forward = (self.ip6forward or
+ self.get_mod_subattr('ip6-forward', 'default'))
+ ip6forward = utils.boolean_support_binary(ip6forward)
+ # File read has been used for better performance
+ # instead of using sysctl command
+ running_ip6forward = self.read_file_oneline(
+ '/proc/sys/net/ipv6/conf/%s/forwarding'
+ %ifaceobj.name)
+ if ip6forward != running_ip6forward:
+ try:
+ self.sysctl_set('net.ipv6.conf.%s.forwarding'
+ %('/'.join(ifaceobj.name.split("."))),
+ ip6forward)
+ except Exception as e:
+ # There is chance of ipv6 being removed because of,
+ # for example, setting mtu < 1280
+ # In such cases, log error only if user has configured
+ # ip6-forward
+ if not setting_default_value:
+ ifaceobj.status = ifaceStatus.ERROR
+ self.logger.error('%s: %s' %(ifaceobj.name, str(e)))
+
+ def process_mtu(self, ifaceobj, ifaceobj_getfunc):
+ mtu = ifaceobj.get_attr_value_first('mtu')
+
+ if not mtu:
+ default_iface_mtu = self.ifaces_defaults.get(ifaceobj.name, {}).get('mtu')
+
+ if default_iface_mtu:
+ try:
+ mtu = default_iface_mtu
+ int(default_iface_mtu)
+ except Exception as e:
+ self.logger.warning('%s: MTU value from policy file: %s' % (ifaceobj.name, str(e)))
+ return
+
+ self._process_mtu_config(ifaceobj, ifaceobj_getfunc, mtu)
+
+ def up_ipv6_addrgen(self, ifaceobj):
+ user_configured_ipv6_addrgen = ifaceobj.get_attr_value_first('ipv6-addrgen')
+
+ if not user_configured_ipv6_addrgen and ifupdownflags.flags.PERFMODE:
+ # no need to go further during perfmode (boot)
+ return
+
+ if not user_configured_ipv6_addrgen:
+ # if user didn't configure ipv6-addrgen, should we reset to default?
+ user_configured_ipv6_addrgen = self.get_attr_default_value('ipv6-addrgen')
+
+ ipv6_addrgen_nl = {
+ 'on': 0,
+ 'yes': 0,
+ '0': 0,
+ 'off': 1,
+ 'no': 1,
+ '1': 1
+ }.get(user_configured_ipv6_addrgen.lower(), None)
+
+ if ipv6_addrgen_nl is not None:
+ self.ipcmd.ipv6_addrgen(ifaceobj.name, ipv6_addrgen_nl, link_created=True)
+ # link_create=False will flush the addr cache of that intf
+ else:
+ self.logger.warning('%s: invalid value "%s" for attribute ipv6-addrgen' % (ifaceobj.name, user_configured_ipv6_addrgen))
+
+ def _up(self, ifaceobj, ifaceobj_getfunc=None):
if not self.ipcmd.link_exists(ifaceobj.name):
return
+
+ if not self.syntax_check_enable_l3_iface_forwardings(ifaceobj, ifaceobj_getfunc):
+ return
+
+ alias = ifaceobj.get_attr_value_first('alias')
+ current_alias = self.ipcmd.link_get_alias(ifaceobj.name)
+ if alias and alias != current_alias:
+ self.ipcmd.link_set_alias(ifaceobj.name, alias)
+ elif not alias and current_alias:
+ self.ipcmd.link_set_alias(ifaceobj.name, '')
+
+ self._sysctl_config(ifaceobj)
+
addr_method = ifaceobj.addr_method
+ force_reapply = False
try:
# release any stale dhcp addresses if present
- if (addr_method != "dhcp" and not self.PERFMODE and
+ if (addr_method not in ["dhcp", "ppp"] and not ifupdownflags.flags.PERFMODE and
not (ifaceobj.flags & iface.HAS_SIBLINGS)):
# if not running in perf mode and ifaceobj does not have
# any sibling iface objects, kill any stale dhclient
# processes
dhclientcmd = dhclient()
- if dhclient.is_running(ifaceobj.name):
+ if dhclientcmd.is_running(ifaceobj.name):
# release any dhcp leases
dhclientcmd.release(ifaceobj.name)
- elif dhclient.is_running6(ifaceobj.name):
+ force_reapply = True
+ elif dhclientcmd.is_running6(ifaceobj.name):
dhclientcmd.release6(ifaceobj.name)
+ force_reapply = True
except:
pass
self.ipcmd.batch_start()
- if addr_method != "dhcp":
- self._inet_address_config(ifaceobj)
- mtu = ifaceobj.get_attr_value_first('mtu')
- if mtu:
- self.ipcmd.link_set(ifaceobj.name, 'mtu', mtu)
- alias = ifaceobj.get_attr_value_first('alias')
- if alias:
- self.ipcmd.link_set_alias(ifaceobj.name, alias)
- hwaddress = ifaceobj.get_attr_value_first('hwaddress')
- if hwaddress:
- self.ipcmd.link_set(ifaceobj.name, 'address', hwaddress)
- self.ipcmd.batch_commit()
+ self.up_ipv6_addrgen(ifaceobj)
+
+ if addr_method not in ["dhcp", "ppp"]:
+ self._inet_address_config(ifaceobj, ifaceobj_getfunc,
+ force_reapply)
+
+ self.process_mtu(ifaceobj, ifaceobj_getfunc)
+
+ try:
+ self.ipcmd.batch_commit()
+ except Exception as e:
+ self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj, raise_error=False)
try:
+ hwaddress = self._get_hwaddress(ifaceobj)
+ if hwaddress:
+ running_hwaddress = None
+ if not ifupdownflags.flags.PERFMODE: # system is clean
+ running_hwaddress = self.ipcmd.link_get_hwaddress(ifaceobj.name)
+ if hwaddress != running_hwaddress:
+ slave_down = False
+ netlink.link_set_updown(ifaceobj.name, "down")
+ if ifaceobj.link_kind & ifaceLinkKind.BOND:
+ # if bond, down all the slaves
+ if ifaceobj.lowerifaces:
+ for l in ifaceobj.lowerifaces:
+ netlink.link_set_updown(l, "down")
+ slave_down = True
+ try:
+ self.ipcmd.link_set(ifaceobj.name, 'address', hwaddress)
+ finally:
+ netlink.link_set_updown(ifaceobj.name, "up")
+ if slave_down:
+ for l in ifaceobj.lowerifaces:
+ netlink.link_set_updown(l, "up")
+
# Handle special things on a bridge
self._process_bridge(ifaceobj, True)
except Exception, e:
- self.log_warn('%s: %s' %(ifaceobj.name, str(e)))
- pass
+ self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
- if addr_method != "dhcp":
- self.ipcmd.route_add_gateway(ifaceobj.name,
- ifaceobj.get_attr_value_first('gateway'))
+ gateways = ifaceobj.get_attr_value('gateway')
+ if not gateways:
+ gateways = []
+ prev_gw = self._get_prev_gateway(ifaceobj, gateways)
+ self._add_delete_gateway(ifaceobj, gateways, prev_gw)
- def _down(self, ifaceobj):
+ def _down(self, ifaceobj, ifaceobj_getfunc=None):
try:
if not self.ipcmd.link_exists(ifaceobj.name):
return
addr_method = ifaceobj.addr_method
- if addr_method != "dhcp":
- self.ipcmd.route_del_gateway(ifaceobj.name,
- ifaceobj.get_attr_value_first('gateway'),
- ifaceobj.get_attr_value_first('metric'))
- self.ipcmd.del_addr_all(ifaceobj.name)
+ if addr_method not in ["dhcp", "ppp"]:
+ if ifaceobj.get_attr_value_first('address-purge')=='no':
+ addrlist = ifaceobj.get_attr_value('address')
+ for addr in addrlist:
+ self.ipcmd.addr_del(ifaceobj.name, addr)
+ #self.ipcmd.addr_del(ifaceobj.name, ifaceobj.get_attr_value('address')[0])
+ elif not ifaceobj.link_kind:
+ # for logical interfaces we don't need to remove the ip addresses
+ # kernel will do it for us on 'ip link del'
+ self.ipcmd.del_addr_all(ifaceobj.name)
+ gateways = ifaceobj.get_attr_value('gateway')
+ if gateways:
+ self._delete_gateway(ifaceobj, gateways,
+ ifaceobj.get_attr_value_first('vrf'),
+ ifaceobj.get_attr_value_first('metric'))
+ mtu = ifaceobj.get_attr_value_first('mtu')
+ if (not ifaceobj.link_kind and mtu and
+ self.default_mtu and (mtu != self.default_mtu)):
+ self.ipcmd.link_set(ifaceobj.name, 'mtu', self.default_mtu)
alias = ifaceobj.get_attr_value_first('alias')
if alias:
- self.ipcmd.link_set(ifaceobj.name, 'alias', "\'\'")
+ self.write_file('/sys/class/net/%s/ifalias' % ifaceobj.name, '\n')
# XXX hwaddress reset cannot happen because we dont know last
# address.
def _check_addresses_in_bridge(self, ifaceobj, hwaddress):
""" If the device is a bridge, make sure the addresses
are in the bridge """
- if '.' in ifaceobj.name:
- (bridgename, vlan) = ifaceobj.name.split('.')
+ if ifaceobj.link_kind & ifaceLinkKind.VLAN:
+ bridgename = ifaceobj.lowerifaces[0]
+ vlan = self._get_vlan_id(ifaceobj)
if self.ipcmd.bridge_is_vlan_aware(bridgename):
- fdb_addrs = self._get_bridge_fdbs(bridgename, vlan)
+ fdb_addrs = self._get_bridge_fdbs(bridgename, str(vlan))
if not fdb_addrs or hwaddress not in fdb_addrs:
return False
return True
- def _query_check(self, ifaceobj, ifaceobjcurr):
+ def _query_sysctl(self, ifaceobj, ifaceobjcurr):
+ bridge_port = ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT
+ ipforward = ifaceobj.get_attr_value_first('ip-forward')
+ if ipforward:
+ if bridge_port:
+ ifaceobjcurr.status = ifaceStatus.ERROR
+ ifaceobjcurr.status_str = ('\'ip-forward\' not supported ' +
+ 'for bridge port')
+ ifaceobjcurr.update_config_with_status('ip-forward', 1, None)
+ else:
+ running_ipforward = self.read_file_oneline(
+ '/proc/sys/net/ipv4/conf/%s/forwarding'
+ %ifaceobj.name)
+ running_ipforward = utils.get_boolean_from_string(running_ipforward)
+ config_ipforward = utils.get_boolean_from_string(ipforward)
+ ifaceobjcurr.update_config_with_status(
+ 'ip-forward',
+ 'on' if running_ipforward else 'off',
+ running_ipforward != config_ipforward
+ )
+
+ ip6forward = ifaceobj.get_attr_value_first('ip6-forward')
+ if ip6forward:
+ if bridge_port:
+ ifaceobjcurr.status = ifaceStatus.ERROR
+ ifaceobjcurr.status_str = ('\'ip6-forward\' not supported ' +
+ 'for bridge port')
+ ifaceobjcurr.update_config_with_status('ip6-forward', 1, None)
+ else:
+ running_ip6forward = self.read_file_oneline(
+ '/proc/sys/net/ipv6/conf/%s/forwarding'
+ %ifaceobj.name)
+ running_ip6forward = utils.get_boolean_from_string(running_ip6forward)
+ config_ip6forward = utils.get_boolean_from_string(ip6forward)
+ ifaceobjcurr.update_config_with_status(
+ 'ip6-forward',
+ 'on' if running_ip6forward else 'off',
+ running_ip6forward != config_ip6forward
+ )
+ mpls_enable = ifaceobj.get_attr_value_first('mpls-enable');
+ if mpls_enable:
+ running_mpls_enable = self.read_file_oneline(
+ '/proc/sys/net/mpls/conf/%s/input'
+ %ifaceobj.name)
+ running_mpls_enable = utils.get_yesno_from_onezero(
+ running_mpls_enable)
+ ifaceobjcurr.update_config_with_status('mpls-enable',
+ running_mpls_enable,
+ mpls_enable != running_mpls_enable)
+ return
+
+ def query_check_ipv6_addrgen(self, ifaceobj, ifaceobjcurr):
+ ipv6_addrgen = ifaceobj.get_attr_value_first('ipv6-addrgen')
+
+ if not ipv6_addrgen:
+ return
+
+ if ipv6_addrgen in utils._string_values:
+ ifaceobjcurr.update_config_with_status(
+ 'ipv6-addrgen',
+ ipv6_addrgen,
+ utils.get_boolean_from_string(ipv6_addrgen) == self.ipcmd.get_ipv6_addrgen_mode(ifaceobj.name)
+ )
+ else:
+ ifaceobjcurr.update_config_with_status('ipv6-addrgen', ipv6_addrgen, 1)
+
+ def _query_check(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc=None):
runningaddrsdict = None
if not self.ipcmd.link_exists(ifaceobj.name):
self.logger.debug('iface %s not found' %ifaceobj.name)
return
+
+ self.query_check_ipv6_addrgen(ifaceobj, ifaceobjcurr)
+
addr_method = ifaceobj.addr_method
self.query_n_update_ifaceobjcurr_attr(ifaceobj, ifaceobjcurr,
'mtu', self.ipcmd.link_get_mtu)
- hwaddress = ifaceobj.get_attr_value_first('hwaddress')
+ hwaddress = self._get_hwaddress(ifaceobj)
if hwaddress:
rhwaddress = self.ipcmd.link_get_hwaddress(ifaceobj.name)
if not rhwaddress or rhwaddress != hwaddress:
0)
self.query_n_update_ifaceobjcurr_attr(ifaceobj, ifaceobjcurr,
'alias', self.ipcmd.link_get_alias)
+ self._query_sysctl(ifaceobj, ifaceobjcurr)
# compare addresses
- if addr_method == 'dhcp':
+ if addr_method in ["dhcp", "ppp"]:
return
- addrs = self._get_iface_addresses(ifaceobj)
- runningaddrsdict = self.ipcmd.addr_get(ifaceobj.name)
+ addrs = utils.get_normalized_ip_addr(ifaceobj.name,
+ self._get_iface_addresses(ifaceobj))
+ runningaddrsdict = self.ipcmd.get_running_addrs(ifaceobj)
+ # if anycast address is configured on 'lo' and is in running config
+ # add it to addrs so that query_check doesn't fail
+ anycast_addr = utils.get_normalized_ip_addr(ifaceobj.name, ifaceobj.get_attr_value_first('clagd-vxlan-anycast-ip'))
+ if anycast_addr:
+ anycast_addr = anycast_addr+'/32'
+ if runningaddrsdict and anycast_addr and runningaddrsdict.get(anycast_addr):
+ addrs.append(anycast_addr)
# Set ifaceobjcurr method and family
ifaceobjcurr.addr_method = ifaceobj.addr_method
if not runningaddrsdict and not addrs:
return
runningaddrs = runningaddrsdict.keys() if runningaddrsdict else []
+ # Add /32 netmask to configured address without netmask.
+ # This may happen on interfaces where pointopoint is used.
+ runningaddrs = [ addr if '/' in addr else addr + '/32' for addr in runningaddrs]
if runningaddrs != addrs:
runningaddrsset = set(runningaddrs) if runningaddrs else set([])
addrsset = set(addrs) if addrs else set([])
#XXXX Check broadcast address, scope, etc
return
- def _query_running(self, ifaceobjrunning):
+ def query_running_ipv6_addrgen(self, ifaceobjrunning):
+ ipv6_addrgen = self.ipcmd.get_ipv6_addrgen_mode(ifaceobjrunning.name)
+
+ if ipv6_addrgen:
+ ifaceobjrunning.update_config('ipv6-addrgen', 'off')
+
+ def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
if not self.ipcmd.link_exists(ifaceobjrunning.name):
self.logger.debug('iface %s not found' %ifaceobjrunning.name)
return
+
+ self.query_running_ipv6_addrgen(ifaceobjrunning)
+
dhclientcmd = dhclient()
if (dhclientcmd.is_running(ifaceobjrunning.name) or
dhclientcmd.is_running6(ifaceobjrunning.name)):
# If dhcp is configured on the interface, we skip it
- return
+ return
isloopback = self.ipcmd.link_isloopback(ifaceobjrunning.name)
if isloopback:
default_addrs = ['127.0.0.1/8', '::1/128']
- ifaceobjrunning.addr_family = 'inet'
+ ifaceobjrunning.addr_family.append('inet')
ifaceobjrunning.addr_method = 'loopback'
else:
default_addrs = []
- runningaddrsdict = self.ipcmd.addr_get(ifaceobjrunning.name)
+ runningaddrsdict = self.ipcmd.get_running_addrs(ifaceobjrunning)
if runningaddrsdict:
[ifaceobjrunning.update_config('address', addr)
for addr, addrattrs in runningaddrsdict.items()
mtu != self.get_mod_subattr('mtu', 'default'))):
ifaceobjrunning.update_config('mtu', mtu)
alias = self.ipcmd.link_get_alias(ifaceobjrunning.name)
- if alias:
+ if alias:
ifaceobjrunning.update_config('alias', alias)
+ ipforward = self.read_file_oneline(
+ '/proc/sys/net/ipv4/conf/%s/forwarding'
+ %ifaceobjrunning.name)
+
+
_run_ops = {'up' : _up,
'down' : _down,
'query-checkcurr' : _query_check,
def _init_command_handlers(self):
if not self.ipcmd:
- self.ipcmd = iproute2(**self.get_flags())
+ self.ipcmd = LinkUtils()
- def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
+ def run(self, ifaceobj, operation, query_ifaceobj=None, ifaceobj_getfunc=None):
""" run address configuration on the interface object passed as argument
Args:
return
self._init_command_handlers()
if operation == 'query-checkcurr':
- op_handler(self, ifaceobj, query_ifaceobj)
+ op_handler(self, ifaceobj, query_ifaceobj,
+ ifaceobj_getfunc=ifaceobj_getfunc)
else:
- op_handler(self, ifaceobj)
+ op_handler(self, ifaceobj,
+ ifaceobj_getfunc=ifaceobj_getfunc)