]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/core/gro_cells.c
UBUNTU: Ubuntu-4.15.0-96.97
[mirror_ubuntu-bionic-kernel.git] / net / core / gro_cells.c
index 4b54e5f107c6a3a50031a6e19fb249a15086b892..e095fb871d9120787bfdf62149f4d82e0e3b0a51 100644 (file)
@@ -13,22 +13,36 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
        struct gro_cell *cell;
+       int res;
 
-       if (!gcells->cells || skb_cloned(skb) || netif_elide_gro(dev))
-               return netif_rx(skb);
+       rcu_read_lock();
+       if (unlikely(!(dev->flags & IFF_UP)))
+               goto drop;
+
+       if (!gcells->cells || skb_cloned(skb) || netif_elide_gro(dev)) {
+               res = netif_rx(skb);
+               goto unlock;
+       }
 
        cell = this_cpu_ptr(gcells->cells);
 
        if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
+drop:
                atomic_long_inc(&dev->rx_dropped);
                kfree_skb(skb);
-               return NET_RX_DROP;
+               res = NET_RX_DROP;
+               goto unlock;
        }
 
        __skb_queue_tail(&cell->napi_skbs, skb);
        if (skb_queue_len(&cell->napi_skbs) == 1)
                napi_schedule(&cell->napi);
-       return NET_RX_SUCCESS;
+
+       res = NET_RX_SUCCESS;
+
+unlock:
+       rcu_read_unlock();
+       return res;
 }
 EXPORT_SYMBOL(gro_cells_receive);
 
@@ -84,6 +98,7 @@ void gro_cells_destroy(struct gro_cells *gcells)
        for_each_possible_cpu(i) {
                struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
 
+               napi_disable(&cell->napi);
                netif_napi_del(&cell->napi);
                __skb_queue_purge(&cell->napi_skbs);
        }