1 /* net/sched/sch_teql.c "True" (or "trivial") link equalizer.
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License
5 * as published by the Free Software Foundation; either version
6 * 2 of the License, or (at your option) any later version.
8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/errno.h>
16 #include <linux/if_arp.h>
17 #include <linux/netdevice.h>
18 #include <linux/init.h>
19 #include <linux/skbuff.h>
20 #include <linux/moduleparam.h>
22 #include <net/neighbour.h>
23 #include <net/pkt_sched.h>
29 After loading this module you will find a new device teqlN
30 and new qdisc with the same name. To join a slave to the equalizer
31 you should just set this qdisc on a device f.e.
33 # tc qdisc add dev eth0 root teql0
34 # tc qdisc add dev eth1 root teql0
36 That's all. Full PnP 8)
41 1. Slave devices MUST be active devices, i.e., they must raise the tbusy
42 signal and generate EOI events. If you want to equalize virtual devices
43 like tunnels, use a normal eql device.
44 2. This device puts no limitations on physical slave characteristics
45 f.e. it will equalize 9600baud line and 100Mb ethernet perfectly :-)
46 Certainly, large difference in link speeds will make the resulting
47 eqalized link unusable, because of huge packet reordering.
48 I estimate an upper useful difference as ~10 times.
49 3. If the slave requires address resolution, only protocols using
50 neighbour cache (IPv4/IPv6) will work over the equalized link.
51 Other protocols are still allowed to use the slave device directly,
52 which will not break load balancing, though native slave
53 traffic will have the highest priority. */
57 struct Qdisc_ops qops;
58 struct net_device *dev;
60 struct list_head master_list;
61 struct net_device_stats stats;
64 struct teql_sched_data
67 struct teql_master *m;
68 struct neighbour *ncache;
69 struct sk_buff_head q;
72 #define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next)
74 #define FMASK (IFF_BROADCAST|IFF_POINTOPOINT)
76 /* "teql*" qdisc routines */
79 teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)
81 struct net_device *dev = qdisc_dev(sch);
82 struct teql_sched_data *q = qdisc_priv(sch);
84 if (q->q.qlen < dev->tx_queue_len) {
85 __skb_queue_tail(&q->q, skb);
86 sch->bstats.bytes += qdisc_pkt_len(skb);
87 sch->bstats.packets++;
97 teql_requeue(struct sk_buff *skb, struct Qdisc* sch)
99 struct teql_sched_data *q = qdisc_priv(sch);
101 __skb_queue_head(&q->q, skb);
102 sch->qstats.requeues++;
106 static struct sk_buff *
107 teql_dequeue(struct Qdisc* sch)
109 struct teql_sched_data *dat = qdisc_priv(sch);
110 struct netdev_queue *dat_queue;
113 skb = __skb_dequeue(&dat->q);
114 dat_queue = netdev_get_tx_queue(dat->m->dev, 0);
116 struct net_device *m = qdisc_dev(dat_queue->qdisc);
118 dat->m->slaves = sch;
122 sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen;
126 static struct sk_buff *
127 teql_peek(struct Qdisc* sch)
129 /* teql is meant to be used as root qdisc */
133 static __inline__ void
134 teql_neigh_release(struct neighbour *n)
141 teql_reset(struct Qdisc* sch)
143 struct teql_sched_data *dat = qdisc_priv(sch);
145 skb_queue_purge(&dat->q);
147 teql_neigh_release(xchg(&dat->ncache, NULL));
151 teql_destroy(struct Qdisc* sch)
153 struct Qdisc *q, *prev;
154 struct teql_sched_data *dat = qdisc_priv(sch);
155 struct teql_master *master = dat->m;
157 if ((prev = master->slaves) != NULL) {
159 q = NEXT_SLAVE(prev);
161 NEXT_SLAVE(prev) = NEXT_SLAVE(q);
162 if (q == master->slaves) {
163 master->slaves = NEXT_SLAVE(q);
164 if (q == master->slaves) {
165 struct netdev_queue *txq;
166 spinlock_t *root_lock;
168 txq = netdev_get_tx_queue(master->dev, 0);
169 master->slaves = NULL;
171 root_lock = qdisc_root_sleeping_lock(txq->qdisc);
172 spin_lock_bh(root_lock);
173 qdisc_reset(txq->qdisc);
174 spin_unlock_bh(root_lock);
177 skb_queue_purge(&dat->q);
178 teql_neigh_release(xchg(&dat->ncache, NULL));
182 } while ((prev = q) != master->slaves);
186 static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
188 struct net_device *dev = qdisc_dev(sch);
189 struct teql_master *m = (struct teql_master*)sch->ops;
190 struct teql_sched_data *q = qdisc_priv(sch);
192 if (dev->hard_header_len > m->dev->hard_header_len)
200 skb_queue_head_init(&q->q);
203 if (m->dev->flags & IFF_UP) {
204 if ((m->dev->flags&IFF_POINTOPOINT && !(dev->flags&IFF_POINTOPOINT))
205 || (m->dev->flags&IFF_BROADCAST && !(dev->flags&IFF_BROADCAST))
206 || (m->dev->flags&IFF_MULTICAST && !(dev->flags&IFF_MULTICAST))
207 || dev->mtu < m->dev->mtu)
210 if (!(dev->flags&IFF_POINTOPOINT))
211 m->dev->flags &= ~IFF_POINTOPOINT;
212 if (!(dev->flags&IFF_BROADCAST))
213 m->dev->flags &= ~IFF_BROADCAST;
214 if (!(dev->flags&IFF_MULTICAST))
215 m->dev->flags &= ~IFF_MULTICAST;
216 if (dev->mtu < m->dev->mtu)
217 m->dev->mtu = dev->mtu;
219 q->next = NEXT_SLAVE(m->slaves);
220 NEXT_SLAVE(m->slaves) = sch;
224 m->dev->mtu = dev->mtu;
225 m->dev->flags = (m->dev->flags&~FMASK)|(dev->flags&FMASK);
232 __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
234 struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0);
235 struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc);
236 struct neighbour *mn = skb->dst->neighbour;
237 struct neighbour *n = q->ncache;
241 if (n && n->tbl == mn->tbl &&
242 memcmp(n->primary_key, mn->primary_key, mn->tbl->key_len) == 0) {
243 atomic_inc(&n->refcnt);
245 n = __neigh_lookup_errno(mn->tbl, mn->primary_key, dev);
249 if (neigh_event_send(n, skb_res) == 0) {
253 err = dev_hard_header(skb, dev, ntohs(skb->protocol),
254 n->ha, NULL, skb->len);
255 read_unlock(&n->lock);
261 teql_neigh_release(xchg(&q->ncache, n));
265 return (skb_res == NULL) ? -EAGAIN : 1;
268 static inline int teql_resolve(struct sk_buff *skb,
269 struct sk_buff *skb_res, struct net_device *dev)
271 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
272 if (txq->qdisc == &noop_qdisc)
275 if (dev->header_ops == NULL ||
277 skb->dst->neighbour == NULL)
279 return __teql_resolve(skb, skb_res, dev);
282 static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
284 struct teql_master *master = netdev_priv(dev);
285 struct Qdisc *start, *q;
288 int subq = skb_get_queue_mapping(skb);
289 struct sk_buff *skb_res = NULL;
291 start = master->slaves;
297 if ((q = start) == NULL)
301 struct net_device *slave = qdisc_dev(q);
302 struct netdev_queue *slave_txq;
304 slave_txq = netdev_get_tx_queue(slave, 0);
305 if (slave_txq->qdisc_sleeping != q)
307 if (__netif_subqueue_stopped(slave, subq) ||
308 !netif_running(slave)) {
313 switch (teql_resolve(skb, skb_res, slave)) {
315 if (__netif_tx_trylock(slave_txq)) {
316 if (!netif_tx_queue_stopped(slave_txq) &&
317 !netif_tx_queue_frozen(slave_txq) &&
318 slave->hard_start_xmit(skb, slave) == 0) {
319 __netif_tx_unlock(slave_txq);
320 master->slaves = NEXT_SLAVE(q);
321 netif_wake_queue(dev);
322 master->stats.tx_packets++;
323 master->stats.tx_bytes +=
327 __netif_tx_unlock(slave_txq);
329 if (netif_queue_stopped(dev))
333 master->slaves = NEXT_SLAVE(q);
339 __skb_pull(skb, skb_network_offset(skb));
340 } while ((q = NEXT_SLAVE(q)) != start);
342 if (nores && skb_res == NULL) {
348 netif_stop_queue(dev);
351 master->stats.tx_errors++;
354 master->stats.tx_dropped++;
359 static int teql_master_open(struct net_device *dev)
362 struct teql_master *m = netdev_priv(dev);
364 unsigned flags = IFF_NOARP|IFF_MULTICAST;
366 if (m->slaves == NULL)
373 struct net_device *slave = qdisc_dev(q);
378 if (slave->mtu < mtu)
380 if (slave->hard_header_len > LL_MAX_HEADER)
383 /* If all the slaves are BROADCAST, master is BROADCAST
384 If all the slaves are PtP, master is PtP
385 Otherwise, master is NBMA.
387 if (!(slave->flags&IFF_POINTOPOINT))
388 flags &= ~IFF_POINTOPOINT;
389 if (!(slave->flags&IFF_BROADCAST))
390 flags &= ~IFF_BROADCAST;
391 if (!(slave->flags&IFF_MULTICAST))
392 flags &= ~IFF_MULTICAST;
393 } while ((q = NEXT_SLAVE(q)) != m->slaves);
396 m->dev->flags = (m->dev->flags&~FMASK) | flags;
397 netif_start_queue(m->dev);
401 static int teql_master_close(struct net_device *dev)
403 netif_stop_queue(dev);
407 static struct net_device_stats *teql_master_stats(struct net_device *dev)
409 struct teql_master *m = netdev_priv(dev);
413 static int teql_master_mtu(struct net_device *dev, int new_mtu)
415 struct teql_master *m = netdev_priv(dev);
424 if (new_mtu > qdisc_dev(q)->mtu)
426 } while ((q=NEXT_SLAVE(q)) != m->slaves);
433 static __init void teql_master_setup(struct net_device *dev)
435 struct teql_master *master = netdev_priv(dev);
436 struct Qdisc_ops *ops = &master->qops;
439 ops->priv_size = sizeof(struct teql_sched_data);
441 ops->enqueue = teql_enqueue;
442 ops->dequeue = teql_dequeue;
443 ops->peek = teql_peek;
444 ops->requeue = teql_requeue;
445 ops->init = teql_qdisc_init;
446 ops->reset = teql_reset;
447 ops->destroy = teql_destroy;
448 ops->owner = THIS_MODULE;
450 dev->open = teql_master_open;
451 dev->hard_start_xmit = teql_master_xmit;
452 dev->stop = teql_master_close;
453 dev->get_stats = teql_master_stats;
454 dev->change_mtu = teql_master_mtu;
455 dev->type = ARPHRD_VOID;
457 dev->tx_queue_len = 100;
458 dev->flags = IFF_NOARP;
459 dev->hard_header_len = LL_MAX_HEADER;
462 static LIST_HEAD(master_dev_list);
463 static int max_equalizers = 1;
464 module_param(max_equalizers, int, 0);
465 MODULE_PARM_DESC(max_equalizers, "Max number of link equalizers");
467 static int __init teql_init(void)
472 for (i = 0; i < max_equalizers; i++) {
473 struct net_device *dev;
474 struct teql_master *master;
476 dev = alloc_netdev(sizeof(struct teql_master),
477 "teql%d", teql_master_setup);
483 if ((err = register_netdev(dev))) {
488 master = netdev_priv(dev);
490 strlcpy(master->qops.id, dev->name, IFNAMSIZ);
491 err = register_qdisc(&master->qops);
494 unregister_netdev(dev);
499 list_add_tail(&master->master_list, &master_dev_list);
504 static void __exit teql_exit(void)
506 struct teql_master *master, *nxt;
508 list_for_each_entry_safe(master, nxt, &master_dev_list, master_list) {
510 list_del(&master->master_list);
512 unregister_qdisc(&master->qops);
513 unregister_netdev(master->dev);
514 free_netdev(master->dev);
518 module_init(teql_init);
519 module_exit(teql_exit);
521 MODULE_LICENSE("GPL");