Linux 5.7.7
[linux/fpc-iii.git] / net / sched / sch_teql.c
blob689ef6f3ded80968a46aaccc9dc6fd4db9506a85
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* net/sched/sch_teql.c "True" (or "trivial") link equalizer.
4 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
5 */
7 #include <linux/module.h>
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/string.h>
12 #include <linux/errno.h>
13 #include <linux/if_arp.h>
14 #include <linux/netdevice.h>
15 #include <linux/init.h>
16 #include <linux/skbuff.h>
17 #include <linux/moduleparam.h>
18 #include <net/dst.h>
19 #include <net/neighbour.h>
20 #include <net/pkt_sched.h>
23 How to setup it.
24 ----------------
26 After loading this module you will find a new device teqlN
27 and new qdisc with the same name. To join a slave to the equalizer
28 you should just set this qdisc on a device f.e.
30 # tc qdisc add dev eth0 root teql0
31 # tc qdisc add dev eth1 root teql0
33 That's all. Full PnP 8)
35 Applicability.
36 --------------
38 1. Slave devices MUST be active devices, i.e., they must raise the tbusy
39 signal and generate EOI events. If you want to equalize virtual devices
40 like tunnels, use a normal eql device.
41 2. This device puts no limitations on physical slave characteristics
42 f.e. it will equalize 9600baud line and 100Mb ethernet perfectly :-)
43 Certainly, large difference in link speeds will make the resulting
44 eqalized link unusable, because of huge packet reordering.
45 I estimate an upper useful difference as ~10 times.
46 3. If the slave requires address resolution, only protocols using
47 neighbour cache (IPv4/IPv6) will work over the equalized link.
48 Other protocols are still allowed to use the slave device directly,
49 which will not break load balancing, though native slave
50 traffic will have the highest priority. */
52 struct teql_master {
53 struct Qdisc_ops qops;
54 struct net_device *dev;
55 struct Qdisc *slaves;
56 struct list_head master_list;
57 unsigned long tx_bytes;
58 unsigned long tx_packets;
59 unsigned long tx_errors;
60 unsigned long tx_dropped;
63 struct teql_sched_data {
64 struct Qdisc *next;
65 struct teql_master *m;
66 struct sk_buff_head q;
69 #define NEXT_SLAVE(q) (((struct teql_sched_data *)qdisc_priv(q))->next)
71 #define FMASK (IFF_BROADCAST | IFF_POINTOPOINT)
73 /* "teql*" qdisc routines */
75 static int
76 teql_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
78 struct net_device *dev = qdisc_dev(sch);
79 struct teql_sched_data *q = qdisc_priv(sch);
81 if (q->q.qlen < dev->tx_queue_len) {
82 __skb_queue_tail(&q->q, skb);
83 return NET_XMIT_SUCCESS;
86 return qdisc_drop(skb, sch, to_free);
89 static struct sk_buff *
90 teql_dequeue(struct Qdisc *sch)
92 struct teql_sched_data *dat = qdisc_priv(sch);
93 struct netdev_queue *dat_queue;
94 struct sk_buff *skb;
95 struct Qdisc *q;
97 skb = __skb_dequeue(&dat->q);
98 dat_queue = netdev_get_tx_queue(dat->m->dev, 0);
99 q = rcu_dereference_bh(dat_queue->qdisc);
101 if (skb == NULL) {
102 struct net_device *m = qdisc_dev(q);
103 if (m) {
104 dat->m->slaves = sch;
105 netif_wake_queue(m);
107 } else {
108 qdisc_bstats_update(sch, skb);
110 sch->q.qlen = dat->q.qlen + q->q.qlen;
111 return skb;
114 static struct sk_buff *
115 teql_peek(struct Qdisc *sch)
117 /* teql is meant to be used as root qdisc */
118 return NULL;
121 static void
122 teql_reset(struct Qdisc *sch)
124 struct teql_sched_data *dat = qdisc_priv(sch);
126 skb_queue_purge(&dat->q);
127 sch->q.qlen = 0;
130 static void
131 teql_destroy(struct Qdisc *sch)
133 struct Qdisc *q, *prev;
134 struct teql_sched_data *dat = qdisc_priv(sch);
135 struct teql_master *master = dat->m;
137 prev = master->slaves;
138 if (prev) {
139 do {
140 q = NEXT_SLAVE(prev);
141 if (q == sch) {
142 NEXT_SLAVE(prev) = NEXT_SLAVE(q);
143 if (q == master->slaves) {
144 master->slaves = NEXT_SLAVE(q);
145 if (q == master->slaves) {
146 struct netdev_queue *txq;
147 spinlock_t *root_lock;
149 txq = netdev_get_tx_queue(master->dev, 0);
150 master->slaves = NULL;
152 root_lock = qdisc_root_sleeping_lock(rtnl_dereference(txq->qdisc));
153 spin_lock_bh(root_lock);
154 qdisc_reset(rtnl_dereference(txq->qdisc));
155 spin_unlock_bh(root_lock);
158 skb_queue_purge(&dat->q);
159 break;
162 } while ((prev = q) != master->slaves);
166 static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt,
167 struct netlink_ext_ack *extack)
169 struct net_device *dev = qdisc_dev(sch);
170 struct teql_master *m = (struct teql_master *)sch->ops;
171 struct teql_sched_data *q = qdisc_priv(sch);
173 if (dev->hard_header_len > m->dev->hard_header_len)
174 return -EINVAL;
176 if (m->dev == dev)
177 return -ELOOP;
179 q->m = m;
181 skb_queue_head_init(&q->q);
183 if (m->slaves) {
184 if (m->dev->flags & IFF_UP) {
185 if ((m->dev->flags & IFF_POINTOPOINT &&
186 !(dev->flags & IFF_POINTOPOINT)) ||
187 (m->dev->flags & IFF_BROADCAST &&
188 !(dev->flags & IFF_BROADCAST)) ||
189 (m->dev->flags & IFF_MULTICAST &&
190 !(dev->flags & IFF_MULTICAST)) ||
191 dev->mtu < m->dev->mtu)
192 return -EINVAL;
193 } else {
194 if (!(dev->flags&IFF_POINTOPOINT))
195 m->dev->flags &= ~IFF_POINTOPOINT;
196 if (!(dev->flags&IFF_BROADCAST))
197 m->dev->flags &= ~IFF_BROADCAST;
198 if (!(dev->flags&IFF_MULTICAST))
199 m->dev->flags &= ~IFF_MULTICAST;
200 if (dev->mtu < m->dev->mtu)
201 m->dev->mtu = dev->mtu;
203 q->next = NEXT_SLAVE(m->slaves);
204 NEXT_SLAVE(m->slaves) = sch;
205 } else {
206 q->next = sch;
207 m->slaves = sch;
208 m->dev->mtu = dev->mtu;
209 m->dev->flags = (m->dev->flags&~FMASK)|(dev->flags&FMASK);
211 return 0;
215 static int
216 __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
217 struct net_device *dev, struct netdev_queue *txq,
218 struct dst_entry *dst)
220 struct neighbour *n;
221 int err = 0;
223 n = dst_neigh_lookup_skb(dst, skb);
224 if (!n)
225 return -ENOENT;
227 if (dst->dev != dev) {
228 struct neighbour *mn;
230 mn = __neigh_lookup_errno(n->tbl, n->primary_key, dev);
231 neigh_release(n);
232 if (IS_ERR(mn))
233 return PTR_ERR(mn);
234 n = mn;
237 if (neigh_event_send(n, skb_res) == 0) {
238 int err;
239 char haddr[MAX_ADDR_LEN];
241 neigh_ha_snapshot(haddr, n, dev);
242 err = dev_hard_header(skb, dev, ntohs(tc_skb_protocol(skb)),
243 haddr, NULL, skb->len);
245 if (err < 0)
246 err = -EINVAL;
247 } else {
248 err = (skb_res == NULL) ? -EAGAIN : 1;
250 neigh_release(n);
251 return err;
254 static inline int teql_resolve(struct sk_buff *skb,
255 struct sk_buff *skb_res,
256 struct net_device *dev,
257 struct netdev_queue *txq)
259 struct dst_entry *dst = skb_dst(skb);
260 int res;
262 if (rcu_access_pointer(txq->qdisc) == &noop_qdisc)
263 return -ENODEV;
265 if (!dev->header_ops || !dst)
266 return 0;
268 rcu_read_lock();
269 res = __teql_resolve(skb, skb_res, dev, txq, dst);
270 rcu_read_unlock();
272 return res;
275 static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
277 struct teql_master *master = netdev_priv(dev);
278 struct Qdisc *start, *q;
279 int busy;
280 int nores;
281 int subq = skb_get_queue_mapping(skb);
282 struct sk_buff *skb_res = NULL;
284 start = master->slaves;
286 restart:
287 nores = 0;
288 busy = 0;
290 q = start;
291 if (!q)
292 goto drop;
294 do {
295 struct net_device *slave = qdisc_dev(q);
296 struct netdev_queue *slave_txq = netdev_get_tx_queue(slave, 0);
298 if (slave_txq->qdisc_sleeping != q)
299 continue;
300 if (netif_xmit_stopped(netdev_get_tx_queue(slave, subq)) ||
301 !netif_running(slave)) {
302 busy = 1;
303 continue;
306 switch (teql_resolve(skb, skb_res, slave, slave_txq)) {
307 case 0:
308 if (__netif_tx_trylock(slave_txq)) {
309 unsigned int length = qdisc_pkt_len(skb);
311 if (!netif_xmit_frozen_or_stopped(slave_txq) &&
312 netdev_start_xmit(skb, slave, slave_txq, false) ==
313 NETDEV_TX_OK) {
314 __netif_tx_unlock(slave_txq);
315 master->slaves = NEXT_SLAVE(q);
316 netif_wake_queue(dev);
317 master->tx_packets++;
318 master->tx_bytes += length;
319 return NETDEV_TX_OK;
321 __netif_tx_unlock(slave_txq);
323 if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)))
324 busy = 1;
325 break;
326 case 1:
327 master->slaves = NEXT_SLAVE(q);
328 return NETDEV_TX_OK;
329 default:
330 nores = 1;
331 break;
333 __skb_pull(skb, skb_network_offset(skb));
334 } while ((q = NEXT_SLAVE(q)) != start);
336 if (nores && skb_res == NULL) {
337 skb_res = skb;
338 goto restart;
341 if (busy) {
342 netif_stop_queue(dev);
343 return NETDEV_TX_BUSY;
345 master->tx_errors++;
347 drop:
348 master->tx_dropped++;
349 dev_kfree_skb(skb);
350 return NETDEV_TX_OK;
353 static int teql_master_open(struct net_device *dev)
355 struct Qdisc *q;
356 struct teql_master *m = netdev_priv(dev);
357 int mtu = 0xFFFE;
358 unsigned int flags = IFF_NOARP | IFF_MULTICAST;
360 if (m->slaves == NULL)
361 return -EUNATCH;
363 flags = FMASK;
365 q = m->slaves;
366 do {
367 struct net_device *slave = qdisc_dev(q);
369 if (slave == NULL)
370 return -EUNATCH;
372 if (slave->mtu < mtu)
373 mtu = slave->mtu;
374 if (slave->hard_header_len > LL_MAX_HEADER)
375 return -EINVAL;
377 /* If all the slaves are BROADCAST, master is BROADCAST
378 If all the slaves are PtP, master is PtP
379 Otherwise, master is NBMA.
381 if (!(slave->flags&IFF_POINTOPOINT))
382 flags &= ~IFF_POINTOPOINT;
383 if (!(slave->flags&IFF_BROADCAST))
384 flags &= ~IFF_BROADCAST;
385 if (!(slave->flags&IFF_MULTICAST))
386 flags &= ~IFF_MULTICAST;
387 } while ((q = NEXT_SLAVE(q)) != m->slaves);
389 m->dev->mtu = mtu;
390 m->dev->flags = (m->dev->flags&~FMASK) | flags;
391 netif_start_queue(m->dev);
392 return 0;
395 static int teql_master_close(struct net_device *dev)
397 netif_stop_queue(dev);
398 return 0;
401 static void teql_master_stats64(struct net_device *dev,
402 struct rtnl_link_stats64 *stats)
404 struct teql_master *m = netdev_priv(dev);
406 stats->tx_packets = m->tx_packets;
407 stats->tx_bytes = m->tx_bytes;
408 stats->tx_errors = m->tx_errors;
409 stats->tx_dropped = m->tx_dropped;
412 static int teql_master_mtu(struct net_device *dev, int new_mtu)
414 struct teql_master *m = netdev_priv(dev);
415 struct Qdisc *q;
417 q = m->slaves;
418 if (q) {
419 do {
420 if (new_mtu > qdisc_dev(q)->mtu)
421 return -EINVAL;
422 } while ((q = NEXT_SLAVE(q)) != m->slaves);
425 dev->mtu = new_mtu;
426 return 0;
429 static const struct net_device_ops teql_netdev_ops = {
430 .ndo_open = teql_master_open,
431 .ndo_stop = teql_master_close,
432 .ndo_start_xmit = teql_master_xmit,
433 .ndo_get_stats64 = teql_master_stats64,
434 .ndo_change_mtu = teql_master_mtu,
437 static __init void teql_master_setup(struct net_device *dev)
439 struct teql_master *master = netdev_priv(dev);
440 struct Qdisc_ops *ops = &master->qops;
442 master->dev = dev;
443 ops->priv_size = sizeof(struct teql_sched_data);
445 ops->enqueue = teql_enqueue;
446 ops->dequeue = teql_dequeue;
447 ops->peek = teql_peek;
448 ops->init = teql_qdisc_init;
449 ops->reset = teql_reset;
450 ops->destroy = teql_destroy;
451 ops->owner = THIS_MODULE;
453 dev->netdev_ops = &teql_netdev_ops;
454 dev->type = ARPHRD_VOID;
455 dev->mtu = 1500;
456 dev->min_mtu = 68;
457 dev->max_mtu = 65535;
458 dev->tx_queue_len = 100;
459 dev->flags = IFF_NOARP;
460 dev->hard_header_len = LL_MAX_HEADER;
461 netif_keep_dst(dev);
464 static LIST_HEAD(master_dev_list);
465 static int max_equalizers = 1;
466 module_param(max_equalizers, int, 0);
467 MODULE_PARM_DESC(max_equalizers, "Max number of link equalizers");
469 static int __init teql_init(void)
471 int i;
472 int err = -ENODEV;
474 for (i = 0; i < max_equalizers; i++) {
475 struct net_device *dev;
476 struct teql_master *master;
478 dev = alloc_netdev(sizeof(struct teql_master), "teql%d",
479 NET_NAME_UNKNOWN, teql_master_setup);
480 if (!dev) {
481 err = -ENOMEM;
482 break;
485 if ((err = register_netdev(dev))) {
486 free_netdev(dev);
487 break;
490 master = netdev_priv(dev);
492 strlcpy(master->qops.id, dev->name, IFNAMSIZ);
493 err = register_qdisc(&master->qops);
495 if (err) {
496 unregister_netdev(dev);
497 free_netdev(dev);
498 break;
501 list_add_tail(&master->master_list, &master_dev_list);
503 return i ? 0 : err;
506 static void __exit teql_exit(void)
508 struct teql_master *master, *nxt;
510 list_for_each_entry_safe(master, nxt, &master_dev_list, master_list) {
512 list_del(&master->master_list);
514 unregister_qdisc(&master->qops);
515 unregister_netdev(master->dev);
516 free_netdev(master->dev);
520 module_init(teql_init);
521 module_exit(teql_exit);
523 MODULE_LICENSE("GPL");