1 /*
2 * originally based on the dummy device.
3 *
4 * Copyright 1999, Thomas Davis, tadavis@lbl.gov.
5 * Licensed under the GPL. Based on dummy.c, and eql.c devices.
6 *
7 * bond.c: a bonding/etherchannel/sun trunking net driver
8 *
9 * This is useful to talk to a Cisco 5500, running Etherchannel, aka:
10 * Linux Channel Bonding
11 * Sun Trunking (Solaris)
12 *
13 * How it works:
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.
19 *
20 * ifconfig bond0 down
21 * will release all slaves, marking them as down.
22 *
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.
28 *
29 * v0.1 - first working version.
30 * v0.2 - changed stats to be calculated by summing slaves stats.
31 *
32 */
33
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/netdevice.h>
37 #include <linux/init.h>
38 #include <linux/if_bonding.h>
39
40 typedef struct slave
41 {
42 struct slave *next;
43 struct slave *prev;
44 struct net_device *dev;
45 } slave_t;
46
47 typedef struct bonding
48 {
49 slave_t *next;
50 slave_t *prev;
51 struct net_device *master;
52
53 slave_t *current_slave;
54 struct net_device_stats stats;
55 } bonding_t;
56
57
58 static int bond_xmit(struct sk_buff *skb, struct net_device *dev);
59 static struct net_device_stats *bond_get_stats(struct net_device *dev);
60
61 static struct net_device *this_bond;
62
63 static int bond_open(struct net_device *dev)
64 {
65 MOD_INC_USE_COUNT;
66 return 0;
67 }
68
69 static void release_one_slave(struct net_device *master, slave_t *slave)
70 {
71 bonding_t *bond = master->priv;
72
73 spin_lock_bh(&master->xmit_lock);
74 if (bond->current_slave == slave)
75 bond->current_slave = slave->next;
76 slave->next->prev = slave->prev;
77 slave->prev->next = slave->next;
78 spin_unlock_bh(&master->xmit_lock);
79
80 netdev_set_master(slave->dev, NULL);
81
82 dev_put(slave->dev);
83 kfree(slave);
84 MOD_DEC_USE_COUNT;
85 }
86
87 static int bond_close(struct net_device *master)
88 {
89 bonding_t *bond = master->priv;
90 slave_t *slave;
91
92 while ((slave = bond->next) != (slave_t*)bond)
93 release_one_slave(master, slave);
94
95 MOD_DEC_USE_COUNT;
96 return 0;
97 }
98
99 static void bond_set_multicast_list(struct net_device *master)
100 {
101 bonding_t *bond = master->priv;
102 slave_t *slave;
103
104 for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
105 slave->dev->mc_list = master->mc_list;
106 slave->dev->mc_count = master->mc_count;
107 slave->dev->flags = master->flags;
108 slave->dev->set_multicast_list(slave->dev);
109 }
110 }
111
112 static int bond_enslave(struct net_device *master, struct net_device *dev)
113 {
114 int err;
115 bonding_t *bond = master->priv;
116 slave_t *slave;
117
118 if (dev->type != master->type)
119 return -ENODEV;
120
121 if ((slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL)
122 return -ENOMEM;
123
124 memset(slave, 0, sizeof(slave_t));
125
126 err = netdev_set_master(dev, master);
127 if (err) {
128 kfree(slave);
129 return err;
130 }
131
132 slave->dev = dev;
133
134 spin_lock_bh(&master->xmit_lock);
135
136 dev_hold(dev);
137
138 slave->prev = bond->prev;
139 slave->next = (slave_t*)bond;
140 slave->prev->next = slave;
141 slave->next->prev = slave;
142
143 spin_unlock_bh(&master->xmit_lock);
144
145 MOD_INC_USE_COUNT;
146 return 0;
147 }
148
149 static int bond_release(struct net_device *master, struct net_device *dev)
150 {
151 bonding_t *bond = master->priv;
152 slave_t *slave;
153
154 if (dev->master != master)
155 return -EINVAL;
156
157 for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) {
158 if (slave->dev == dev) {
159 release_one_slave(master, slave);
160 break;
161 }
162 }
163
164 return 0;
165 }
166
167 /* It is pretty silly, SIOCSIFHWADDR exists to make this. */
168
169 static int bond_sethwaddr(struct net_device *master, struct net_device *slave)
170 {
171 memcpy(master->dev_addr, slave->dev_addr, slave->addr_len);
172 return 0;
173 }
174
175 static int bond_ioctl(struct net_device *master, struct ifreq *ifr, int cmd)
176 {
177 struct net_device *slave = __dev_get_by_name(ifr->ifr_slave);
178
179 if (slave == NULL)
180 return -ENODEV;
181
182 switch (cmd) {
183 case BOND_ENSLAVE:
184 return bond_enslave(master, slave);
185 case BOND_RELEASE:
186 return bond_release(master, slave);
187 case BOND_SETHWADDR:
188 return bond_sethwaddr(master, slave);
189 default:
190 return -EOPNOTSUPP;
191 }
192 }
193
194 static int bond_event(struct notifier_block *this, unsigned long event, void *ptr)
195 {
196 struct net_device *slave = ptr;
197
198 if (this_bond == NULL ||
199 this_bond == slave ||
200 this_bond != slave->master)
201 return NOTIFY_DONE;
202
203 switch (event) {
204 case NETDEV_UNREGISTER:
205 bond_release(this_bond, slave);
206 break;
207 }
208
209 return NOTIFY_DONE;
210 }
211
212 static struct notifier_block bond_netdev_notifier={
213 bond_event,
214 NULL,
215 0
216 };
217
218 static int __init bond_init(struct net_device *dev)
219 {
220 bonding_t *bond;
221
222 bond = kmalloc(sizeof(struct bonding), GFP_KERNEL);
223 if (bond == NULL)
224 return -ENOMEM;
225
226 memset(bond, 0, sizeof(struct bonding));
227 bond->next = (slave_t*)bond;
228 bond->prev = (slave_t*)bond;
229 bond->master = dev;
230 bond->current_slave = (slave_t*)bond;
231 dev->priv = bond;
232
233 /* Initialize the device structure. */
234 dev->hard_start_xmit = bond_xmit;
235 dev->get_stats = bond_get_stats;
236 dev->open = bond_open;
237 dev->stop = bond_close;
238 dev->set_multicast_list = bond_set_multicast_list;
239 dev->do_ioctl = bond_ioctl;
240
241 /* Fill in the fields of the device structure with ethernet-generic
242 values. */
243 ether_setup(dev);
244 dev->tx_queue_len = 0;
245 dev->flags |= IFF_MASTER;
246
247 this_bond = dev;
248
249 register_netdevice_notifier(&bond_netdev_notifier);
250
251 return 0;
252 }
253
254 static int bond_xmit(struct sk_buff *skb, struct net_device *dev)
255 {
256 bonding_t *bond = dev->priv;
257 slave_t *slave, *start_at;
258 int pkt_len = skb->len;
259
260 slave = start_at = bond->current_slave;
261
262 do {
263 if (slave == (slave_t*)bond)
264 continue;
265
266 if (netif_running(slave->dev) && netif_carrier_ok(slave->dev)) {
267 bond->current_slave = slave->next;
268 skb->dev = slave->dev;
269
270 if (dev_queue_xmit(skb)) {
271 bond->stats.tx_dropped++;
272 } else {
273 bond->stats.tx_packets++;
274 bond->stats.tx_bytes += pkt_len;
275 }
276 return 0;
277 }
278 } while ((slave = slave->next) != start_at);
279
280 bond->stats.tx_dropped++;
281 kfree_skb(skb);
282 return 0;
283 }
284
285 static struct net_device_stats *bond_get_stats(struct net_device *dev)
286 {
287 bonding_t *bond = dev->priv;
288
289 return &bond->stats;
290 }
291
292 static struct net_device dev_bond = {
293 "",
294 0, 0, 0, 0,
295 0x0, 0,
296 0, 0, 0, NULL, bond_init };
297
298 static int __init bonding_init(void)
299 {
300 /* Find a name for this unit */
301 int err=dev_alloc_name(&dev_bond,"bond%d");
302
303 if (err<0)
304 return err;
305
306 if (register_netdev(&dev_bond) != 0)
307 return -EIO;
308
309 return 0;
310 }
311
312 static void __exit bonding_exit(void)
313 {
314 unregister_netdevice_notifier(&bond_netdev_notifier);
315
316 unregister_netdev(&dev_bond);
317
318 kfree(dev_bond.priv);
319 }
320
321 module_init(bonding_init);
322 module_exit(bonding_exit);
323
324 /*
325 * Local variables:
326 * c-indent-level: 8
327 * c-basic-offset: 8
328 * tab-width: 8
329 * End:
330 */
331
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.