Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
7527f000
Commit
7527f000
authored
Sep 20, 2003
by
Amir Noam
Committed by
Stephen Hemminger
Sep 20, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] [bonding 2.6] consolidate change_active operations
parent
b6d4364c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
141 additions
and
171 deletions
+141
-171
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_main.c
+141
-171
No files found.
drivers/net/bonding/bond_main.c
View file @
7527f000
...
...
@@ -473,6 +473,11 @@ DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n";
#define MAX_ARP_IP_TARGETS 16
#endif
#define USES_PRIMARY(mode) \
(((mode) == BOND_MODE_ACTIVEBACKUP) || \
((mode) == BOND_MODE_TLB) || \
((mode) == BOND_MODE_ALB))
struct
bond_parm_tbl
{
char
*
modename
;
int
mode
;
...
...
@@ -581,6 +586,9 @@ static int bond_enslave(struct net_device *master, struct net_device *slave);
static
int
bond_release
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
static
int
bond_release_all
(
struct
net_device
*
master
);
static
int
bond_sethwaddr
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
static
void
change_active_interface
(
struct
bonding
*
bond
,
struct
slave
*
new
);
static
void
reselect_active_interface
(
struct
bonding
*
bond
);
static
struct
slave
*
find_best_interface
(
struct
bonding
*
bond
);
/* Caller must hold bond->ptrlock for write */
static
inline
struct
slave
*
...
...
@@ -691,7 +699,7 @@ update_slave_cnt(bonding_t *bond, int incr)
* belongs to <bond>. It returns <slave> in case it's needed.
* Nothing is freed on return, structures are just unchained.
* If the bond->current_slave pointer was pointing to <slave>,
* it
's replaced with bond->next, or NULL if not applicable
.
* it
should be changed by the calling function
.
*
* bond->lock held for writing by caller.
*/
...
...
@@ -725,17 +733,6 @@ bond_detach_slave(bonding_t *bond, slave_t *slave)
update_slave_cnt
(
bond
,
-
1
);
/* no need to hold ptrlock since bond lock is
* already held for writing
*/
if
(
slave
==
bond
->
current_slave
)
{
if
(
bond
->
next
!=
(
slave_t
*
)
bond
)
{
/* found one slave */
bond_assign_current_slave
(
bond
,
bond
->
next
);
}
else
{
bond_assign_current_slave
(
bond
,
NULL
);
}
}
return
slave
;
}
...
...
@@ -1578,9 +1575,7 @@ static int bond_enslave(struct net_device *master_dev,
#endif
/* first slave or no active slave yet, and this link
is OK, so make this interface the active one */
bond_assign_current_slave
(
bond
,
new_slave
);
bond_set_slave_active_flags
(
new_slave
);
bond_mc_update
(
bond
,
new_slave
,
NULL
);
change_active_interface
(
bond
,
new_slave
);
}
else
{
#ifdef BONDING_DEBUG
...
...
@@ -1630,7 +1625,7 @@ static int bond_enslave(struct net_device *master_dev,
/* first slave or no active slave yet, and this link
* is OK, so make this interface the active one
*/
bond_assign_current_slav
e
(
bond
,
new_slave
);
change_active_interfac
e
(
bond
,
new_slave
);
}
/* if there is a primary slave, remember it */
...
...
@@ -1737,6 +1732,13 @@ static int bond_change_active(struct net_device *master_dev, struct net_device *
return
-
ENODEV
;
}
/* Verify that master_dev is indeed the master of slave_dev */
if
(
!
(
slave_dev
->
flags
&
IFF_SLAVE
)
||
(
slave_dev
->
master
!=
master_dev
))
{
return
-
EINVAL
;
}
bond
=
(
struct
bonding
*
)
master_dev
->
priv
;
write_lock_bh
(
&
bond
->
lock
);
slave
=
(
slave_t
*
)
bond
;
...
...
@@ -1761,16 +1763,7 @@ static int bond_change_active(struct net_device *master_dev, struct net_device *
(
oldactive
!=
NULL
)
&&
(
newactive
->
link
==
BOND_LINK_UP
)
&&
IS_UP
(
newactive
->
dev
))
{
if
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
{
bond_set_slave_inactive_flags
(
oldactive
);
bond_set_slave_active_flags
(
newactive
);
}
bond_mc_update
(
bond
,
newactive
,
oldactive
);
bond_assign_current_slave
(
bond
,
newactive
);
printk
(
"%s : activate %s(old : %s)
\n
"
,
master_dev
->
name
,
newactive
->
dev
->
name
,
oldactive
->
dev
->
name
);
change_active_interface
(
bond
,
newactive
);
}
else
{
ret
=
-
EINVAL
;
}
...
...
@@ -1778,47 +1771,26 @@ static int bond_change_active(struct net_device *master_dev, struct net_device *
return
ret
;
}
/* Choose a new valid interface from the pool, set it active
* and make it the current slave. If no valid interface is
* found, the oldest slave in BACK state is choosen and
* activated. If none is found, it's considered as no
* interfaces left so the current slave is set to NULL.
* The result is a pointer to the current slave.
*
* Since this function sends messages tails through printk, the caller
* must have started something like `printk(KERN_INFO "xxxx ");'.
/**
* find_best_interface - select the best available slave to be the active one
* @bond: our bonding struct
*
* Warning: Caller must hold ptrlock for writing.
*/
s
lave_t
*
change_active_interface
(
bonding_t
*
bond
)
s
tatic
struct
slave
*
find_best_interface
(
struct
bonding
*
bond
)
{
s
lave_t
*
newslave
,
*
oldslave
;
s
lave_t
*
bestslave
=
NULL
;
s
truct
slave
*
newslave
,
*
oldslave
;
s
truct
slave
*
bestslave
=
NULL
;
int
mintime
;
newslave
=
oldslave
=
bond
->
current_slave
;
if
(
newslave
==
NULL
)
{
/* there were no active slaves left */
if
(
bond
->
next
!=
(
slave_t
*
)
bond
)
{
/* found one slave */
newslave
=
bond
_assign_current_slave
(
bond
,
bond
->
next
)
;
newslave
=
bond
->
next
;
}
else
{
printk
(
" but could not find any %s interface.
\n
"
,
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
?
"backup"
:
"other"
);
bond_assign_current_slave
(
bond
,
NULL
);
return
NULL
;
/* still no slave, return NULL */
}
}
else
if
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
{
/* make sure oldslave doesn't send arps - this could
* cause a ping-pong effect between interfaces since they
* would be able to tx arps - in active backup only one
* slave should be able to tx arps, and that should be
* the current_slave; the only exception is when all
* slaves have gone down, then only one non-current slave can
* send arps at a time; clearing oldslaves' mc list is handled
* later in this function.
*/
bond_set_slave_inactive_flags
(
oldslave
);
}
mintime
=
updelay
;
...
...
@@ -1833,22 +1805,12 @@ slave_t *change_active_interface(bonding_t *bond)
newslave
=
bond
->
primary_slave
;
}
/* remember where to stop iterating over the slaves */
oldslave
=
newslave
;
do
{
if
(
IS_UP
(
newslave
->
dev
))
{
if
(
newslave
->
link
==
BOND_LINK_UP
)
{
/* this one is immediately usable */
if
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
{
bond_set_slave_active_flags
(
newslave
);
bond_mc_update
(
bond
,
newslave
,
oldslave
);
printk
(
" and making interface %s the active one.
\n
"
,
newslave
->
dev
->
name
);
}
else
{
printk
(
" and setting pointer to interface %s.
\n
"
,
newslave
->
dev
->
name
);
}
bond_assign_current_slave
(
bond
,
newslave
);
return
newslave
;
}
else
if
(
newslave
->
link
==
BOND_LINK_BACK
)
{
...
...
@@ -1861,46 +1823,100 @@ slave_t *change_active_interface(bonding_t *bond)
}
}
while
((
newslave
=
newslave
->
next
)
!=
oldslave
);
/* no usable backup found, we'll see if we at least got a link that was
coming back for a long time, and could possibly already be usable.
*/
if
(
bestslave
!=
NULL
)
{
/* early take-over. */
printk
(
" and making interface %s the active one %d ms earlier.
\n
"
,
bestslave
->
dev
->
name
,
(
updelay
-
bestslave
->
delay
)
*
miimon
);
bestslave
->
delay
=
0
;
bestslave
->
link
=
BOND_LINK_UP
;
bestslave
->
jiffies
=
jiffies
;
bond_set_slave_active_flags
(
bestslave
);
bond_mc_update
(
bond
,
bestslave
,
oldslave
);
bond_assign_current_slave
(
bond
,
bestslave
);
return
bestslave
;
}
if
((
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
&&
(
multicast_mode
==
BOND_MULTICAST_ACTIVE
)
&&
(
oldslave
!=
NULL
))
{
/* flush bonds (master's) mc_list from oldslave since it wasn't
* updated (and deleted) above
*/
bond_mc_list_flush
(
oldslave
->
dev
,
bond
->
device
);
if
(
bond
->
device
->
flags
&
IFF_PROMISC
)
{
dev_set_promiscuity
(
oldslave
->
dev
,
-
1
);
return
bestslave
;
}
/**
* change_active_interface - change the active slave into the specified one
* @bond: our bonding struct
* @new: the new slave to make the active one
*
* Set the new slave to the bond's settings and unset them on the old
* current_slave.
* Setting include flags, mc-list, promiscuity, allmulti, etc.
*
* If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
* because it is apparently the best available slave we have, even though its
* updelay hasn't timed out yet.
*
* Warning: Caller must hold ptrlock for writing.
*/
static
void
change_active_interface
(
struct
bonding
*
bond
,
struct
slave
*
new
)
{
struct
slave
*
old
=
bond
->
current_slave
;
if
(
old
==
new
)
{
return
;
}
if
(
new
)
{
if
(
new
->
link
==
BOND_LINK_BACK
)
{
if
(
USES_PRIMARY
(
bond_mode
))
{
printk
(
KERN_INFO
"%s: making interface %s the new "
"active one %d ms earlier.
\n
"
,
bond
->
device
->
name
,
new
->
dev
->
name
,
(
updelay
-
new
->
delay
)
*
miimon
);
}
new
->
delay
=
0
;
new
->
link
=
BOND_LINK_UP
;
new
->
jiffies
=
jiffies
;
if
(
bond_mode
==
BOND_MODE_8023AD
)
{
bond_3ad_handle_link_change
(
new
,
BOND_LINK_UP
);
}
if
((
bond_mode
==
BOND_MODE_TLB
)
||
(
bond_mode
==
BOND_MODE_ALB
))
{
bond_alb_handle_link_change
(
bond
,
new
,
BOND_LINK_UP
);
}
}
else
{
if
(
USES_PRIMARY
(
bond_mode
))
{
printk
(
KERN_INFO
"%s: making interface %s the new active one.
\n
"
,
bond
->
device
->
name
,
new
->
dev
->
name
);
}
}
if
(
bond
->
device
->
flags
&
IFF_ALLMULTI
)
{
dev_set_allmulti
(
oldslave
->
dev
,
-
1
);
}
if
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
{
if
(
old
)
{
bond_set_slave_inactive_flags
(
old
);
}
if
(
new
)
{
bond_set_slave_active_flags
(
new
);
}
}
printk
(
" but could not find any %s interface.
\n
"
,
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
?
"backup"
:
"other"
);
/* absolutely nothing found. let's return NULL */
bond_assign_current_slave
(
bond
,
NULL
);
return
NULL
;
if
(
USES_PRIMARY
(
bond_mode
))
{
bond_mc_update
(
bond
,
new
,
old
);
}
bond_assign_current_slave
(
bond
,
new
);
}
/**
* reselect_active_interface - select a new active slave, if needed
* @bond: our bonding struct
*
* This functions shoud be called when one of the following occurs:
* - The old current_slave has been released or lost its link.
* - The primary_slave has got its link back.
* - A slave has got its link back and there's no old current_slave.
*
* Warning: Caller must hold ptrlock for writing.
*/
static
void
reselect_active_interface
(
struct
bonding
*
bond
)
{
struct
slave
*
best_slave
;
best_slave
=
find_best_interface
(
bond
);
if
(
best_slave
!=
bond
->
current_slave
)
{
change_active_interface
(
bond
,
best_slave
);
}
}
/*
...
...
@@ -1967,6 +1983,11 @@ static int bond_release(struct net_device *master, struct net_device *slave)
bond_3ad_unbind_slave
(
our_slave
);
}
printk
(
KERN_INFO
"%s: releasing %s interface %s
\n
"
,
master
->
name
,
(
our_slave
->
state
==
BOND_STATE_ACTIVE
)
?
"active"
:
"backup"
,
slave
->
name
);
/* release the slave from its bond */
bond_detach_slave
(
bond
,
our_slave
);
...
...
@@ -1974,18 +1995,11 @@ static int bond_release(struct net_device *master, struct net_device *slave)
bond
->
primary_slave
=
NULL
;
}
printk
(
KERN_INFO
"%s: releasing %s interface %s"
,
master
->
name
,
(
our_slave
->
state
==
BOND_STATE_ACTIVE
)
?
"active"
:
"backup"
,
slave
->
name
);
if
(
our_slave
==
old_current
)
{
/* find a new interface and be verbose */
change_active_interface
(
bond
);
}
else
{
printk
(
".
\n
"
);
if
(
bond
->
current_slave
==
our_slave
)
{
change_active_interface
(
bond
,
NULL
);
reselect_active_interface
(
bond
);
}
if
(
bond
->
current_slave
==
NULL
)
{
printk
(
KERN_INFO
"%s: now running without any active interface !
\n
"
,
...
...
@@ -2274,9 +2288,7 @@ static void bond_mii_monitor(struct net_device *master)
write_lock
(
&
bond
->
ptrlock
);
if
(
slave
==
bond
->
current_slave
)
{
/* find a new interface and be verbose */
change_active_interface
(
bond
);
}
else
{
printk
(
".
\n
"
);
reselect_active_interface
(
bond
);
}
write_unlock
(
&
bond
->
ptrlock
);
slave_died
=
1
;
...
...
@@ -2372,7 +2384,7 @@ static void bond_mii_monitor(struct net_device *master)
write_lock
(
&
bond
->
ptrlock
);
if
(
(
bond
->
primary_slave
!=
NULL
)
&&
(
slave
==
bond
->
primary_slave
)
)
change
_active_interface
(
bond
);
reselect
_active_interface
(
bond
);
write_unlock
(
&
bond
->
ptrlock
);
}
else
...
...
@@ -2418,40 +2430,8 @@ static void bond_mii_monitor(struct net_device *master)
/* no active interface at the moment or need to bring up the primary */
if
(
oldcurrent
==
NULL
)
{
/* no active interface at the moment */
if
(
bestslave
!=
NULL
)
{
/* last chance to find one ? */
if
(
bestslave
->
link
==
BOND_LINK_UP
)
{
printk
(
KERN_INFO
"%s: making interface %s the new active one.
\n
"
,
master
->
name
,
bestslave
->
dev
->
name
);
}
else
{
printk
(
KERN_INFO
"%s: making interface %s the new "
"active one %d ms earlier.
\n
"
,
master
->
name
,
bestslave
->
dev
->
name
,
(
updelay
-
bestslave
->
delay
)
*
miimon
);
bestslave
->
delay
=
0
;
bestslave
->
link
=
BOND_LINK_UP
;
bestslave
->
jiffies
=
jiffies
;
/* notify ad that the link status has changed */
if
(
bond_mode
==
BOND_MODE_8023AD
)
{
bond_3ad_handle_link_change
(
bestslave
,
BOND_LINK_UP
);
}
if
((
bond_mode
==
BOND_MODE_TLB
)
||
(
bond_mode
==
BOND_MODE_ALB
))
{
bond_alb_handle_link_change
(
bond
,
bestslave
,
BOND_LINK_UP
);
}
}
if
(
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
{
bond_set_slave_active_flags
(
bestslave
);
bond_mc_update
(
bond
,
bestslave
,
NULL
);
}
else
if
(
bond_mode
!=
BOND_MODE_8023AD
)
{
bestslave
->
state
=
BOND_STATE_ACTIVE
;
}
write_lock
(
&
bond
->
ptrlock
);
bond_assign_current_slav
e
(
bond
,
bestslave
);
change_active_interfac
e
(
bond
,
bestslave
);
write_unlock
(
&
bond
->
ptrlock
);
}
else
if
(
slave_died
)
{
/* print this message only once a slave has just died */
...
...
@@ -2535,7 +2515,7 @@ static void loadbalance_arp_monitor(struct net_device *master)
"for interface %s, "
,
master
->
name
,
slave
->
dev
->
name
);
change
_active_interface
(
bond
);
reselect
_active_interface
(
bond
);
}
else
{
printk
(
KERN_INFO
"%s: interface %s is now up
\n
"
,
...
...
@@ -2567,7 +2547,7 @@ static void loadbalance_arp_monitor(struct net_device *master)
write_lock
(
&
bond
->
ptrlock
);
if
(
slave
==
bond
->
current_slave
)
{
change
_active_interface
(
bond
);
reselect
_active_interface
(
bond
);
}
write_unlock
(
&
bond
->
ptrlock
);
}
...
...
@@ -2645,9 +2625,7 @@ static void activebackup_arp_monitor(struct net_device *master)
if
((
bond
->
current_slave
==
NULL
)
&&
((
jiffies
-
slave
->
dev
->
trans_start
)
<=
the_delta_in_ticks
))
{
bond_assign_current_slave
(
bond
,
slave
);
bond_set_slave_active_flags
(
slave
);
bond_mc_update
(
bond
,
slave
,
NULL
);
change_active_interface
(
bond
,
slave
);
bond
->
current_arp_slave
=
NULL
;
}
else
if
(
bond
->
current_slave
!=
slave
)
{
/* this slave has just come up but we
...
...
@@ -2737,7 +2715,8 @@ static void activebackup_arp_monitor(struct net_device *master)
master
->
name
,
slave
->
dev
->
name
);
write_lock
(
&
bond
->
ptrlock
);
slave
=
change_active_interface
(
bond
);
reselect_active_interface
(
bond
);
slave
=
bond
->
current_slave
;
write_unlock
(
&
bond
->
ptrlock
);
bond
->
current_arp_slave
=
slave
;
if
(
slave
!=
NULL
)
{
...
...
@@ -2756,13 +2735,10 @@ static void activebackup_arp_monitor(struct net_device *master)
bond
->
primary_slave
->
dev
->
name
);
/* primary is up so switch to it */
bond_set_slave_inactive_flags
(
slave
);
bond_mc_update
(
bond
,
bond
->
primary_slave
,
slave
);
write_lock
(
&
bond
->
ptrlock
);
bond_assign_current_slav
e
(
bond
,
bond
->
primary_slave
);
change_active_interfac
e
(
bond
,
bond
->
primary_slave
);
write_unlock
(
&
bond
->
ptrlock
);
slave
=
bond
->
primary_slave
;
bond_set_slave_active_flags
(
slave
);
slave
->
jiffies
=
jiffies
;
}
else
{
bond
->
current_arp_slave
=
NULL
;
...
...
@@ -2805,7 +2781,7 @@ static void activebackup_arp_monitor(struct net_device *master)
/* if the link state is up at this point, we
* mark it down - this can happen if we have
* simultaneous link failures and
*
change
_active_interface doesn't make this
*
reselect
_active_interface doesn't make this
* one the current slave so it is still marked
* up when it is actually down
*/
...
...
@@ -3056,9 +3032,7 @@ static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
break
;
case
BOND_CHANGE_ACTIVE_OLD
:
case
SIOCBONDCHANGEACTIVE
:
if
((
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
||
(
bond_mode
==
BOND_MODE_TLB
)
||
(
bond_mode
==
BOND_MODE_ALB
))
{
if
(
USES_PRIMARY
(
bond_mode
))
{
ret
=
bond_change_active
(
master_dev
,
slave_dev
);
}
else
{
...
...
@@ -3388,9 +3362,7 @@ static int bond_read_proc(char *buf, char **start, off_t off, int count, int *eo
len
+=
sprintf
(
buf
+
len
,
"Bonding Mode: %s
\n
"
,
bond_mode_name
());
if
((
bond_mode
==
BOND_MODE_ACTIVEBACKUP
)
||
(
bond_mode
==
BOND_MODE_TLB
)
||
(
bond_mode
==
BOND_MODE_ALB
))
{
if
(
USES_PRIMARY
(
bond_mode
))
{
read_lock_bh
(
&
bond
->
lock
);
read_lock
(
&
bond
->
ptrlock
);
if
(
bond
->
current_slave
!=
NULL
)
{
...
...
@@ -3905,9 +3877,7 @@ static int __init bonding_init(void)
"link failures! see bonding.txt for details.
\n
"
);
}
if
((
primary
!=
NULL
)
&&
(
bond_mode
!=
BOND_MODE_ACTIVEBACKUP
)
&&
(
bond_mode
!=
BOND_MODE_TLB
)
&&
(
bond_mode
!=
BOND_MODE_ALB
)){
if
((
primary
!=
NULL
)
&&
!
USES_PRIMARY
(
bond_mode
))
{
/* currently, using a primary only makes sense
* in active backup, TLB or ALB modes
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment