2 * originally based on the dummy device.
4 * Copyright 1999, Thomas Davis, tadavis@lbl.gov.
5 * Licensed under the GPL. Based on dummy.c, and eql.c devices.
7 * bond.c: a bonding/etherchannel/sun trunking net driver
9 * This is useful to talk to a Cisco 5500, running Etherchannel, aka:
10 * Linux Channel Bonding
11 * Sun Trunking (Solaris)
14 * ifconfig bond0 ipaddress netmask up
15 * will setup a network device, with an ip address. No mac address
16 * will be assigned at this time. The hw mac address will come from
17 * the first slave bonded to the channel. All slaves will then use
18 * this hw mac address.
21 * will release all slaves, marking them as down.
23 * ifenslave bond0 eth0
24 * will attache eth0 to bond0 as a slave. eth0 hw mac address will either
25 * a: be used as initial mac address
26 * b: if a hw mac address already is there, eth0's hw mac address
27 * will then be set from bond0.
29 * v0.1 - first working version.
30 * v0.2 - changed stats to be calculated by summing slaves stats.
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/sched.h>
37 #include <linux/types.h>
38 #include <linux/fcntl.h>
39 #include <linux/interrupt.h>
40 #include <linux/ptrace.h>
41 #include <linux/ioport.h>
43 #include <linux/malloc.h>
44 #include <linux/string.h>
45 #include <linux/init.h>
46 #include <asm/system.h>
47 #include <asm/bitops.h>
50 #include <asm/uaccess.h>
51 #include <linux/errno.h>
53 #include <linux/netdevice.h>
54 #include <linux/etherdevice.h>
55 #include <linux/skbuff.h>
57 #include <linux/if_bonding.h>
63 struct net_device
*dev
;
66 typedef struct bonding
70 struct net_device
*master
;
72 slave_t
*current_slave
;
73 struct net_device_stats stats
;
77 static int bond_xmit(struct sk_buff
*skb
, struct net_device
*dev
);
78 static struct net_device_stats
*bond_get_stats(struct net_device
*dev
);
80 static struct net_device
*this_bond
;
82 static int bond_open(struct net_device
*dev
)
88 static int bond_close(struct net_device
*master
)
90 bonding_t
*bond
= master
->priv
;
93 while ((slave
= bond
->next
) != (slave_t
*)bond
) {
95 spin_lock_bh(&master
->xmit_lock
);
96 slave
->next
->prev
= slave
->prev
;
97 slave
->prev
->next
= slave
->next
;
98 bond
->current_slave
= (slave_t
*)bond
;
99 spin_unlock_bh(&master
->xmit_lock
);
101 netdev_set_master(slave
->dev
, NULL
);
110 /* Fake multicast ability.
112 NB. It is possible and necessary to make it true one, otherwise
113 the device is not functional.
115 static void bond_set_multicast_list(struct net_device
*dev
)
119 static int bond_enslave(struct net_device
*master
, struct net_device
*dev
)
122 bonding_t
*bond
= master
->priv
;
125 if (dev
->type
!= master
->type
)
128 if ((slave
= kmalloc(sizeof(slave_t
), GFP_KERNEL
)) == NULL
)
131 memset(slave
, 0, sizeof(slave_t
));
133 err
= netdev_set_master(dev
, master
);
141 spin_lock_bh(&master
->xmit_lock
);
145 slave
->prev
= bond
->prev
;
146 slave
->next
= (slave_t
*)bond
;
147 slave
->prev
->next
= slave
;
148 slave
->next
->prev
= slave
;
150 spin_unlock_bh(&master
->xmit_lock
);
156 static int bond_release(struct net_device
*master
, struct net_device
*dev
)
158 bonding_t
*bond
= master
->priv
;
161 if (dev
->master
!= master
)
164 netdev_set_master(dev
, NULL
);
166 for (slave
= bond
->next
; slave
!= (slave_t
*)bond
; slave
= slave
->next
) {
167 if (slave
->dev
== dev
) {
168 spin_lock_bh(&master
->xmit_lock
);
169 if (bond
->current_slave
== slave
)
170 bond
->current_slave
= slave
->next
;
171 slave
->next
->prev
= slave
->prev
;
172 slave
->prev
->next
= slave
->next
;
173 spin_unlock_bh(&master
->xmit_lock
);
185 /* It is pretty silly, SIOCSIFHWADDR exists to make this. */
187 static int bond_sethwaddr(struct net_device
*master
, struct net_device
*slave
)
189 memcpy(master
->dev_addr
, slave
->dev_addr
, slave
->addr_len
);
193 static int bond_ioctl(struct net_device
*master
, struct ifreq
*ifr
, int cmd
)
195 struct net_device
*slave
= __dev_get_by_name(ifr
->ifr_slave
);
202 return bond_enslave(master
, slave
);
204 return bond_release(master
, slave
);
206 return bond_sethwaddr(master
, slave
);
212 static int bond_event(struct notifier_block
*this, unsigned long event
, void *ptr
)
214 struct net_device
*slave
= ptr
;
216 if (this_bond
== NULL
||
217 this_bond
== slave
||
218 this_bond
!= slave
->master
)
222 case NETDEV_UNREGISTER
:
223 bond_release(this_bond
, slave
);
230 struct notifier_block bond_netdev_notifier
={
236 int __init
bond_init(struct net_device
*dev
)
240 bond
= kmalloc(sizeof(struct bonding
), GFP_KERNEL
);
244 memset(bond
, 0, sizeof(struct bonding
));
245 bond
->next
= (slave_t
*)bond
;
246 bond
->prev
= (slave_t
*)bond
;
248 bond
->current_slave
= (slave_t
*)bond
;
251 /* Initialize the device structure. */
252 dev
->hard_start_xmit
= bond_xmit
;
253 dev
->get_stats
= bond_get_stats
;
254 dev
->open
= bond_open
;
255 dev
->stop
= bond_close
;
256 dev
->set_multicast_list
= bond_set_multicast_list
;
257 dev
->do_ioctl
= bond_ioctl
;
259 /* Fill in the fields of the device structure with ethernet-generic
262 dev
->tx_queue_len
= 0;
263 dev
->flags
|= IFF_MASTER
;
267 register_netdevice_notifier(&bond_netdev_notifier
);
272 static int bond_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
274 bonding_t
*bond
= dev
->priv
;
275 slave_t
*slave
, *start_at
;
276 int pkt_len
= skb
->len
;
278 slave
= start_at
= bond
->current_slave
;
281 if (slave
== (slave_t
*)bond
)
284 if (netif_running(slave
->dev
) && netif_carrier_ok(dev
)) {
285 bond
->current_slave
= slave
->next
;
286 skb
->dev
= slave
->dev
;
288 if (dev_queue_xmit(skb
)) {
289 bond
->stats
.tx_dropped
++;
291 bond
->stats
.tx_packets
++;
292 bond
->stats
.tx_bytes
+= pkt_len
;
296 } while ((slave
= slave
->next
) != start_at
);
298 bond
->stats
.tx_dropped
++;
303 static struct net_device_stats
*bond_get_stats(struct net_device
*dev
)
305 bonding_t
*bond
= dev
->priv
;
312 static char bond_name
[16];
314 static struct net_device dev_bond
= {
315 bond_name
, /* Needs to be writeable */
318 0, 0, 0, NULL
, bond_init
};
320 int init_module(void)
322 /* Find a name for this unit */
323 int err
=dev_alloc_name(&dev_bond
,"bond%d");
328 if (register_netdev(&dev_bond
) != 0)
334 void cleanup_module(void)
336 unregister_netdevice_notifier(&bond_netdev_notifier
);
338 unregister_netdev(&dev_bond
);
340 kfree(dev_bond
.priv
);