]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/core/pktgen.c
pktgen: fix skb leak in case of failure
[linux-2.6-omap-h63xx.git] / net / core / pktgen.c
index 526236453908280654104886d09e26e0117aba80..99f656d35b4f5556be314cbb3ec4c732228f5709 100644 (file)
@@ -1961,6 +1961,8 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
  */
 static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 {
+       int ntxq;
+
        if (!pkt_dev->odev) {
                printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in "
                       "setup_inject.\n");
@@ -1969,6 +1971,33 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
                return;
        }
 
+       /* make sure that we don't pick a non-existing transmit queue */
+       ntxq = pkt_dev->odev->real_num_tx_queues;
+       if (ntxq <= num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) {
+               printk(KERN_WARNING "pktgen: WARNING: QUEUE_MAP_CPU "
+                      "disabled because CPU count (%d) exceeds number ",
+                      num_online_cpus());
+               printk(KERN_WARNING "pktgen: WARNING: of tx queues "
+                      "(%d) on %s \n", ntxq, pkt_dev->odev->name);
+               pkt_dev->flags &= ~F_QUEUE_MAP_CPU;
+       }
+       if (ntxq <= pkt_dev->queue_map_min) {
+               printk(KERN_WARNING "pktgen: WARNING: Requested "
+                      "queue_map_min (%d) exceeds number of tx\n",
+                      pkt_dev->queue_map_min);
+               printk(KERN_WARNING "pktgen: WARNING: queues (%d) on "
+                      "%s, resetting\n", ntxq, pkt_dev->odev->name);
+               pkt_dev->queue_map_min = ntxq - 1;
+       }
+       if (ntxq <= pkt_dev->queue_map_max) {
+               printk(KERN_WARNING "pktgen: WARNING: Requested "
+                      "queue_map_max (%d) exceeds number of tx\n",
+                      pkt_dev->queue_map_max);
+               printk(KERN_WARNING "pktgen: WARNING: queues (%d) on "
+                      "%s, resetting\n", ntxq, pkt_dev->odev->name);
+               pkt_dev->queue_map_max = ntxq - 1;
+       }
+
        /* Default to the interface's mac if not explicitly set. */
 
        if (is_zero_ether_addr(pkt_dev->src_mac))
@@ -2445,7 +2474,7 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
                                if (ret < 0) {
                                        printk(KERN_ERR "Error expanding "
                                               "ipsec packet %d\n",ret);
-                                       return 0;
+                                       goto err;
                                }
                        }
 
@@ -2455,8 +2484,7 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
                        if (ret) {
                                printk(KERN_ERR "Error creating ipsec "
                                       "packet %d\n",ret);
-                               kfree_skb(skb);
-                               return 0;
+                               goto err;
                        }
                        /* restore ll */
                        eth = (__u8 *) skb_push(skb, ETH_HLEN);
@@ -2465,6 +2493,9 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
                }
        }
        return 1;
+err:
+       kfree_skb(skb);
+       return 0;
 }
 #endif