]> Pileus Git - ~andy/linux/blobdiff - net/core/dev.c
dev: introduce skb_scrub_packet()
[~andy/linux] / net / core / dev.c
index fa007dba6beb4371d2690321b4b2447f6dfd8555..370354a9c5f6926e977ce4374541bc4b6e2e5dac 100644 (file)
 #include <linux/cpu_rmap.h>
 #include <linux/static_key.h>
 #include <linux/hashtable.h>
+#include <linux/vmalloc.h>
 
 #include "net-sysfs.h"
 
@@ -1651,22 +1652,13 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
                }
        }
 
-       skb_orphan(skb);
-
        if (unlikely(!is_skb_forwardable(dev, skb))) {
                atomic_long_inc(&dev->rx_dropped);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
-       skb->skb_iif = 0;
-       skb_dst_drop(skb);
-       skb->tstamp.tv64 = 0;
-       skb->pkt_type = PACKET_HOST;
+       skb_scrub_packet(skb);
        skb->protocol = eth_type_trans(skb, dev);
-       skb->mark = 0;
-       secpath_reset(skb);
-       nf_reset(skb);
-       nf_reset_trace(skb);
        return netif_rx(skb);
 }
 EXPORT_SYMBOL_GPL(dev_forward_skb);
@@ -5253,17 +5245,28 @@ static void netdev_init_one_queue(struct net_device *dev,
 #endif
 }
 
+static void netif_free_tx_queues(struct net_device *dev)
+{
+       if (is_vmalloc_addr(dev->_tx))
+               vfree(dev->_tx);
+       else
+               kfree(dev->_tx);
+}
+
 static int netif_alloc_netdev_queues(struct net_device *dev)
 {
        unsigned int count = dev->num_tx_queues;
        struct netdev_queue *tx;
+       size_t sz = count * sizeof(*tx);
 
-       BUG_ON(count < 1);
-
-       tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL);
-       if (!tx)
-               return -ENOMEM;
+       BUG_ON(count < 1 || count > 0xffff);
 
+       tx = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
+       if (!tx) {
+               tx = vzalloc(sz);
+               if (!tx)
+                       return -ENOMEM;
+       }
        dev->_tx = tx;
 
        netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
@@ -5811,7 +5814,7 @@ free_all:
 
 free_pcpu:
        free_percpu(dev->pcpu_refcnt);
-       kfree(dev->_tx);
+       netif_free_tx_queues(dev);
 #ifdef CONFIG_RPS
        kfree(dev->_rx);
 #endif
@@ -5836,7 +5839,7 @@ void free_netdev(struct net_device *dev)
 
        release_net(dev_net(dev));
 
-       kfree(dev->_tx);
+       netif_free_tx_queues(dev);
 #ifdef CONFIG_RPS
        kfree(dev->_rx);
 #endif