1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

This patch moves bond slave link ownership to the bond module and makes

sure that slaves can never be brought admin up on their own when they
are not in the bond

Ticket: CM-4408
Reviewed By: CCR-2323
Testing Done: Tested ifup/ifdown of bond slaves and bond interface

This patch introduces:
- introduces 2 interface flags, LINK_MASTER and LINK_SLAVE.
- The bond module will set LINK_MASTER on the bond iface object
indicating that the bond module owns the link.
- Which means that all lower devices /slaves of the bond get their
link when the bond (aka LINK_MASTER) is processed in the bond module
- The module that queries dependencies propagates the LINK_SLAVE flags
on the dependents of LINK_MASTER.
- The scheduler now acts on the LINK_SLAVE flag. If LINK_SLAVE is set,
it skips setting admin 'up' on that interface. It also makes sure the
interface is not already in the bond.
    ie if an interface is a LINK_SLAVE (bond slave in this case), admin
up will not be executed when the interface is not inside the bond.
(cherry picked from commit 84b5a07a4f7685c7ae2eac5892889d6c0e08b2eb)
This commit is contained in:
Roopa Prabhu
2014-12-08 17:15:57 -08:00
parent 971c9b35c0
commit b48ff1a983
3 changed files with 40 additions and 43 deletions

View File

@ -105,6 +105,7 @@ class ifenslave(moduleBase):
# Also save a copy for future use # Also save a copy for future use
ifaceobj.priv_data = list(slave_list) ifaceobj.priv_data = list(slave_list)
ifaceobj.flags |= iface.LINK_MASTER
return slave_list return slave_list
def get_dependent_ifacenames_running(self, ifaceobj): def get_dependent_ifacenames_running(self, ifaceobj):
@ -200,9 +201,8 @@ class ifenslave(moduleBase):
self.log_warn('%s: skipping slave %s, does not exist' self.log_warn('%s: skipping slave %s, does not exist'
%(ifaceobj.name, slave)) %(ifaceobj.name, slave))
continue continue
self.ifenslavecmd.enslave_slave(ifaceobj.name, slave, self.ipcmd.link_set(slave, 'master', ifaceobj.name)
prehook=self.ipcmd.link_down, rtnetlink_api.rtnl_api.link_set(slave, "up")
posthook=self.ipcmd.link_up)
def _apply_slaves_lacp_fallback_prio(self, ifaceobj): def _apply_slaves_lacp_fallback_prio(self, ifaceobj):
slaves = self.ifenslavecmd.get_slaves(ifaceobj.name) slaves = self.ifenslavecmd.get_slaves(ifaceobj.name)

View File

@ -181,6 +181,8 @@ class iface():
HAS_SIBLINGS = 0x2 HAS_SIBLINGS = 0x2
IFACERANGE_ENTRY = 0x3 IFACERANGE_ENTRY = 0x3
IFACERANGE_START = 0x4 IFACERANGE_START = 0x4
LINK_MASTER = 0x5
LINK_SLAVE = 0x6
version = '0.1' version = '0.1'
@ -452,10 +454,10 @@ class iface():
unknownstr='unknown', use_realname=False): unknownstr='unknown', use_realname=False):
indent = '\t' indent = '\t'
outbuf = '' outbuf = ''
if use_realname: if use_realname and self.realname:
name = self.realname name = '%s' %self.realname
else: else:
name = self.name name = '%s' %self.name
if self.auto: if self.auto:
outbuf += 'auto %s\n' %name outbuf += 'auto %s\n' %name
ifaceline = '' ifaceline = ''

View File

@ -108,14 +108,26 @@ class ifupdownMain(ifupdownBase):
# Handlers for ops that ifupdown2 owns # Handlers for ops that ifupdown2 owns
def run_up(self, ifaceobj): def run_up(self, ifaceobj):
ifacename = ifaceobj.name # If this object is a link slave, ie its link is controlled
if self.link_exists(ifacename): # by its link master interface, then dont set the link state.
self.link_up(ifacename) # But do allow user to change state of the link if the interface
# is already with its link master (hence the master check).
if ((ifaceobj.flags & iface.LINK_SLAVE) and
not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)):
return
if self.link_exists(ifaceobj.name):
self.link_up(ifaceobj.name)
def run_down(self, ifaceobj): def run_down(self, ifaceobj):
ifacename = ifaceobj.name # If this object is a link slave, ie its link is controlled
if self.link_exists(ifacename): # by its link master interface, then dont set the link state.
self.link_down(ifacename) # But do allow user to change state of the link if the interface
# is already with its link master (hence the master check).
if ((ifaceobj.flags & iface.LINK_SLAVE) and
not os.path.exists('/sys/class/net/%s/master' %ifaceobj.name)):
return
if self.link_exists(ifaceobj.name):
self.link_down(ifaceobj.name)
# ifupdown object interface operation handlers # ifupdown object interface operation handlers
ops_handlers = OrderedDict([('up', run_up), ops_handlers = OrderedDict([('up', run_up),
@ -314,7 +326,7 @@ class ifupdownMain(ifupdownBase):
if not ifaceobj: return True if not ifaceobj: return True
return self.is_ifaceobj_noconfig(ifaceobj) return self.is_ifaceobj_noconfig(ifaceobj)
def preprocess_dependency_list(self, upperifacename, dlist, ops): def preprocess_dependency_list(self, upperifaceobj, dlist, ops):
""" We go through the dependency list and """ We go through the dependency list and
delete or add interfaces from the interfaces dict by delete or add interfaces from the interfaces dict by
applying the following rules: applying the following rules:
@ -334,18 +346,25 @@ class ifupdownMain(ifupdownBase):
for d in dlist: for d in dlist:
dilist = self.get_ifaceobjs(d) dilist = self.get_ifaceobjs(d)
if not dilist: if not dilist:
ni = None
if self.is_iface_builtin_byname(d): if self.is_iface_builtin_byname(d):
self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG, ni = self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG,
True).add_to_upperifaces(upperifacename) True)
elif not self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG: elif not self._DELETE_DEPENDENT_IFACES_WITH_NOCONFIG:
self.create_n_save_ifaceobj(d, self.NOCONFIG, ni = self.create_n_save_ifaceobj(d, self.NOCONFIG,
True).add_to_upperifaces(upperifacename) True)
else: else:
del_list.append(d) del_list.append(d)
if ni:
ni.add_to_upperifaces(upperifaceobj.name)
if (upperifaceobj.flags & iface.LINK_MASTER):
ni.flags |= iface.LINK_SLAVE
else: else:
for di in dilist: for di in dilist:
di.inc_refcnt() di.inc_refcnt()
di.add_to_upperifaces(upperifacename) di.add_to_upperifaces(upperifaceobj.name)
if (upperifaceobj.flags & iface.LINK_MASTER):
di.flags |= iface.LINK_SLAVE
for d in del_list: for d in del_list:
dlist.remove(d) dlist.remove(d)
@ -375,30 +394,6 @@ class ifupdownMain(ifupdownBase):
if dlist: ret_dlist.extend(dlist) if dlist: ret_dlist.extend(dlist)
return list(set(ret_dlist)) return list(set(ret_dlist))
def populate_dependency_info_old(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """
if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
iqueue = deque(ifacenames)
while iqueue:
i = iqueue.popleft()
# Go through all modules and find dependent ifaces
dlist = None
ifaceobj = self.get_ifaceobj_first(i)
if not ifaceobj:
continue
dlist = self.query_dependents(ifaceobj, ops, ifacenames)
if dlist and dlist != ifaceobj.lowerifaces:
self.preprocess_dependency_list(ifaceobj.name,
dlist, ops)
[iqueue.append(d) for d in dlist]
self.dependency_graph.setdefault(i, []).extend(dlist)
ifaceobj.lowerifaces = self.dependency_graph.get(i)
else:
self.dependency_graph[i] = dlist
def populate_dependency_info(self, ops, ifacenames=None): def populate_dependency_info(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """ """ recursive function to generate iface dependency info """
@ -419,7 +414,7 @@ class ifupdownMain(ifupdownBase):
else: else:
continue continue
if dlist: if dlist:
self.preprocess_dependency_list(ifaceobj.name, self.preprocess_dependency_list(ifaceobj,
dlist, ops) dlist, ops)
ifaceobj.lowerifaces = dlist ifaceobj.lowerifaces = dlist
[iqueue.append(d) for d in dlist] [iqueue.append(d) for d in dlist]