]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/core/dev.c
net: Fix Tx hash bound checking
[linux.git] / net / core / dev.c
index a69e8bd7ed74f1c8c34eab5ffa792e4096761072..c6c985fe7b1bcf784cedde2b2a86e26356471bee 100644 (file)
 #include "net-sysfs.h"
 
 #define MAX_GRO_SKBS 8
-#define MAX_NEST_DEV 8
 
 /* This should be increased if a protocol with a bigger head is added. */
 #define GRO_MAX_HEAD (MAX_HEADER + 128)
@@ -331,6 +330,12 @@ int netdev_name_node_alt_destroy(struct net_device *dev, const char *name)
        name_node = netdev_name_node_lookup(net, name);
        if (!name_node)
                return -ENOENT;
+       /* lookup might have found our primary name or a name belonging
+        * to another device.
+        */
+       if (name_node == dev->name_node || name_node->dev != dev)
+               return -EINVAL;
+
        __netdev_name_node_alt_destroy(name_node);
 
        return 0;
@@ -3071,6 +3076,8 @@ static u16 skb_tx_hash(const struct net_device *dev,
 
        if (skb_rx_queue_recorded(skb)) {
                hash = skb_get_rx_queue(skb);
+               if (hash >= qoffset)
+                       hash -= qoffset;
                while (unlikely(hash >= qcount))
                        hash -= qcount;
                return hash + qoffset;
@@ -3657,26 +3664,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
        qdisc_calculate_pkt_len(skb, q);
 
        if (q->flags & TCQ_F_NOLOCK) {
-               if ((q->flags & TCQ_F_CAN_BYPASS) && READ_ONCE(q->empty) &&
-                   qdisc_run_begin(q)) {
-                       if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED,
-                                             &q->state))) {
-                               __qdisc_drop(skb, &to_free);
-                               rc = NET_XMIT_DROP;
-                               goto end_run;
-                       }
-                       qdisc_bstats_cpu_update(q, skb);
-
-                       rc = NET_XMIT_SUCCESS;
-                       if (sch_direct_xmit(skb, q, dev, txq, NULL, true))
-                               __qdisc_run(q);
-
-end_run:
-                       qdisc_run_end(q);
-               } else {
-                       rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK;
-                       qdisc_run(q);
-               }
+               rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK;
+               qdisc_run(q);
 
                if (unlikely(to_free))
                        kfree_skb_list(to_free);
@@ -4527,14 +4516,14 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
        /* Reinjected packets coming from act_mirred or similar should
         * not get XDP generic processing.
         */
-       if (skb_cloned(skb) || skb_is_tc_redirected(skb))
+       if (skb_is_tc_redirected(skb))
                return XDP_PASS;
 
        /* XDP packets must be linear and must have sufficient headroom
         * of XDP_PACKET_HEADROOM bytes. This is the guarantee that also
         * native XDP provides, thus we need to do it here as well.
         */
-       if (skb_is_nonlinear(skb) ||
+       if (skb_cloned(skb) || skb_is_nonlinear(skb) ||
            skb_headroom(skb) < XDP_PACKET_HEADROOM) {
                int hroom = XDP_PACKET_HEADROOM - skb_headroom(skb);
                int troom = skb->tail + skb->data_len - skb->end;
@@ -7201,8 +7190,8 @@ static int __netdev_walk_all_lower_dev(struct net_device *dev,
        return 0;
 }
 
-static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev,
-                                                   struct list_head **iter)
+struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev,
+                                            struct list_head **iter)
 {
        struct netdev_adjacent *lower;
 
@@ -7214,6 +7203,7 @@ static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev,
 
        return lower->dev;
 }
+EXPORT_SYMBOL(netdev_next_lower_dev_rcu);
 
 static u8 __netdev_upper_depth(struct net_device *dev)
 {