From 02e00f54bbf9d0ca647c1ed2c39f7af28b6653b7 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 4 Jan 2017 14:52:09 -0800 Subject: [PATCH] ifupdown: add new 'down [yes|no]' link attribute to keep link down Ticket: CM-13434 Reviewed by: julien, nikhil, daniel Testing Done: ifreload and multiple down [yes|no] sequences under physical and logical interfaces (ifupdown2-tests test case is pending) This also moves the fix done for CM-4125 (inet manual handling for logical devices) into a single place under ifupdownmain. attribute 'down [yes|no]' will not work in all cases when 'inet manual' is used. This is only to preserve the semantics of 'inet manual'. Best use of 'down [yes|no]' is to use it without 'inet manual'.. they are conflicting features anyways. Signed-off-by: Roopa Prabhu --- addons/address.py | 4 ++++ addons/bond.py | 2 -- addons/bridge.py | 6 ------ addons/vlan.py | 5 ----- addons/vxlan.py | 3 --- ifupdown/iface.py | 1 + ifupdown/ifupdownmain.py | 24 ++++++++++++++++++++---- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/addons/address.py b/addons/address.py index fc9fa89..13f73f1 100644 --- a/addons/address.py +++ b/addons/address.py @@ -98,6 +98,10 @@ class address(moduleBase): if self.max_mtu: self.logger.info('address: using max mtu %s' %self.max_mtu) + def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None): + if ifaceobj.get_attr_value_first('down') == 'yes': + ifaceobj.link_privflags |= ifaceLinkPrivFlags.KEEP_LINK_DOWN + def syntax_check(self, ifaceobj, ifaceobj_getfunc=None): return (self.syntax_check_multiple_gateway(ifaceobj) and self.syntax_check_addr_allowed_on(ifaceobj, True) diff --git a/addons/bond.py b/addons/bond.py index 401ec04..829fbd5 100644 --- a/addons/bond.py +++ b/addons/bond.py @@ -304,8 +304,6 @@ class bond(moduleBase): self.bondcmd.create_bond(ifaceobj.name) self._apply_master_settings(ifaceobj) self._add_slaves(ifaceobj) - if ifaceobj.addr_method == 'manual': - netlink.link_set_updown(ifaceobj.name, "up") except Exception, e: self.log_error(str(e), ifaceobj) diff --git a/addons/bridge.py b/addons/bridge.py index 564bf83..b9b598c 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -1289,12 +1289,6 @@ class bridge(moduleBase): self.logger.debug('%s: %s: link set up (%s)' %(ifaceobj.name, p, str(e))) pass - - if ifaceobj.addr_method == 'manual': - try: - netlink.link_set_updown(ifaceobj.name, "up") - except Exception as e: - self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj) if err: raise Exception(errstr) diff --git a/addons/vlan.py b/addons/vlan.py index ad6dfaf..0bdab46 100644 --- a/addons/vlan.py +++ b/addons/vlan.py @@ -141,11 +141,6 @@ class vlan(moduleBase): return netlink.link_add_vlan(vlanrawdevice, ifaceobj.name, vlanid) self._bridge_vid_add_del(ifaceobj, vlanrawdevice, vlanid) - if ifaceobj.addr_method == 'manual': - try: - netlink.link_set_updown(ifaceobj.name, "up") - except Exception as e: - self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj) def _down(self, ifaceobj): vlanid = self._get_vlan_id(ifaceobj) diff --git a/addons/vxlan.py b/addons/vxlan.py index df51843..8bdcd9f 100644 --- a/addons/vxlan.py +++ b/addons/vxlan.py @@ -123,9 +123,6 @@ class vxlan(moduleBase): except: pass - if ifaceobj.addr_method == 'manual': - netlink.link_set_updown(ifaceobj.name, "up") - def _up(self, ifaceobj): self._vxlan_create(ifaceobj) diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 98a3c89..d883dbc 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -64,6 +64,7 @@ class ifaceLinkPrivFlags(): BRIDGE_VXLAN = 0x10000 ADDRESS_VIRTUAL_SLAVE = 0x100000 LOOPBACK = 0x1000000 + KEEP_LINK_DOWN = 0x10000000 @classmethod def get_str(cls, flag): diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index cb0389b..809950c 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -115,8 +115,10 @@ class ifupdownMain(ifupdownBase): if ((ifaceobj.link_kind & ifaceLinkKind.VRF) or (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)): return - if (ifaceobj.addr_method and - ifaceobj.addr_method == 'manual'): + # if not a logical interface and addr method is manual, + # ignore link admin state changes + if (ifaceobj.addr_method == 'manual' and + not ifaceobj.link_kind): return if self._delay_admin_state: self._delay_admin_state_iface_queue.append(ifaceobj.name) @@ -129,6 +131,12 @@ class ifupdownMain(ifupdownBase): return if not self.link_exists(ifaceobj.name): return + if ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN: + # user has asked to explicitly keep the link down, + # so, force link down + self.logger.info('%s: keeping link down due to user config' %ifaceobj.name) + self.link_down(ifaceobj.name) + return self.link_up(ifaceobj.name) def run_down(self, ifaceobj): @@ -139,8 +147,10 @@ class ifupdownMain(ifupdownBase): # there is no real interface behind it if ifaceobj.type == ifaceType.BRIDGE_VLAN: return - if (ifaceobj.addr_method and - ifaceobj.addr_method == 'manual'): + # if not a logical interface and addr method is manual, + # ignore link admin state changes + if (ifaceobj.addr_method == 'manual' and + not ifaceobj.link_lind): return if self._delay_admin_state: self._delay_admin_state_iface_queue.append(ifaceobj.name) @@ -468,6 +478,12 @@ class ifupdownMain(ifupdownBase): def _set_iface_role_n_kind(self, ifaceobj, upperifaceobj): + # If addr_method is set and link is not a logical interface, + # set flag KEEP_LINK_DOWN. addr_method == 'manual' only applies to + # logical interfaces. + if (ifaceobj.addr_method == 'manual' and not ifaceobj.link_kind): + ifaceobj.link_privflags |= ifaceLinkPrivFlags.KEEP_LINK_DOWN + if (upperifaceobj.link_kind & ifaceLinkKind.BOND): self._set_iface_role(ifaceobj, ifaceRole.SLAVE, upperifaceobj) ifaceobj.link_privflags |= ifaceLinkPrivFlags.BOND_SLAVE