'dual connected VxLANs',
'validvals' : ['<ipv4>', ],
'example' : ['clagd-vxlan-anycast-ip 36.0.0.11']},
+ 'arp-accept' :
+ { 'help': 'Allow gratuitous arp to update arp table',
+ 'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
+ 'default' : 'off',
+ 'example' : ['arp-accept on']},
'ip-forward' :
{ 'help': 'ip forwarding flag',
'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
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
+ )
+
+ self.l3_intf_default_gateway_set_onlink = utils.get_boolean_from_string(
+ policymanager.policymanager_api.get_module_globals(
+ module_name=self.__class__.__name__,
+ attr='l3_intf_default_gateway_set_onlink'
+ ),
+ default=True
+ )
+
def syntax_check(self, ifaceobj, ifaceobj_getfunc=None):
return (self.syntax_check_multiple_gateway(ifaceobj)
and self.syntax_check_addr_allowed_on(ifaceobj, True)
def _process_bridge(self, ifaceobj, up):
hwaddress = self._get_hwaddress(ifaceobj)
addrs = ifaceobj.get_attr_value_first('address')
+ arp_accept = ifaceobj.get_attr_value_first('arp-accept')
+ arp_accept = utils.boolean_support_binary(arp_accept)
is_vlan_dev_on_vlan_aware_bridge = False
is_bridge = self.ipcmd.is_bridge(ifaceobj.name)
if not is_bridge:
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, arp_accept)
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)
+ if up:
+ # check statemanager to delete the old entry if necessary
+ try:
+ for old_obj in statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) or []:
+ old_hwaddress = old_obj.get_attr_value_first("hwaddress")
+ if old_hwaddress and self.ipcmd.mac_str_to_int(old_hwaddress) != self.ipcmd.mac_str_to_int(hwaddress):
+ self.ipcmd.bridge_fdb_del(bridgename, old_hwaddress, vlan)
+ break
+ except:
+ pass
+ self.ipcmd.bridge_fdb_add(bridgename, hwaddress, vlan)
+ else:
+ self.ipcmd.bridge_fdb_del(bridgename, hwaddress, vlan)
def _get_anycast_addr(self, ifaceobjlist):
for ifaceobj in ifaceobjlist:
vrf, metric)
for add_gw in gateways:
try:
- self.ipcmd.route_add_gateway(ifaceobj.name, add_gw, vrf, metric)
+ self.ipcmd.route_add_gateway(ifaceobj.name, add_gw, vrf, metric, onlink=self.l3_intf_default_gateway_set_onlink)
except Exception as e:
self.log_error('%s: %s' % (ifaceobj.name, str(e)))
return
if ifaceobj.link_kind:
- # bonds and vxlan devices need an explicit set of mtu.
+ # bonds, vxlan and custom devices (like dummy) need an explicit set of mtu.
# bridges don't need mtu set
if (ifaceobj.link_kind & ifaceLinkKind.BOND or
- ifaceobj.link_kind & ifaceLinkKind.VXLAN):
+ ifaceobj.link_kind & ifaceLinkKind.VXLAN or
+ ifaceobj.link_kind & ifaceLinkKind.OTHER
+ ):
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)
def _set_bridge_forwarding(self, ifaceobj):
""" set ip forwarding to 0 if bridge interface does not have a
ip nor svi """
+ ifname = ifaceobj.name
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)
+ if self.sysctl_get_forwarding_value_from_proc(ifname, "ipv4") == '1':
+ self.sysctl_write_forwarding_value_to_proc(ifname, "ipv4", 0)
+ if self.sysctl_get_forwarding_value_from_proc(ifname, "ipv6") == '1':
+ self.sysctl_write_forwarding_value_to_proc(ifname, "ipv6", 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)
+ if self.sysctl_get_forwarding_value_from_proc(ifname, "ipv4") == '0':
+ self.sysctl_write_forwarding_value_to_proc(ifname, "ipv4", 1)
+ if self.sysctl_get_forwarding_value_from_proc(ifname, "ipv6") == '0':
+ self.sysctl_write_forwarding_value_to_proc(ifname, "ipv6", 1)
+
+ def sysctl_get_forwarding_value_from_proc(self, ifname, family):
+ return self.read_file_oneline("/proc/sys/net/%s/conf/%s/forwarding" % (family, ifname))
+
+ def sysctl_write_forwarding_value_to_proc(self, ifname, family, value):
+ self.write_file("/proc/sys/net/%s/conf/%s/forwarding" % (family, ifname), "%s\n" % value)
def _sysctl_config(self, ifaceobj):
setting_default_value = False
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)))
+ ipforward = self.ipforward
+
+ if ipforward:
+ 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)))
+ ip6forward = self.ip6forward
+
+ if ip6forward:
+ 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')
def up_ipv6_addrgen(self, ifaceobj):
user_configured_ipv6_addrgen = ifaceobj.get_attr_value_first('ipv6-addrgen')
- if not user_configured_ipv6_addrgen:
- for old_ifaceobj in statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) or []:
- old_config_ipv6_addrgen = old_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 old_config_ipv6_addrgen:
- user_configured_ipv6_addrgen = self.get_attr_default_value('ipv6-addrgen')
- break
+ if not user_configured_ipv6_addrgen and ifaceobj.addr_method == 'dhcp':
+ return
- if not user_configured_ipv6_addrgen:
- # no previous config detected we dont have to configure ipv6-addrgen
- 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,
if addr_method not in ["dhcp", "ppp"]:
self._inet_address_config(ifaceobj, ifaceobj_getfunc,
force_reapply)
+ else:
+ # remove old addresses added by ifupdown2
+ # (if intf was moved from static config to dhcp)
+ for old_ifaceobj in statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) or []:
+ for addr in old_ifaceobj.get_attr_value("address") or []:
+ self.ipcmd.addr_del(ifaceobj.name, addr)
self.process_mtu(ifaceobj, ifaceobj_getfunc)
except Exception as e:
self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj, raise_error=False)
+ self.up_hwaddress(ifaceobj)
+
+ 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 up_hwaddress(self, ifaceobj):
try:
hwaddress = self._get_hwaddress(ifaceobj)
+
if hwaddress:
- running_hwaddress = None
- if not ifupdownflags.flags.PERFMODE: # system is clean
+ if not ifupdownflags.flags.PERFMODE: # system is clean
running_hwaddress = self.ipcmd.link_get_hwaddress(ifaceobj.name)
- if hwaddress != running_hwaddress:
+ else:
+ running_hwaddress = None
+
+ if self.ipcmd.mac_str_to_int(running_hwaddress) != self.ipcmd.mac_str_to_int(hwaddress):
slave_down = False
netlink.link_set_updown(ifaceobj.name, "down")
if ifaceobj.link_kind & ifaceLinkKind.BOND:
netlink.link_set_updown(l, "down")
slave_down = True
try:
- self.ipcmd.link_set(ifaceobj.name, 'address', hwaddress)
+ self.ipcmd.link_set_hwaddress(ifaceobj.name, hwaddress, force=True)
finally:
netlink.link_set_updown(ifaceobj.name, "up")
if slave_down:
# Handle special things on a bridge
self._process_bridge(ifaceobj, True)
except Exception, e:
- self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
-
- 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)
+ self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
def _down(self, ifaceobj, ifaceobj_getfunc=None):
try:
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, str(vlan))
- if not fdb_addrs or hwaddress not in fdb_addrs:
- return False
+ fdb_addrs = [self.ipcmd.mac_str_to_int(fdb_addr) for fdb_addr in self._get_bridge_fdbs(bridgename, str(vlan))]
+ if not fdb_addrs:
+ return False
+ hwaddress_int = self.ipcmd.mac_str_to_int(hwaddress)
+ if hwaddress_int not in fdb_addrs:
+ return False
return True
def _query_sysctl(self, ifaceobj, ifaceobjcurr):
hwaddress = self._get_hwaddress(ifaceobj)
if hwaddress:
rhwaddress = self.ipcmd.link_get_hwaddress(ifaceobj.name)
- if not rhwaddress or rhwaddress != hwaddress:
+ if not rhwaddress or self.ipcmd.mac_str_to_int(rhwaddress) != self.ipcmd.mac_str_to_int(hwaddress):
ifaceobjcurr.update_config_with_status('hwaddress', rhwaddress,
1)
elif not self._check_addresses_in_bridge(ifaceobj, hwaddress):