These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / ifb.c
1 /* drivers/net/ifb.c:
2
3         The purpose of this driver is to provide a device that allows
4         for sharing of resources:
5
6         1) qdiscs/policies that are per device as opposed to system wide.
7         ifb allows for a device which can be redirected to thus providing
8         an impression of sharing.
9
10         2) Allows for queueing incoming traffic for shaping instead of
11         dropping.
12
13         The original concept is based on what is known as the IMQ
14         driver initially written by Martin Devera, later rewritten
15         by Patrick McHardy and then maintained by Andre Correa.
16
17         You need the tc action  mirror or redirect to feed this device
18         packets.
19
20         This program is free software; you can redistribute it and/or
21         modify it under the terms of the GNU General Public License
22         as published by the Free Software Foundation; either version
23         2 of the License, or (at your option) any later version.
24
25         Authors:        Jamal Hadi Salim (2005)
26
27 */
28
29
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/netdevice.h>
33 #include <linux/etherdevice.h>
34 #include <linux/init.h>
35 #include <linux/interrupt.h>
36 #include <linux/moduleparam.h>
37 #include <net/pkt_sched.h>
38 #include <net/net_namespace.h>
39
40 #define TX_Q_LIMIT    32
41 struct ifb_q_private {
42         struct net_device       *dev;
43         struct tasklet_struct   ifb_tasklet;
44         int                     tasklet_pending;
45         int                     txqnum;
46         struct sk_buff_head     rq;
47         u64                     rx_packets;
48         u64                     rx_bytes;
49         struct u64_stats_sync   rsync;
50
51         struct u64_stats_sync   tsync;
52         u64                     tx_packets;
53         u64                     tx_bytes;
54         struct sk_buff_head     tq;
55 } ____cacheline_aligned_in_smp;
56
57 struct ifb_dev_private {
58         struct ifb_q_private *tx_private;
59 };
60
61 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev);
62 static int ifb_open(struct net_device *dev);
63 static int ifb_close(struct net_device *dev);
64
65 static void ifb_ri_tasklet(unsigned long _txp)
66 {
67         struct ifb_q_private *txp = (struct ifb_q_private *)_txp;
68         struct netdev_queue *txq;
69         struct sk_buff *skb;
70
71         txq = netdev_get_tx_queue(txp->dev, txp->txqnum);
72         skb = skb_peek(&txp->tq);
73         if (!skb) {
74                 if (!__netif_tx_trylock(txq))
75                         goto resched;
76                 skb_queue_splice_tail_init(&txp->rq, &txp->tq);
77                 __netif_tx_unlock(txq);
78         }
79
80         while ((skb = __skb_dequeue(&txp->tq)) != NULL) {
81                 u32 from = G_TC_FROM(skb->tc_verd);
82
83                 skb->tc_verd = 0;
84                 skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
85
86                 u64_stats_update_begin(&txp->tsync);
87                 txp->tx_packets++;
88                 txp->tx_bytes += skb->len;
89                 u64_stats_update_end(&txp->tsync);
90
91                 rcu_read_lock();
92                 skb->dev = dev_get_by_index_rcu(dev_net(txp->dev), skb->skb_iif);
93                 if (!skb->dev) {
94                         rcu_read_unlock();
95                         dev_kfree_skb(skb);
96                         txp->dev->stats.tx_dropped++;
97                         if (skb_queue_len(&txp->tq) != 0)
98                                 goto resched;
99                         break;
100                 }
101                 rcu_read_unlock();
102                 skb->skb_iif = txp->dev->ifindex;
103
104                 if (from & AT_EGRESS) {
105                         dev_queue_xmit(skb);
106                 } else if (from & AT_INGRESS) {
107                         skb_pull(skb, skb->mac_len);
108                         netif_receive_skb(skb);
109                 } else
110                         BUG();
111         }
112
113         if (__netif_tx_trylock(txq)) {
114                 skb = skb_peek(&txp->rq);
115                 if (!skb) {
116                         txp->tasklet_pending = 0;
117                         if (netif_tx_queue_stopped(txq))
118                                 netif_tx_wake_queue(txq);
119                 } else {
120                         __netif_tx_unlock(txq);
121                         goto resched;
122                 }
123                 __netif_tx_unlock(txq);
124         } else {
125 resched:
126                 txp->tasklet_pending = 1;
127                 tasklet_schedule(&txp->ifb_tasklet);
128         }
129
130 }
131
132 static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev,
133                                              struct rtnl_link_stats64 *stats)
134 {
135         struct ifb_dev_private *dp = netdev_priv(dev);
136         struct ifb_q_private *txp = dp->tx_private;
137         unsigned int start;
138         u64 packets, bytes;
139         int i;
140
141         for (i = 0; i < dev->num_tx_queues; i++,txp++) {
142                 do {
143                         start = u64_stats_fetch_begin_irq(&txp->rsync);
144                         packets = txp->rx_packets;
145                         bytes = txp->rx_bytes;
146                 } while (u64_stats_fetch_retry_irq(&txp->rsync, start));
147                 stats->rx_packets += packets;
148                 stats->rx_bytes += bytes;
149
150                 do {
151                         start = u64_stats_fetch_begin_irq(&txp->tsync);
152                         packets = txp->tx_packets;
153                         bytes = txp->tx_bytes;
154                 } while (u64_stats_fetch_retry_irq(&txp->tsync, start));
155                 stats->tx_packets += packets;
156                 stats->tx_bytes += bytes;
157         }
158         stats->rx_dropped = dev->stats.rx_dropped;
159         stats->tx_dropped = dev->stats.tx_dropped;
160
161         return stats;
162 }
163
164 static int ifb_dev_init(struct net_device *dev)
165 {
166         struct ifb_dev_private *dp = netdev_priv(dev);
167         struct ifb_q_private *txp;
168         int i;
169
170         txp = kcalloc(dev->num_tx_queues, sizeof(*txp), GFP_KERNEL);
171         if (!txp)
172                 return -ENOMEM;
173         dp->tx_private = txp;
174         for (i = 0; i < dev->num_tx_queues; i++,txp++) {
175                 txp->txqnum = i;
176                 txp->dev = dev;
177                 __skb_queue_head_init(&txp->rq);
178                 __skb_queue_head_init(&txp->tq);
179                 u64_stats_init(&txp->rsync);
180                 u64_stats_init(&txp->tsync);
181                 tasklet_init(&txp->ifb_tasklet, ifb_ri_tasklet,
182                              (unsigned long)txp);
183                 netif_tx_start_queue(netdev_get_tx_queue(dev, i));
184         }
185         return 0;
186 }
187
188 static const struct net_device_ops ifb_netdev_ops = {
189         .ndo_open       = ifb_open,
190         .ndo_stop       = ifb_close,
191         .ndo_get_stats64 = ifb_stats64,
192         .ndo_start_xmit = ifb_xmit,
193         .ndo_validate_addr = eth_validate_addr,
194         .ndo_init       = ifb_dev_init,
195 };
196
197 #define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG  | NETIF_F_FRAGLIST  | \
198                       NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6      | \
199                       NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX         | \
200                       NETIF_F_HW_VLAN_STAG_TX)
201
202 static void ifb_dev_free(struct net_device *dev)
203 {
204         struct ifb_dev_private *dp = netdev_priv(dev);
205         struct ifb_q_private *txp = dp->tx_private;
206         int i;
207
208         for (i = 0; i < dev->num_tx_queues; i++,txp++) {
209                 tasklet_kill(&txp->ifb_tasklet);
210                 __skb_queue_purge(&txp->rq);
211                 __skb_queue_purge(&txp->tq);
212         }
213         kfree(dp->tx_private);
214         free_netdev(dev);
215 }
216
217 static void ifb_setup(struct net_device *dev)
218 {
219         /* Initialize the device structure. */
220         dev->netdev_ops = &ifb_netdev_ops;
221
222         /* Fill in device structure with ethernet-generic values. */
223         ether_setup(dev);
224         dev->tx_queue_len = TX_Q_LIMIT;
225
226         dev->features |= IFB_FEATURES;
227         dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
228                                                NETIF_F_HW_VLAN_STAG_TX);
229
230         dev->flags |= IFF_NOARP;
231         dev->flags &= ~IFF_MULTICAST;
232         dev->priv_flags &= ~IFF_TX_SKB_SHARING;
233         netif_keep_dst(dev);
234         eth_hw_addr_random(dev);
235         dev->destructor = ifb_dev_free;
236 }
237
238 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
239 {
240         struct ifb_dev_private *dp = netdev_priv(dev);
241         u32 from = G_TC_FROM(skb->tc_verd);
242         struct ifb_q_private *txp = dp->tx_private + skb_get_queue_mapping(skb);
243
244         u64_stats_update_begin(&txp->rsync);
245         txp->rx_packets++;
246         txp->rx_bytes += skb->len;
247         u64_stats_update_end(&txp->rsync);
248
249         if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->skb_iif) {
250                 dev_kfree_skb(skb);
251                 dev->stats.rx_dropped++;
252                 return NETDEV_TX_OK;
253         }
254
255         if (skb_queue_len(&txp->rq) >= dev->tx_queue_len)
256                 netif_tx_stop_queue(netdev_get_tx_queue(dev, txp->txqnum));
257
258         __skb_queue_tail(&txp->rq, skb);
259         if (!txp->tasklet_pending) {
260                 txp->tasklet_pending = 1;
261                 tasklet_schedule(&txp->ifb_tasklet);
262         }
263
264         return NETDEV_TX_OK;
265 }
266
267 static int ifb_close(struct net_device *dev)
268 {
269         netif_tx_stop_all_queues(dev);
270         return 0;
271 }
272
273 static int ifb_open(struct net_device *dev)
274 {
275         netif_tx_start_all_queues(dev);
276         return 0;
277 }
278
279 static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
280 {
281         if (tb[IFLA_ADDRESS]) {
282                 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
283                         return -EINVAL;
284                 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
285                         return -EADDRNOTAVAIL;
286         }
287         return 0;
288 }
289
290 static struct rtnl_link_ops ifb_link_ops __read_mostly = {
291         .kind           = "ifb",
292         .priv_size      = sizeof(struct ifb_dev_private),
293         .setup          = ifb_setup,
294         .validate       = ifb_validate,
295 };
296
297 /* Number of ifb devices to be set up by this module.
298  * Note that these legacy devices have one queue.
299  * Prefer something like : ip link add ifb10 numtxqueues 8 type ifb
300  */
301 static int numifbs = 2;
302 module_param(numifbs, int, 0);
303 MODULE_PARM_DESC(numifbs, "Number of ifb devices");
304
305 static int __init ifb_init_one(int index)
306 {
307         struct net_device *dev_ifb;
308         int err;
309
310         dev_ifb = alloc_netdev(sizeof(struct ifb_dev_private), "ifb%d",
311                                NET_NAME_UNKNOWN, ifb_setup);
312
313         if (!dev_ifb)
314                 return -ENOMEM;
315
316         dev_ifb->rtnl_link_ops = &ifb_link_ops;
317         err = register_netdevice(dev_ifb);
318         if (err < 0)
319                 goto err;
320
321         return 0;
322
323 err:
324         free_netdev(dev_ifb);
325         return err;
326 }
327
328 static int __init ifb_init_module(void)
329 {
330         int i, err;
331
332         rtnl_lock();
333         err = __rtnl_link_register(&ifb_link_ops);
334         if (err < 0)
335                 goto out;
336
337         for (i = 0; i < numifbs && !err; i++) {
338                 err = ifb_init_one(i);
339                 cond_resched();
340         }
341         if (err)
342                 __rtnl_link_unregister(&ifb_link_ops);
343
344 out:
345         rtnl_unlock();
346
347         return err;
348 }
349
350 static void __exit ifb_cleanup_module(void)
351 {
352         rtnl_link_unregister(&ifb_link_ops);
353 }
354
355 module_init(ifb_init_module);
356 module_exit(ifb_cleanup_module);
357 MODULE_LICENSE("GPL");
358 MODULE_AUTHOR("Jamal Hadi Salim");
359 MODULE_ALIAS_RTNL_LINK("ifb");