From 22b49c2810243723e6646c044c84595705dc9374 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Tue, 22 Nov 2016 17:06:16 +0100 Subject: [PATCH] addons: warn or ignore if IP address is assigned to an enslaved interface Ticket: CM-11967 Reviewed By: Roopa, Daniel W, Nikhil G Testing Done: ifupdown2-tests Signed-off-by: Julien Fortin --- addons/address.py | 22 ++++++++++++---------- addons/dhcp.py | 10 ++++++++++ ifupdown/utils.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/addons/address.py b/addons/address.py index c7cb5f0..2bce58f 100644 --- a/addons/address.py +++ b/addons/address.py @@ -98,6 +98,15 @@ class address(moduleBase): if self.max_mtu: self.logger.info('address: using max mtu %s' %self.max_mtu) + def syntax_check(self, ifaceobj, ifaceobj_func=None): + return (self.syntax_check_multiple_gateway(ifaceobj) + and self.syntax_check_addr_allowed_on(ifaceobj, 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: @@ -106,7 +115,7 @@ class address(moduleBase): return True return False - def syntax_check(self, ifaceobj, ifaceobj_func=None): + def syntax_check_multiple_gateway(self, ifaceobj): result = True inet = False inet6 = False @@ -179,15 +188,8 @@ class address(moduleBase): if not addrs: continue - if (((ifaceobj.role & ifaceRole.SLAVE) and - not (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)) or - ((ifaceobj.link_kind & ifaceLinkKind.BRIDGE) and - (ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE))): - # we must not configure an IP address if the interface is - # enslaved or is a VLAN AWARE BRIDGE - self.logger.info('%s: ignoring ip address. Interface is ' - 'enslaved or a vlan aware bridge and cannot' - ' have an IP Address' %(ifaceobj.name)) + 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)): diff --git a/addons/dhcp.py b/addons/dhcp.py index 12c68cc..f8852e3 100644 --- a/addons/dhcp.py +++ b/addons/dhcp.py @@ -27,6 +27,14 @@ class dhcp(moduleBase): self.dhclientcmd = dhclient(**kargs) self.ipcmd = None + def syntax_check(self, ifaceobj, ifaceobj_getfunc): + return self.is_dhcp_allowed_on(ifaceobj, syntax_check=True) + + def is_dhcp_allowed_on(self, ifaceobj, syntax_check): + if ifaceobj.addr_method and 'dhcp' in ifaceobj.addr_method: + return utils.is_addr_ip_allowed_on(ifaceobj, syntax_check=True) + return True + def _up(self, ifaceobj): # if dhclient is already running do not stop and start it if self.dhclientcmd.is_running(ifaceobj.name) or \ @@ -162,6 +170,8 @@ class dhcp(moduleBase): return except: return + if not self.is_dhcp_allowed_on(ifaceobj, syntax_check=False): + return self._init_command_handlers() if operation == 'query-checkcurr': op_handler(self, ifaceobj, query_ifaceobj) diff --git a/ifupdown/utils.py b/ifupdown/utils.py index a9063b3..82eafa1 100644 --- a/ifupdown/utils.py +++ b/ifupdown/utils.py @@ -19,6 +19,8 @@ import ifupdownflags from functools import partial from ipaddr import IPNetwork, IPAddress +from ifupdown.iface import * + def signal_handler_f(ps, sig, frame): if ps: ps.send_signal(sig) @@ -210,6 +212,33 @@ class utils(): cls.logger.warning('%s: %s' % (ifacename, e)) return ipaddrs + @classmethod + def is_addr_ip_allowed_on(cls, ifaceobj, syntax_check=False): + msg = ('%s: ignoring ip address. Assigning an IP ' + 'address is not allowed on' % ifaceobj.name) + if (ifaceobj.role & ifaceRole.SLAVE + and not (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)): + up = None + if ifaceobj.upperifaces: + up = ifaceobj.upperifaces[0] + msg = ('%s enslaved interfaces. %s' + % (msg, ('%s is enslaved to %s' + % (ifaceobj.name, up)) if up else '')).strip() + if syntax_check: + cls.logger.warning(msg) + else: + cls.logger.info(msg) + return False + elif (ifaceobj.link_kind & ifaceLinkKind.BRIDGE + and ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE): + msg = '%s bridge vlan aware interfaces' + if syntax_check: + cls.logger.warning(msg) + else: + cls.logger.info(msg) + return False + return True + @classmethod def _execute_subprocess(cls, cmd, env=None,