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
nexedi
linux
Commits
e3fe9444
Commit
e3fe9444
authored
Jun 03, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bonding driver: Merge 2.4.x driver updates into 2.5.
parent
d403771c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
274 additions
and
30 deletions
+274
-30
CREDITS
CREDITS
+4
-0
drivers/net/bonding.c
drivers/net/bonding.c
+266
-29
include/linux/if_bonding.h
include/linux/if_bonding.h
+4
-1
No files found.
CREDITS
View file @
e3fe9444
...
@@ -2774,6 +2774,10 @@ N: Christopher Smith
...
@@ -2774,6 +2774,10 @@ N: Christopher Smith
E: x@xman.org
E: x@xman.org
D: Tulip net driver hacker
D: Tulip net driver hacker
N: Mark Smith
E: mark.smith@comdev.cc
D: Multicast support in bonding driver
N: Miquel van Smoorenburg
N: Miquel van Smoorenburg
E: miquels@cistron.nl
E: miquels@cistron.nl
D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff.
D: Kernel and net hacker. Sysvinit, minicom. doing Debian stuff.
...
...
drivers/net/bonding.c
View file @
e3fe9444
...
@@ -161,6 +161,21 @@
...
@@ -161,6 +161,21 @@
* - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
* - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
* - Handle hot swap ethernet interface deregistration events to remove
* - Handle hot swap ethernet interface deregistration events to remove
* kernel oops following hot swap of enslaved interface
* kernel oops following hot swap of enslaved interface
*
* 2002/1/2 - Chad N. Tindel <ctindel at ieee dot org>
* - Restore original slave flags at release time.
*
* 2002/02/18 - Erik Habbinga <erik_habbinga at hp dot com>
* - bond_release(): calling kfree on our_slave after call to
* bond_restore_slave_flags, not before
* - bond_enslave(): saving slave flags into original_flags before
* call to netdev_set_master, so the IFF_SLAVE flag doesn't end
* up in original_flags
*
* 2002/04/05 - Mark Smith <mark.smith at comdev dot cc> and
* Steve Mead <steve.mead at comdev dot cc>
* - Port Gleb Natapov's multicast support patchs from 2.4.12
* to 2.4.18 adding support for multicast.
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -208,11 +223,8 @@
...
@@ -208,11 +223,8 @@
#define MII_ENDOF_NWAY 0x20
#define MII_ENDOF_NWAY 0x20
#undef MII_LINK_READY
#undef MII_LINK_READY
/*#define MII_LINK_READY (MII_LINK_UP | MII_ENDOF_NWAY)*/
#define MII_LINK_READY (MII_LINK_UP)
#define MII_LINK_READY (MII_LINK_UP)
#define MAX_BOND_ADDR 256
#ifndef BOND_LINK_ARP_INTERV
#ifndef BOND_LINK_ARP_INTERV
#define BOND_LINK_ARP_INTERV 0
#define BOND_LINK_ARP_INTERV 0
#endif
#endif
...
@@ -223,7 +235,7 @@ static unsigned long arp_target = 0;
...
@@ -223,7 +235,7 @@ static unsigned long arp_target = 0;
static
u32
my_ip
=
0
;
static
u32
my_ip
=
0
;
char
*
arp_target_hw_addr
=
NULL
;
char
*
arp_target_hw_addr
=
NULL
;
static
int
max_bonds
=
MAX_BONDS
;
static
int
max_bonds
=
BOND_DEFAULT_
MAX_BONDS
;
static
int
miimon
=
BOND_LINK_MON_INTERV
;
static
int
miimon
=
BOND_LINK_MON_INTERV
;
static
int
mode
=
BOND_MODE_ROUNDROBIN
;
static
int
mode
=
BOND_MODE_ROUNDROBIN
;
static
int
updelay
=
0
;
static
int
updelay
=
0
;
...
@@ -234,7 +246,7 @@ int bond_cnt;
...
@@ -234,7 +246,7 @@ int bond_cnt;
static
struct
bonding
*
these_bonds
=
NULL
;
static
struct
bonding
*
these_bonds
=
NULL
;
static
struct
net_device
*
dev_bonds
=
NULL
;
static
struct
net_device
*
dev_bonds
=
NULL
;
MODULE_PARM
(
max_bonds
,
"
1-"
__MODULE_STRING
(
INT_MAX
)
"
i"
);
MODULE_PARM
(
max_bonds
,
"i"
);
MODULE_PARM_DESC
(
max_bonds
,
"Max number of bonded devices"
);
MODULE_PARM_DESC
(
max_bonds
,
"Max number of bonded devices"
);
MODULE_PARM
(
miimon
,
"i"
);
MODULE_PARM
(
miimon
,
"i"
);
MODULE_PARM_DESC
(
miimon
,
"Link check interval in milliseconds"
);
MODULE_PARM_DESC
(
miimon
,
"Link check interval in milliseconds"
);
...
@@ -260,6 +272,15 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev);
...
@@ -260,6 +272,15 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev);
static
void
bond_mii_monitor
(
struct
net_device
*
dev
);
static
void
bond_mii_monitor
(
struct
net_device
*
dev
);
static
void
bond_arp_monitor
(
struct
net_device
*
dev
);
static
void
bond_arp_monitor
(
struct
net_device
*
dev
);
static
int
bond_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
);
static
int
bond_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
);
static
void
bond_restore_slave_flags
(
slave_t
*
slave
);
static
void
bond_mc_list_destroy
(
struct
bonding
*
bond
);
static
void
bond_mc_add
(
bonding_t
*
bond
,
void
*
addr
,
int
alen
);
static
void
bond_mc_delete
(
bonding_t
*
bond
,
void
*
addr
,
int
alen
);
static
int
bond_mc_list_copy
(
struct
dev_mc_list
*
src
,
struct
bonding
*
dst
,
int
gpf_flag
);
static
inline
int
dmi_same
(
struct
dev_mc_list
*
dmi1
,
struct
dev_mc_list
*
dmi2
);
static
void
bond_set_promiscuity
(
bonding_t
*
bond
,
int
inc
);
static
void
bond_set_allmulti
(
bonding_t
*
bond
,
int
inc
);
static
struct
dev_mc_list
*
bond_mc_list_find_dmi
(
struct
dev_mc_list
*
dmi
,
struct
dev_mc_list
*
mc_list
);
static
void
bond_set_slave_inactive_flags
(
slave_t
*
slave
);
static
void
bond_set_slave_inactive_flags
(
slave_t
*
slave
);
static
void
bond_set_slave_active_flags
(
slave_t
*
slave
);
static
void
bond_set_slave_active_flags
(
slave_t
*
slave
);
static
int
bond_enslave
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
static
int
bond_enslave
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
...
@@ -282,6 +303,11 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length);
...
@@ -282,6 +303,11 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length);
#define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
#define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
(netif_running(dev) && netif_carrier_ok(dev)))
(netif_running(dev) && netif_carrier_ok(dev)))
static
void
bond_restore_slave_flags
(
slave_t
*
slave
)
{
slave
->
dev
->
flags
=
slave
->
original_flags
;
}
static
void
bond_set_slave_inactive_flags
(
slave_t
*
slave
)
static
void
bond_set_slave_inactive_flags
(
slave_t
*
slave
)
{
{
slave
->
state
=
BOND_STATE_BACKUP
;
slave
->
state
=
BOND_STATE_BACKUP
;
...
@@ -431,6 +457,7 @@ static int bond_close(struct net_device *master)
...
@@ -431,6 +457,7 @@ static int bond_close(struct net_device *master)
/* Release the bonded slaves */
/* Release the bonded slaves */
bond_release_all
(
master
);
bond_release_all
(
master
);
bond_mc_list_destroy
(
bond
);
write_unlock_irqrestore
(
&
bond
->
lock
,
flags
);
write_unlock_irqrestore
(
&
bond
->
lock
,
flags
);
...
@@ -438,19 +465,180 @@ static int bond_close(struct net_device *master)
...
@@ -438,19 +465,180 @@ static int bond_close(struct net_device *master)
return
0
;
return
0
;
}
}
static
void
set_multicast_list
(
struct
net_device
*
master
)
/*
* flush all members of flush->mc_list from device dev->mc_list
*/
static
void
bond_mc_list_flush
(
struct
net_device
*
dev
,
struct
net_device
*
flush
)
{
{
struct
dev_mc_list
*
dmi
;
for
(
dmi
=
flush
->
mc_list
;
dmi
!=
NULL
;
dmi
=
dmi
->
next
)
dev_mc_delete
(
dev
,
dmi
->
dmi_addr
,
dmi
->
dmi_addrlen
,
0
);
}
/*
/*
bonding_t *bond = master->priv;
* Totally destroys the mc_list in bond
*/
static
void
bond_mc_list_destroy
(
struct
bonding
*
bond
)
{
struct
dev_mc_list
*
dmi
;
dmi
=
bond
->
mc_list
;
while
(
dmi
)
{
bond
->
mc_list
=
dmi
->
next
;
kfree
(
dmi
);
dmi
=
bond
->
mc_list
;
}
}
/*
* Add a Multicast address to every slave in the bonding group
*/
static
void
bond_mc_add
(
bonding_t
*
bond
,
void
*
addr
,
int
alen
)
{
slave_t
*
slave
;
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
{
dev_mc_add
(
slave
->
dev
,
addr
,
alen
,
0
);
}
}
/*
* Remove a multicast address from every slave in the bonding group
*/
static
void
bond_mc_delete
(
bonding_t
*
bond
,
void
*
addr
,
int
alen
)
{
slave_t
*
slave
;
slave_t
*
slave
;
for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
slave->dev->mc_list = master->mc_list;
dev_mc_delete
(
slave
->
dev
,
addr
,
alen
,
0
);
slave->dev->mc_count = master->mc_count;
}
slave->dev->flags = master->flags;
slave->dev->set_multicast_list(slave->dev);
/*
* Copy all the Multicast addresses from src to the bonding device dst
*/
static
int
bond_mc_list_copy
(
struct
dev_mc_list
*
src
,
struct
bonding
*
dst
,
int
gpf_flag
)
{
struct
dev_mc_list
*
dmi
,
*
new_dmi
;
for
(
dmi
=
src
;
dmi
!=
NULL
;
dmi
=
dmi
->
next
)
{
new_dmi
=
kmalloc
(
sizeof
(
struct
dev_mc_list
),
gpf_flag
);
if
(
new_dmi
==
NULL
)
{
return
-
ENOMEM
;
}
new_dmi
->
next
=
dst
->
mc_list
;
dst
->
mc_list
=
new_dmi
;
new_dmi
->
dmi_addrlen
=
dmi
->
dmi_addrlen
;
memcpy
(
new_dmi
->
dmi_addr
,
dmi
->
dmi_addr
,
dmi
->
dmi_addrlen
);
new_dmi
->
dmi_users
=
dmi
->
dmi_users
;
new_dmi
->
dmi_gusers
=
dmi
->
dmi_gusers
;
}
}
return
0
;
}
/*
* Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
*/
static
inline
int
dmi_same
(
struct
dev_mc_list
*
dmi1
,
struct
dev_mc_list
*
dmi2
)
{
return
memcmp
(
dmi1
->
dmi_addr
,
dmi2
->
dmi_addr
,
dmi1
->
dmi_addrlen
)
==
0
&&
dmi1
->
dmi_addrlen
==
dmi2
->
dmi_addrlen
;
}
/*
* Push the promiscuity flag down to all slaves
*/
*/
static
void
bond_set_promiscuity
(
bonding_t
*
bond
,
int
inc
)
{
slave_t
*
slave
;
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
dev_set_promiscuity
(
slave
->
dev
,
inc
);
}
/*
* Push the allmulti flag down to all slaves
*/
static
void
bond_set_allmulti
(
bonding_t
*
bond
,
int
inc
)
{
slave_t
*
slave
;
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
dev_set_allmulti
(
slave
->
dev
,
inc
);
}
/*
* returns dmi entry if found, NULL otherwise
*/
static
struct
dev_mc_list
*
bond_mc_list_find_dmi
(
struct
dev_mc_list
*
dmi
,
struct
dev_mc_list
*
mc_list
)
{
struct
dev_mc_list
*
idmi
;
for
(
idmi
=
mc_list
;
idmi
!=
NULL
;
idmi
=
idmi
->
next
)
{
if
(
dmi_same
(
dmi
,
idmi
))
{
return
idmi
;
}
}
return
NULL
;
}
static
void
set_multicast_list
(
struct
net_device
*
master
)
{
bonding_t
*
bond
=
master
->
priv
;
struct
dev_mc_list
*
dmi
;
unsigned
long
flags
=
0
;
/*
* Lock the private data for the master
*/
write_lock_irqsave
(
&
bond
->
lock
,
flags
);
/*
* Lock the master device so that noone trys to transmit
* while we're changing things
*/
spin_lock_bh
(
&
master
->
xmit_lock
);
/* set promiscuity flag to slaves */
if
(
(
master
->
flags
&
IFF_PROMISC
)
&&
!
(
bond
->
flags
&
IFF_PROMISC
)
)
bond_set_promiscuity
(
bond
,
1
);
if
(
!
(
master
->
flags
&
IFF_PROMISC
)
&&
(
bond
->
flags
&
IFF_PROMISC
)
)
bond_set_promiscuity
(
bond
,
-
1
);
/* set allmulti flag to slaves */
if
(
(
master
->
flags
&
IFF_ALLMULTI
)
&&
!
(
bond
->
flags
&
IFF_ALLMULTI
)
)
bond_set_allmulti
(
bond
,
1
);
if
(
!
(
master
->
flags
&
IFF_ALLMULTI
)
&&
(
bond
->
flags
&
IFF_ALLMULTI
)
)
bond_set_allmulti
(
bond
,
-
1
);
bond
->
flags
=
master
->
flags
;
/* looking for addresses to add to slaves' mc list */
for
(
dmi
=
master
->
mc_list
;
dmi
!=
NULL
;
dmi
=
dmi
->
next
)
{
if
(
bond_mc_list_find_dmi
(
dmi
,
bond
->
mc_list
)
==
NULL
)
bond_mc_add
(
bond
,
dmi
->
dmi_addr
,
dmi
->
dmi_addrlen
);
}
/* looking for addresses to delete from slaves' list */
for
(
dmi
=
bond
->
mc_list
;
dmi
!=
NULL
;
dmi
=
dmi
->
next
)
{
if
(
bond_mc_list_find_dmi
(
dmi
,
master
->
mc_list
)
==
NULL
)
bond_mc_delete
(
bond
,
dmi
->
dmi_addr
,
dmi
->
dmi_addrlen
);
}
/* save master's multicast list */
bond_mc_list_destroy
(
bond
);
bond_mc_list_copy
(
master
->
mc_list
,
bond
,
GFP_KERNEL
);
spin_unlock_bh
(
&
master
->
xmit_lock
);
write_unlock_irqrestore
(
&
bond
->
lock
,
flags
);
}
}
/*
/*
...
@@ -476,6 +664,7 @@ static int bond_enslave(struct net_device *master_dev,
...
@@ -476,6 +664,7 @@ static int bond_enslave(struct net_device *master_dev,
unsigned
long
flags
=
0
;
unsigned
long
flags
=
0
;
int
ndx
=
0
;
int
ndx
=
0
;
int
err
=
0
;
int
err
=
0
;
struct
dev_mc_list
*
dmi
;
if
(
master_dev
==
NULL
||
slave_dev
==
NULL
)
{
if
(
master_dev
==
NULL
||
slave_dev
==
NULL
)
{
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -513,6 +702,8 @@ static int bond_enslave(struct net_device *master_dev,
...
@@ -513,6 +702,8 @@ static int bond_enslave(struct net_device *master_dev,
}
}
memset
(
new_slave
,
0
,
sizeof
(
slave_t
));
memset
(
new_slave
,
0
,
sizeof
(
slave_t
));
/* save flags before call to netdev_set_master */
new_slave
->
original_flags
=
slave_dev
->
flags
;
err
=
netdev_set_master
(
slave_dev
,
master_dev
);
err
=
netdev_set_master
(
slave_dev
,
master_dev
);
if
(
err
)
{
if
(
err
)
{
...
@@ -526,10 +717,38 @@ static int bond_enslave(struct net_device *master_dev,
...
@@ -526,10 +717,38 @@ static int bond_enslave(struct net_device *master_dev,
new_slave
->
dev
=
slave_dev
;
new_slave
->
dev
=
slave_dev
;
/* set promiscuity level to new slave */
if
(
master_dev
->
flags
&
IFF_PROMISC
)
dev_set_promiscuity
(
slave_dev
,
1
);
/* set allmulti level to new slave */
if
(
master_dev
->
flags
&
IFF_ALLMULTI
)
dev_set_allmulti
(
slave_dev
,
1
);
/* upload master's mc_list to new slave */
for
(
dmi
=
master_dev
->
mc_list
;
dmi
!=
NULL
;
dmi
=
dmi
->
next
)
dev_mc_add
(
slave_dev
,
dmi
->
dmi_addr
,
dmi
->
dmi_addrlen
,
0
);
/*
/*
* queue to the end of the slaves list, make the first element its
* queue to the end of the slaves list, make the first element its
* successor, the last one its predecessor, and make it the bond's
* successor, the last one its predecessor, and make it the bond's
* predecessor.
* predecessor.
*
* Just to clarify, so future bonding driver hackers don't go through
* the same confusion stage I did trying to figure this out, the
* slaves are stored in a double linked circular list, sortof.
* In the ->next direction, the last slave points to the first slave,
* bypassing bond; only the slaves are in the ->next direction.
* In the ->prev direction, however, the first slave points to bond
* and bond points to the last slave.
*
* It looks like a circle with a little bubble hanging off one side
* in the ->prev direction only.
*
* When going through the list once, its best to start at bond->prev
* and go in the ->prev direction, testing for bond. Doing this
* in the ->next direction doesn't work. Trust me, I know this now.
* :) -mts 2002.03.14
*/
*/
new_slave
->
prev
=
bond
->
prev
;
new_slave
->
prev
=
bond
->
prev
;
new_slave
->
prev
->
next
=
new_slave
;
new_slave
->
prev
->
next
=
new_slave
;
...
@@ -838,10 +1057,20 @@ static int bond_release(struct net_device *master, struct net_device *slave)
...
@@ -838,10 +1057,20 @@ static int bond_release(struct net_device *master, struct net_device *slave)
}
else
{
}
else
{
printk
(
".
\n
"
);
printk
(
".
\n
"
);
}
}
kfree
(
our_slave
);
/* release the slave from its bond */
/* release the slave from its bond */
/* flush master's mc_list from slave */
bond_mc_list_flush
(
slave
,
master
);
/* unset promiscuity level from slave */
if
(
master
->
flags
&
IFF_PROMISC
)
dev_set_promiscuity
(
slave
,
-
1
);
/* unset allmulti level from slave */
if
(
master
->
flags
&
IFF_ALLMULTI
)
dev_set_allmulti
(
slave
,
-
1
);
netdev_set_master
(
slave
,
NULL
);
netdev_set_master
(
slave
,
NULL
);
/* only restore its RUNNING flag if monitoring set it down */
/* only restore its RUNNING flag if monitoring set it down */
...
@@ -854,6 +1083,9 @@ static int bond_release(struct net_device *master, struct net_device *slave)
...
@@ -854,6 +1083,9 @@ static int bond_release(struct net_device *master, struct net_device *slave)
dev_close
(
slave
);
dev_close
(
slave
);
}
}
bond_restore_slave_flags
(
our_slave
);
kfree
(
our_slave
);
if
(
bond
->
current_slave
==
NULL
)
{
if
(
bond
->
current_slave
==
NULL
)
{
printk
(
KERN_INFO
printk
(
KERN_INFO
"%s: now running without any active interface !
\n
"
,
"%s: now running without any active interface !
\n
"
,
...
@@ -1121,7 +1353,7 @@ static void bond_mii_monitor(struct net_device *master)
...
@@ -1121,7 +1353,7 @@ static void bond_mii_monitor(struct net_device *master)
master
->
name
,
bestslave
->
dev
->
name
,
master
->
name
,
bestslave
->
dev
->
name
,
(
updelay
-
bestslave
->
delay
)
*
miimon
);
(
updelay
-
bestslave
->
delay
)
*
miimon
);
bestslave
->
delay
=
0
;
bestslave
->
delay
=
0
;
bestslave
->
link
=
BOND_LINK_UP
;
bestslave
->
link
=
BOND_LINK_UP
;
}
}
...
@@ -1192,7 +1424,7 @@ static void bond_arp_monitor(struct net_device *master)
...
@@ -1192,7 +1424,7 @@ static void bond_arp_monitor(struct net_device *master)
read_lock
(
&
bond
->
ptrlock
);
read_lock
(
&
bond
->
ptrlock
);
if
(
(
!
(
slave
->
link
==
BOND_LINK_UP
))
if
(
(
!
(
slave
->
link
==
BOND_LINK_UP
))
&&
(
slave
!=
bond
->
current_slave
)
)
{
&&
(
slave
!=
bond
->
current_slave
)
)
{
read_unlock
(
&
bond
->
ptrlock
);
read_unlock
(
&
bond
->
ptrlock
);
...
@@ -1207,7 +1439,7 @@ static void bond_arp_monitor(struct net_device *master)
...
@@ -1207,7 +1439,7 @@ static void bond_arp_monitor(struct net_device *master)
slave
->
state
=
BOND_STATE_ACTIVE
;
slave
->
state
=
BOND_STATE_ACTIVE
;
bond
->
current_slave
=
slave
;
bond
->
current_slave
=
slave
;
}
}
if
(
slave
!=
bond
->
current_slave
)
{
if
(
slave
!=
bond
->
current_slave
)
{
slave
->
dev
->
flags
|=
IFF_NOARP
;
slave
->
dev
->
flags
|=
IFF_NOARP
;
}
}
write_unlock
(
&
bond
->
ptrlock
);
write_unlock
(
&
bond
->
ptrlock
);
...
@@ -1311,7 +1543,7 @@ static void bond_arp_monitor(struct net_device *master)
...
@@ -1311,7 +1543,7 @@ static void bond_arp_monitor(struct net_device *master)
#define isdigit(c) (c >= '0' && c <= '9')
#define isdigit(c) (c >= '0' && c <= '9')
__inline
static
int
atoi
(
char
**
s
)
__inline
static
int
atoi
(
char
**
s
)
{
{
int
i
=
0
;
int
i
=
0
;
while
(
isdigit
(
**
s
))
while
(
isdigit
(
**
s
))
i
=
i
*
20
+
*
((
*
s
)
++
)
-
'0'
;
i
=
i
*
20
+
*
((
*
s
)
++
)
-
'0'
;
return
i
;
return
i
;
...
@@ -1388,7 +1620,7 @@ my_inet_aton(char *cp, unsigned long *the_addr) {
...
@@ -1388,7 +1620,7 @@ my_inet_aton(char *cp, unsigned long *the_addr) {
goto
ret_0
;
goto
ret_0
;
}
}
if
(
the_addr
!=
NULL
)
{
if
(
the_addr
!=
NULL
)
{
*
the_addr
=
res
.
word
|
htonl
(
val
);
*
the_addr
=
res
.
word
|
htonl
(
val
);
}
}
...
@@ -1420,7 +1652,7 @@ static int bond_info_query(struct net_device *master, struct ifbond *info)
...
@@ -1420,7 +1652,7 @@ static int bond_info_query(struct net_device *master, struct ifbond *info)
info
->
miimon
=
miimon
;
info
->
miimon
=
miimon
;
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
{
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
{
info
->
num_slaves
++
;
info
->
num_slaves
++
;
}
}
read_unlock_irqrestore
(
&
bond
->
lock
,
flags
);
read_unlock_irqrestore
(
&
bond
->
lock
,
flags
);
...
@@ -1696,7 +1928,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
...
@@ -1696,7 +1928,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
/* if we are sending arp packets, try to at least
/* if we are sending arp packets, try to at least
identify our own ip address */
identify our own ip address */
if
(
(
arp_interval
>
0
)
&&
(
my_ip
==
0
)
&&
if
(
(
arp_interval
>
0
)
&&
(
my_ip
==
0
)
&&
(
skb
->
protocol
==
__constant_htons
(
ETH_P_ARP
)
)
)
{
(
skb
->
protocol
==
__constant_htons
(
ETH_P_ARP
)
)
)
{
char
*
the_ip
=
(((
char
*
)
skb
->
data
))
char
*
the_ip
=
(((
char
*
)
skb
->
data
))
+
sizeof
(
struct
ethhdr
)
+
sizeof
(
struct
ethhdr
)
...
@@ -1708,7 +1940,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
...
@@ -1708,7 +1940,7 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
/* if we are sending arp packets and don't know
/* if we are sending arp packets and don't know
the target hw address, save it so we don't need
the target hw address, save it so we don't need
to use a broadcast address */
to use a broadcast address */
if
(
(
arp_interval
>
0
)
&&
(
arp_target_hw_addr
==
NULL
)
&&
if
(
(
arp_interval
>
0
)
&&
(
arp_target_hw_addr
==
NULL
)
&&
(
skb
->
protocol
==
__constant_htons
(
ETH_P_IP
)
)
)
{
(
skb
->
protocol
==
__constant_htons
(
ETH_P_IP
)
)
)
{
struct
ethhdr
*
eth_hdr
=
struct
ethhdr
*
eth_hdr
=
(
struct
ethhdr
*
)
(((
char
*
)
skb
->
data
));
(
struct
ethhdr
*
)
(((
char
*
)
skb
->
data
));
...
@@ -1751,7 +1983,7 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev)
...
@@ -1751,7 +1983,7 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev)
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
read_lock_irqsave
(
&
bond
->
lock
,
flags
);
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
{
for
(
slave
=
bond
->
prev
;
slave
!=
(
slave_t
*
)
bond
;
slave
=
slave
->
prev
)
{
sstats
=
slave
->
dev
->
get_stats
(
slave
->
dev
);
sstats
=
slave
->
dev
->
get_stats
(
slave
->
dev
);
stats
->
rx_packets
+=
sstats
->
rx_packets
;
stats
->
rx_packets
+=
sstats
->
rx_packets
;
...
@@ -1861,7 +2093,7 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length)
...
@@ -1861,7 +2093,7 @@ static int bond_get_info(char *buf, char **start, off_t offset, int length)
static
int
bond_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
static
int
bond_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
void
*
ptr
)
{
{
struct
bonding
*
this_bond
=
(
struct
bonding
*
)
these_bonds
;
struct
bonding
*
this_bond
=
(
struct
bonding
*
)
these_bonds
;
struct
bonding
*
last_bond
;
struct
bonding
*
last_bond
;
struct
net_device
*
event_dev
=
(
struct
net_device
*
)
ptr
;
struct
net_device
*
event_dev
=
(
struct
net_device
*
)
ptr
;
...
@@ -1905,10 +2137,8 @@ static int bond_event(struct notifier_block *this, unsigned long event,
...
@@ -1905,10 +2137,8 @@ static int bond_event(struct notifier_block *this, unsigned long event,
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
}
}
static
struct
notifier_block
bond_netdev_notifier
=
{
static
struct
notifier_block
bond_netdev_notifier
=
{
bond_event
,
notifier_call:
bond_event
,
NULL
,
0
};
};
static
int
__init
bond_init
(
struct
net_device
*
dev
)
static
int
__init
bond_init
(
struct
net_device
*
dev
)
...
@@ -2038,6 +2268,13 @@ static int __init bonding_init(void)
...
@@ -2038,6 +2268,13 @@ static int __init bonding_init(void)
/* Find a name for this unit */
/* Find a name for this unit */
static
struct
net_device
*
dev_bond
=
NULL
;
static
struct
net_device
*
dev_bond
=
NULL
;
if
(
max_bonds
<
1
||
max_bonds
>
INT_MAX
)
{
printk
(
KERN_WARNING
"bonding_init(): max_bonds (%d) not in range %d-%d, "
"so it was reset to BOND_DEFAULT_MAX_BONDS (%d)"
,
max_bonds
,
1
,
INT_MAX
,
BOND_DEFAULT_MAX_BONDS
);
max_bonds
=
BOND_DEFAULT_MAX_BONDS
;
}
dev_bond
=
dev_bonds
=
kmalloc
(
max_bonds
*
sizeof
(
struct
net_device
),
dev_bond
=
dev_bonds
=
kmalloc
(
max_bonds
*
sizeof
(
struct
net_device
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
dev_bond
==
NULL
)
{
if
(
dev_bond
==
NULL
)
{
...
...
include/linux/if_bonding.h
View file @
e3fe9444
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
#define BOND_STATE_ACTIVE 0
/* link is active */
#define BOND_STATE_ACTIVE 0
/* link is active */
#define BOND_STATE_BACKUP 1
/* link is backup */
#define BOND_STATE_BACKUP 1
/* link is backup */
#define
MAX_BONDS 1
/* M
aximum number of devices to support */
#define
BOND_DEFAULT_MAX_BONDS 1
/* Default m
aximum number of devices to support */
typedef
struct
ifbond
{
typedef
struct
ifbond
{
__s32
bond_mode
;
__s32
bond_mode
;
...
@@ -76,6 +76,7 @@ typedef struct slave {
...
@@ -76,6 +76,7 @@ typedef struct slave {
short
delay
;
short
delay
;
char
link
;
/* one of BOND_LINK_XXXX */
char
link
;
/* one of BOND_LINK_XXXX */
char
state
;
/* one of BOND_STATE_XXXX */
char
state
;
/* one of BOND_STATE_XXXX */
unsigned
short
original_flags
;
u32
link_failure_count
;
u32
link_failure_count
;
}
slave_t
;
}
slave_t
;
...
@@ -104,6 +105,8 @@ typedef struct bonding {
...
@@ -104,6 +105,8 @@ typedef struct bonding {
#endif
/* CONFIG_PROC_FS */
#endif
/* CONFIG_PROC_FS */
struct
bonding
*
next_bond
;
struct
bonding
*
next_bond
;
struct
net_device
*
device
;
struct
net_device
*
device
;
struct
dev_mc_list
*
mc_list
;
unsigned
short
flags
;
}
bonding_t
;
}
bonding_t
;
#endif
/* __KERNEL__ */
#endif
/* __KERNEL__ */
...
...
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