summaryrefslogtreecommitdiffstats
path: root/net/core/pktgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r--net/core/pktgen.c302
1 files changed, 148 insertions, 154 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 74a9a32b906d..b92a322872a8 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -129,6 +129,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
+#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/list.h>
@@ -163,14 +164,11 @@
#define VERSION "pktgen v2.68: Packet Generator for packet performance testing.\n"
-/* #define PG_DEBUG(a) a */
-#define PG_DEBUG(a)
-
/* The buckets are exponential in 'width' */
#define LAT_BUCKETS_MAX 32
#define IP_NAME_SZ 32
#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
-#define MPLS_STACK_BOTTOM __constant_htonl(0x00000100)
+#define MPLS_STACK_BOTTOM htonl(0x00000100)
/* Device flag bits */
#define F_IPSRC_RND (1<<0) /* IP-Src Random */
@@ -213,15 +211,11 @@ struct flow_state {
};
struct pktgen_dev {
-
/*
* Try to keep frequent/infrequent used vars. separated.
*/
-
- char ifname[IFNAMSIZ];
- char result[512];
-
- struct pktgen_thread *pg_thread; /* the owner */
+ struct proc_dir_entry *entry; /* proc file */
+ struct pktgen_thread *pg_thread;/* the owner */
struct list_head list; /* Used for chaining in the thread's run-queue */
int running; /* if this changes to false, the test will stop */
@@ -348,6 +342,8 @@ struct pktgen_dev {
unsigned cflows; /* Concurrent flows (config) */
unsigned lflow; /* Flow length (config) */
unsigned nflows; /* accumulated flows (stats) */
+
+ char result[512];
};
struct pktgen_hdr {
@@ -467,17 +463,6 @@ static inline __u64 pg_div64(__u64 n, __u64 base)
return tmp;
}
-static inline u32 pktgen_random(void)
-{
-#if 0
- __u32 n;
- get_random_bytes(&n, 4);
- return n;
-#else
- return net_random();
-#endif
-}
-
static inline __u64 getCurMs(void)
{
struct timeval tv;
@@ -511,7 +496,7 @@ static void pktgen_stop_all_threads_ifs(void);
static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
static void pktgen_stop(struct pktgen_thread *t);
static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
-static int pktgen_mark_device(const char *ifname);
+
static unsigned int scan_ip6(const char *s, char ip[16]);
static unsigned int fmt_ip6(char *s, const char ip[16]);
@@ -605,7 +590,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
" frags: %d delay: %u clone_skb: %d ifname: %s\n",
pkt_dev->nfrags,
1000 * pkt_dev->delay_us + pkt_dev->delay_ns,
- pkt_dev->clone_skb, pkt_dev->ifname);
+ pkt_dev->clone_skb, pkt_dev->odev->name);
seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows,
pkt_dev->lflow);
@@ -660,7 +645,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
if (pkt_dev->nr_labels) {
unsigned i;
seq_printf(seq, " mpls: ");
- for(i = 0; i < pkt_dev->nr_labels; i++)
+ for (i = 0; i < pkt_dev->nr_labels; i++)
seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
i == pkt_dev->nr_labels-1 ? "\n" : ", ");
}
@@ -765,7 +750,7 @@ static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32
int i = 0;
*num = 0;
- for(; i < maxlen; i++) {
+ for (; i < maxlen; i++) {
char c;
*num <<= 4;
if (get_user(c, &user_buffer[i]))
@@ -801,7 +786,7 @@ static int count_trail_chars(const char __user * user_buffer,
break;
default:
goto done;
- };
+ }
}
done:
return i;
@@ -844,7 +829,7 @@ static int strn_len(const char __user * user_buffer, unsigned int maxlen)
break;
default:
break;
- };
+ }
}
done_str:
return i;
@@ -873,7 +858,7 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
n++;
if (n >= MAX_MPLS_LABELS)
return -E2BIG;
- } while(c == ',');
+ } while (c == ',');
pkt_dev->nr_labels = n;
return i;
@@ -1502,7 +1487,7 @@ static ssize_t pktgen_if_write(struct file *file,
if (len < 0) { return len; }
i += len;
offset = sprintf(pg_result, "OK: mpls=");
- for(n = 0; n < pkt_dev->nr_labels; n++)
+ for (n = 0; n < pkt_dev->nr_labels; n++)
offset += sprintf(pg_result + offset,
"%08x%s", ntohl(pkt_dev->labels[n]),
n == pkt_dev->nr_labels-1 ? "" : ",");
@@ -1696,13 +1681,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
if_lock(t);
list_for_each_entry(pkt_dev, &t->if_list, list)
if (pkt_dev->running)
- seq_printf(seq, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->odev->name);
seq_printf(seq, "\nStopped: ");
list_for_each_entry(pkt_dev, &t->if_list, list)
if (!pkt_dev->running)
- seq_printf(seq, "%s ", pkt_dev->ifname);
+ seq_printf(seq, "%s ", pkt_dev->odev->name);
if (t->result[0])
seq_printf(seq, "\nResult: %s\n", t->result);
@@ -1848,16 +1833,14 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
/*
* mark a device for removal
*/
-static int pktgen_mark_device(const char *ifname)
+static void pktgen_mark_device(const char *ifname)
{
struct pktgen_dev *pkt_dev = NULL;
const int max_tries = 10, msec_per_try = 125;
int i = 0;
- int ret = 0;
mutex_lock(&pktgen_thread_lock);
- PG_DEBUG(printk("pktgen: pktgen_mark_device marking %s for removal\n",
- ifname));
+ pr_debug("pktgen: pktgen_mark_device marking %s for removal\n", ifname);
while (1) {
@@ -1866,8 +1849,8 @@ static int pktgen_mark_device(const char *ifname)
break; /* success */
mutex_unlock(&pktgen_thread_lock);
- PG_DEBUG(printk("pktgen: pktgen_mark_device waiting for %s "
- "to disappear....\n", ifname));
+ pr_debug("pktgen: pktgen_mark_device waiting for %s "
+ "to disappear....\n", ifname);
schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try));
mutex_lock(&pktgen_thread_lock);
@@ -1875,79 +1858,91 @@ static int pktgen_mark_device(const char *ifname)
printk("pktgen_mark_device: timed out after waiting "
"%d msec for device %s to be removed\n",
msec_per_try * i, ifname);
- ret = 1;
break;
}
}
mutex_unlock(&pktgen_thread_lock);
+}
- return ret;
+static void pktgen_change_name(struct net_device *dev)
+{
+ struct pktgen_thread *t;
+
+ list_for_each_entry(t, &pktgen_threads, th_list) {
+ struct pktgen_dev *pkt_dev;
+
+ list_for_each_entry(pkt_dev, &t->if_list, list) {
+ if (pkt_dev->odev != dev)
+ continue;
+
+ remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
+
+ pkt_dev->entry = create_proc_entry(dev->name, 0600,
+ pg_proc_dir);
+ if (!pkt_dev->entry)
+ printk(KERN_ERR "pktgen: can't move proc "
+ " entry for '%s'\n", dev->name);
+ break;
+ }
+ }
}
static int pktgen_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
- struct net_device *dev = (struct net_device *)(ptr);
+ struct net_device *dev = ptr;
/* It is OK that we do not hold the group lock right now,
* as we run under the RTNL lock.
*/
switch (event) {
- case NETDEV_CHANGEADDR:
- case NETDEV_GOING_DOWN:
- case NETDEV_DOWN:
- case NETDEV_UP:
- /* Ignore for now */
+ case NETDEV_CHANGENAME:
+ pktgen_change_name(dev);
break;
case NETDEV_UNREGISTER:
pktgen_mark_device(dev->name);
break;
- };
+ }
return NOTIFY_DONE;
}
/* Associate pktgen_dev with a device. */
-static struct net_device *pktgen_setup_dev(struct pktgen_dev *pkt_dev)
+static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
{
struct net_device *odev;
+ int err;
/* Clean old setups */
-
if (pkt_dev->odev) {
dev_put(pkt_dev->odev);
pkt_dev->odev = NULL;
}
- odev = dev_get_by_name(pkt_dev->ifname);
-
+ odev = dev_get_by_name(ifname);
if (!odev) {
- printk("pktgen: no such netdevice: \"%s\"\n", pkt_dev->ifname);
- goto out;
+ printk("pktgen: no such netdevice: \"%s\"\n", ifname);
+ return -ENODEV;
}
+
if (odev->type != ARPHRD_ETHER) {
- printk("pktgen: not an ethernet device: \"%s\"\n",
- pkt_dev->ifname);
- goto out_put;
- }
- if (!netif_running(odev)) {
- printk("pktgen: device is down: \"%s\"\n", pkt_dev->ifname);
- goto out_put;
+ printk("pktgen: not an ethernet device: \"%s\"\n", ifname);
+ err = -EINVAL;
+ } else if (!netif_running(odev)) {
+ printk("pktgen: device is down: \"%s\"\n", ifname);
+ err = -ENETDOWN;
+ } else {
+ pkt_dev->odev = odev;
+ return 0;
}
- pkt_dev->odev = odev;
-
- return pkt_dev->odev;
-out_put:
dev_put(odev);
-out:
- return NULL;
-
+ return err;
}
/* Read pkt_dev from the interface and set up internal pktgen_dev
@@ -1955,10 +1950,6 @@ out:
*/
static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
{
- /* Try once more, just in case it works now. */
- if (!pkt_dev->odev)
- pktgen_setup_dev(pkt_dev);
-
if (!pkt_dev->odev) {
printk("pktgen: ERROR: pkt_dev->odev == NULL in setup_inject.\n");
sprintf(pkt_dev->result,
@@ -2095,7 +2086,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
int flow = 0;
if (pkt_dev->cflows) {
- flow = pktgen_random() % pkt_dev->cflows;
+ flow = random32() % pkt_dev->cflows;
if (pkt_dev->flows[flow].count > pkt_dev->lflow)
pkt_dev->flows[flow].count = 0;
@@ -2107,7 +2098,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
__u32 tmp;
if (pkt_dev->flags & F_MACSRC_RND)
- mc = pktgen_random() % (pkt_dev->src_mac_count);
+ mc = random32() % pkt_dev->src_mac_count;
else {
mc = pkt_dev->cur_src_mac_offset++;
if (pkt_dev->cur_src_mac_offset >
@@ -2133,7 +2124,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
__u32 tmp;
if (pkt_dev->flags & F_MACDST_RND)
- mc = pktgen_random() % (pkt_dev->dst_mac_count);
+ mc = random32() % pkt_dev->dst_mac_count;
else {
mc = pkt_dev->cur_dst_mac_offset++;
@@ -2157,27 +2148,26 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
if (pkt_dev->flags & F_MPLS_RND) {
unsigned i;
- for(i = 0; i < pkt_dev->nr_labels; i++)
+ for (i = 0; i < pkt_dev->nr_labels; i++)
if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM)
pkt_dev->labels[i] = MPLS_STACK_BOTTOM |
- ((__force __be32)pktgen_random() &
+ ((__force __be32)random32() &
htonl(0x000fffff));
}
if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) {
- pkt_dev->vlan_id = pktgen_random() % 4096;
+ pkt_dev->vlan_id = random32() & (4096-1);
}
if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) {
- pkt_dev->svlan_id = pktgen_random() % 4096;
+ pkt_dev->svlan_id = random32() & (4096 - 1);
}
if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
if (pkt_dev->flags & F_UDPSRC_RND)
- pkt_dev->cur_udp_src =
- ((pktgen_random() %
- (pkt_dev->udp_src_max - pkt_dev->udp_src_min)) +
- pkt_dev->udp_src_min);
+ pkt_dev->cur_udp_src = random32() %
+ (pkt_dev->udp_src_max - pkt_dev->udp_src_min)
+ + pkt_dev->udp_src_min;
else {
pkt_dev->cur_udp_src++;
@@ -2188,10 +2178,9 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) {
if (pkt_dev->flags & F_UDPDST_RND) {
- pkt_dev->cur_udp_dst =
- ((pktgen_random() %
- (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min)) +
- pkt_dev->udp_dst_min);
+ pkt_dev->cur_udp_dst = random32() %
+ (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min)
+ + pkt_dev->udp_dst_min;
} else {
pkt_dev->cur_udp_dst++;
if (pkt_dev->cur_udp_dst >= pkt_dev->udp_dst_max)
@@ -2206,7 +2195,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
saddr_max))) {
__u32 t;
if (pkt_dev->flags & F_IPSRC_RND)
- t = ((pktgen_random() % (imx - imn)) + imn);
+ t = random32() % (imx - imn) + imn;
else {
t = ntohl(pkt_dev->cur_saddr);
t++;
@@ -2227,14 +2216,13 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
__be32 s;
if (pkt_dev->flags & F_IPDST_RND) {
- t = pktgen_random() % (imx - imn) + imn;
+ t = random32() % (imx - imn) + imn;
s = htonl(t);
while (LOOPBACK(s) || MULTICAST(s)
|| BADCLASS(s) || ZERONET(s)
|| LOCAL_MCAST(s)) {
- t = (pktgen_random() %
- (imx - imn)) + imn;
+ t = random32() % (imx - imn) + imn;
s = htonl(t);
}
pkt_dev->cur_daddr = s;
@@ -2266,7 +2254,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
for (i = 0; i < 4; i++) {
pkt_dev->cur_in6_daddr.s6_addr32[i] =
- (((__force __be32)pktgen_random() |
+ (((__force __be32)random32() |
pkt_dev->min_in6_daddr.s6_addr32[i]) &
pkt_dev->max_in6_daddr.s6_addr32[i]);
}
@@ -2276,9 +2264,9 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) {
__u32 t;
if (pkt_dev->flags & F_TXSIZE_RND) {
- t = ((pktgen_random() %
- (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size))
- + pkt_dev->min_pkt_size);
+ t = random32() %
+ (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size)
+ + pkt_dev->min_pkt_size;
} else {
t = pkt_dev->cur_pkt_size + 1;
if (t > pkt_dev->max_pkt_size)
@@ -2293,7 +2281,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
{
unsigned i;
- for(i = 0; i < pkt_dev->nr_labels; i++) {
+ for (i = 0; i < pkt_dev->nr_labels; i++) {
*mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM;
}
mpls--;
@@ -2315,7 +2303,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
int datalen, iplen;
struct iphdr *iph;
struct pktgen_hdr *pgh = NULL;
- __be16 protocol = __constant_htons(ETH_P_IP);
+ __be16 protocol = htons(ETH_P_IP);
__be32 *mpls;
__be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
@@ -2324,10 +2312,10 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
if (pkt_dev->nr_labels)
- protocol = __constant_htons(ETH_P_MPLS_UC);
+ protocol = htons(ETH_P_MPLS_UC);
if (pkt_dev->vlan_id != 0xffff)
- protocol = __constant_htons(ETH_P_8021Q);
+ protocol = htons(ETH_P_8021Q);
/* Update any of the values, used when we're incrementing various
* fields.
@@ -2353,24 +2341,28 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
mpls_push(mpls, pkt_dev);
if (pkt_dev->vlan_id != 0xffff) {
- if(pkt_dev->svlan_id != 0xffff) {
+ if (pkt_dev->svlan_id != 0xffff) {
svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
*svlan_tci = build_tci(pkt_dev->svlan_id,
pkt_dev->svlan_cfi,
pkt_dev->svlan_p);
svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
- *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+ *svlan_encapsulated_proto = htons(ETH_P_8021Q);
}
vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
*vlan_tci = build_tci(pkt_dev->vlan_id,
pkt_dev->vlan_cfi,
pkt_dev->vlan_p);
vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
- *vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
+ *vlan_encapsulated_proto = htons(ETH_P_IP);
}
- iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
- udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+ skb->network_header = skb->tail;
+ skb->transport_header = skb->network_header + sizeof(struct iphdr);
+ skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
+
+ iph = ip_hdr(skb);
+ udph = udp_hdr(skb);
memcpy(eth, pkt_dev->hh, 12);
*(__be16 *) & eth[12] = protocol;
@@ -2399,12 +2391,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
iph->check = 0;
iph->check = ip_fast_csum((void *)iph, iph->ihl);
skb->protocol = protocol;
- skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
- VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+ skb->mac_header = (skb->network_header - ETH_HLEN -
+ pkt_dev->nr_labels * sizeof(u32) -
+ VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
- skb->nh.iph = iph;
- skb->h.uh = udph;
if (pkt_dev->nfrags <= 0)
pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
@@ -2653,7 +2644,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
int datalen;
struct ipv6hdr *iph;
struct pktgen_hdr *pgh = NULL;
- __be16 protocol = __constant_htons(ETH_P_IPV6);
+ __be16 protocol = htons(ETH_P_IPV6);
__be32 *mpls;
__be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
@@ -2661,10 +2652,10 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
if (pkt_dev->nr_labels)
- protocol = __constant_htons(ETH_P_MPLS_UC);
+ protocol = htons(ETH_P_MPLS_UC);
if (pkt_dev->vlan_id != 0xffff)
- protocol = __constant_htons(ETH_P_8021Q);
+ protocol = htons(ETH_P_8021Q);
/* Update any of the values, used when we're incrementing various
* fields.
@@ -2689,24 +2680,28 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
mpls_push(mpls, pkt_dev);
if (pkt_dev->vlan_id != 0xffff) {
- if(pkt_dev->svlan_id != 0xffff) {
+ if (pkt_dev->svlan_id != 0xffff) {
svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
*svlan_tci = build_tci(pkt_dev->svlan_id,
pkt_dev->svlan_cfi,
pkt_dev->svlan_p);
svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
- *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
+ *svlan_encapsulated_proto = htons(ETH_P_8021Q);
}
vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
*vlan_tci = build_tci(pkt_dev->vlan_id,
pkt_dev->vlan_cfi,
pkt_dev->vlan_p);
vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
- *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
+ *vlan_encapsulated_proto = htons(ETH_P_IPV6);
}
- iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
- udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+ skb->network_header = skb->tail;
+ skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
+ skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
+
+ iph = ipv6_hdr(skb);
+ udph = udp_hdr(skb);
memcpy(eth, pkt_dev->hh, 12);
*(__be16 *) & eth[12] = protocol;
@@ -2728,7 +2723,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
udph->len = htons(datalen + sizeof(struct udphdr));
udph->check = 0; /* No checksum */
- *(__be32 *) iph = __constant_htonl(0x60000000); /* Version + flow */
+ *(__be32 *) iph = htonl(0x60000000); /* Version + flow */
if (pkt_dev->traffic_class) {
/* Version + traffic class + flow (0) */
@@ -2743,13 +2738,12 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
- skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
- VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+ skb->mac_header = (skb->network_header - ETH_HLEN -
+ pkt_dev->nr_labels * sizeof(u32) -
+ VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
skb->protocol = protocol;
skb->dev = odev;
skb->pkt_type = PACKET_HOST;
- skb->nh.ipv6h = iph;
- skb->h.uh = udph;
if (pkt_dev->nfrags <= 0)
pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
@@ -2847,7 +2841,7 @@ static void pktgen_run(struct pktgen_thread *t)
struct pktgen_dev *pkt_dev;
int started = 0;
- PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
+ pr_debug("pktgen: entering pktgen_run. %p\n", t);
if_lock(t);
list_for_each_entry(pkt_dev, &t->if_list, list) {
@@ -2879,7 +2873,7 @@ static void pktgen_stop_all_threads_ifs(void)
{
struct pktgen_thread *t;
- PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n"));
+ pr_debug("pktgen: entering pktgen_stop_all_threads_ifs.\n");
mutex_lock(&pktgen_thread_lock);
@@ -2947,7 +2941,7 @@ static void pktgen_run_all_threads(void)
{
struct pktgen_thread *t;
- PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
+ pr_debug("pktgen: entering pktgen_run_all_threads.\n");
mutex_lock(&pktgen_thread_lock);
@@ -3005,7 +2999,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
if (!pkt_dev->running) {
printk("pktgen: interface: %s is already stopped\n",
- pkt_dev->ifname);
+ pkt_dev->odev->name);
return -EINVAL;
}
@@ -3039,7 +3033,7 @@ static void pktgen_stop(struct pktgen_thread *t)
{
struct pktgen_dev *pkt_dev;
- PG_DEBUG(printk("pktgen: entering pktgen_stop\n"));
+ pr_debug("pktgen: entering pktgen_stop\n");
if_lock(t);
@@ -3063,7 +3057,7 @@ static void pktgen_rem_one_if(struct pktgen_thread *t)
struct list_head *q, *n;
struct pktgen_dev *cur;
- PG_DEBUG(printk("pktgen: entering pktgen_rem_one_if\n"));
+ pr_debug("pktgen: entering pktgen_rem_one_if\n");
if_lock(t);
@@ -3092,7 +3086,7 @@ static void pktgen_rem_all_ifs(struct pktgen_thread *t)
/* Remove all devices, free mem */
- PG_DEBUG(printk("pktgen: entering pktgen_rem_all_ifs\n"));
+ pr_debug("pktgen: entering pktgen_rem_all_ifs\n");
if_lock(t);
list_for_each_safe(q, n, &t->if_list) {
@@ -3275,7 +3269,7 @@ static int pktgen_thread_worker(void *arg)
t->pid = current->pid;
- PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid));
+ pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid);
max_before_softirq = t->max_before_softirq;
@@ -3333,16 +3327,18 @@ static int pktgen_thread_worker(void *arg)
t->control &= ~(T_REMDEV);
}
+ try_to_freeze();
+
set_current_state(TASK_INTERRUPTIBLE);
}
- PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm));
+ pr_debug("pktgen: %s stopping all device\n", t->tsk->comm);
pktgen_stop(t);
- PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm));
+ pr_debug("pktgen: %s removing all device\n", t->tsk->comm);
pktgen_rem_all_ifs(t);
- PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm));
+ pr_debug("pktgen: %s removing thread.\n", t->tsk->comm);
pktgen_rem_thread(t);
return 0;
@@ -3355,13 +3351,13 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
if_lock(t);
list_for_each_entry(p, &t->if_list, list)
- if (strncmp(p->ifname, ifname, IFNAMSIZ) == 0) {
+ if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) {
pkt_dev = p;
break;
}
if_unlock(t);
- PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev));
+ pr_debug("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev);
return pkt_dev;
}
@@ -3396,7 +3392,7 @@ out:
static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
{
struct pktgen_dev *pkt_dev;
- struct proc_dir_entry *pe;
+ int err;
/* We don't allow a device to be on several threads */
@@ -3438,29 +3434,28 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
pkt_dev->svlan_cfi = 0;
pkt_dev->svlan_id = 0xffff;
- strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
+ err = pktgen_setup_dev(pkt_dev, ifname);
+ if (err)
+ goto out1;
- if (!pktgen_setup_dev(pkt_dev)) {
- printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -ENODEV;
- }
-
- pe = create_proc_entry(ifname, 0600, pg_proc_dir);
- if (!pe) {
+ pkt_dev->entry = create_proc_entry(ifname, 0600, pg_proc_dir);
+ if (!pkt_dev->entry) {
printk("pktgen: cannot create %s/%s procfs entry.\n",
PG_PROC_DIR, ifname);
- if (pkt_dev->flows)
- vfree(pkt_dev->flows);
- kfree(pkt_dev);
- return -EINVAL;
+ err = -EINVAL;
+ goto out2;
}
- pe->proc_fops = &pktgen_if_fops;
- pe->data = pkt_dev;
+ pkt_dev->entry->proc_fops = &pktgen_if_fops;
+ pkt_dev->entry->data = pkt_dev;
return add_dev_to_thread(t, pkt_dev);
+out2:
+ dev_put(pkt_dev->odev);
+out1:
+ if (pkt_dev->flows)
+ vfree(pkt_dev->flows);
+ kfree(pkt_dev);
+ return err;
}
static int __init pktgen_create_thread(int cpu)
@@ -3530,7 +3525,7 @@ static int pktgen_remove_device(struct pktgen_thread *t,
struct pktgen_dev *pkt_dev)
{
- PG_DEBUG(printk("pktgen: remove_device pkt_dev=%p\n", pkt_dev));
+ pr_debug("pktgen: remove_device pkt_dev=%p\n", pkt_dev);
if (pkt_dev->running) {
printk("pktgen:WARNING: trying to remove a running interface, stopping it now.\n");
@@ -3548,9 +3543,8 @@ static int pktgen_remove_device(struct pktgen_thread *t,
_rem_dev_from_if_list(t, pkt_dev);
- /* Clean up proc file system */
-
- remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
+ if (pkt_dev->entry)
+ remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
if (pkt_dev->flows)
vfree(pkt_dev->flows);