xref: /openbmc/linux/net/core/pktgen.c (revision 12e1872328e7055d06e539f1b687dc3d0610855c)
1 /*
2  * Authors:
3  * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se>
4  *                             Uppsala University and
5  *                             Swedish University of Agricultural Sciences
6  *
7  * Alexey Kuznetsov  <kuznet@ms2.inr.ac.ru>
8  * Ben Greear <greearb@candelatech.com>
9  * Jens L��s <jens.laas@data.slu.se>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version
14  * 2 of the License, or (at your option) any later version.
15  *
16  *
17  * A tool for loading the network with preconfigurated packets.
18  * The tool is implemented as a linux module.  Parameters are output
19  * device, delay (to hard_xmit), number of packets, and whether
20  * to use multiple SKBs or just the same one.
21  * pktgen uses the installed interface's output routine.
22  *
23  * Additional hacking by:
24  *
25  * Jens.Laas@data.slu.se
26  * Improved by ANK. 010120.
27  * Improved by ANK even more. 010212.
28  * MAC address typo fixed. 010417 --ro
29  * Integrated.  020301 --DaveM
30  * Added multiskb option 020301 --DaveM
31  * Scaling of results. 020417--sigurdur@linpro.no
32  * Significant re-work of the module:
33  *   *  Convert to threaded model to more efficiently be able to transmit
34  *       and receive on multiple interfaces at once.
35  *   *  Converted many counters to __u64 to allow longer runs.
36  *   *  Allow configuration of ranges, like min/max IP address, MACs,
37  *       and UDP-ports, for both source and destination, and can
38  *       set to use a random distribution or sequentially walk the range.
39  *   *  Can now change most values after starting.
40  *   *  Place 12-byte packet in UDP payload with magic number,
41  *       sequence number, and timestamp.
42  *   *  Add receiver code that detects dropped pkts, re-ordered pkts, and
43  *       latencies (with micro-second) precision.
44  *   *  Add IOCTL interface to easily get counters & configuration.
45  *   --Ben Greear <greearb@candelatech.com>
46  *
47  * Renamed multiskb to clone_skb and cleaned up sending core for two distinct
48  * skb modes. A clone_skb=0 mode for Ben "ranges" work and a clone_skb != 0
49  * as a "fastpath" with a configurable number of clones after alloc's.
50  * clone_skb=0 means all packets are allocated this also means ranges time
51  * stamps etc can be used. clone_skb=100 means 1 malloc is followed by 100
52  * clones.
53  *
54  * Also moved to /proc/net/pktgen/
55  * --ro
56  *
57  * Sept 10:  Fixed threading/locking.  Lots of bone-headed and more clever
58  *    mistakes.  Also merged in DaveM's patch in the -pre6 patch.
59  * --Ben Greear <greearb@candelatech.com>
60  *
61  * Integrated to 2.5.x 021029 --Lucio Maciel (luciomaciel@zipmail.com.br)
62  *
63  *
64  * 021124 Finished major redesign and rewrite for new functionality.
65  * See Documentation/networking/pktgen.txt for how to use this.
66  *
67  * The new operation:
68  * For each CPU one thread/process is created at start. This process checks
69  * for running devices in the if_list and sends packets until count is 0 it
70  * also the thread checks the thread->control which is used for inter-process
71  * communication. controlling process "posts" operations to the threads this
72  * way. The if_lock should be possible to remove when add/rem_device is merged
73  * into this too.
74  *
75  * By design there should only be *one* "controlling" process. In practice
76  * multiple write accesses gives unpredictable result. Understood by "write"
77  * to /proc gives result code thats should be read be the "writer".
78  * For practical use this should be no problem.
79  *
80  * Note when adding devices to a specific CPU there good idea to also assign
81  * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
82  * --ro
83  *
84  * Fix refcount off by one if first packet fails, potential null deref,
85  * memleak 030710- KJP
86  *
87  * First "ranges" functionality for ipv6 030726 --ro
88  *
89  * Included flow support. 030802 ANK.
90  *
91  * Fixed unaligned access on IA-64 Grant Grundler <grundler@parisc-linux.org>
92  *
93  * Remove if fix from added Harald Welte <laforge@netfilter.org> 040419
94  * ia64 compilation fix from  Aron Griffis <aron@hp.com> 040604
95  *
96  * New xmit() return, do_div and misc clean up by Stephen Hemminger
97  * <shemminger@osdl.org> 040923
98  *
99  * Randy Dunlap fixed u64 printk compiler waring
100  *
101  * Remove FCS from BW calculation.  Lennert Buytenhek <buytenh@wantstofly.org>
102  * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
103  *
104  * Corrections from Nikolai Malykh (nmalykh@bilim.com)
105  * Removed unused flags F_SET_SRCMAC & F_SET_SRCIP 041230
106  *
107  * interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <nacc@us.ibm.com>
108  * 050103
109  */
110 #include <linux/sys.h>
111 #include <linux/types.h>
112 #include <linux/module.h>
113 #include <linux/moduleparam.h>
114 #include <linux/kernel.h>
115 #include <linux/smp_lock.h>
116 #include <linux/sched.h>
117 #include <linux/slab.h>
118 #include <linux/vmalloc.h>
119 #include <linux/unistd.h>
120 #include <linux/string.h>
121 #include <linux/ptrace.h>
122 #include <linux/errno.h>
123 #include <linux/ioport.h>
124 #include <linux/interrupt.h>
125 #include <linux/capability.h>
126 #include <linux/delay.h>
127 #include <linux/timer.h>
128 #include <linux/list.h>
129 #include <linux/init.h>
130 #include <linux/skbuff.h>
131 #include <linux/netdevice.h>
132 #include <linux/inet.h>
133 #include <linux/inetdevice.h>
134 #include <linux/rtnetlink.h>
135 #include <linux/if_arp.h>
136 #include <linux/in.h>
137 #include <linux/ip.h>
138 #include <linux/ipv6.h>
139 #include <linux/udp.h>
140 #include <linux/proc_fs.h>
141 #include <linux/seq_file.h>
142 #include <linux/wait.h>
143 #include <linux/etherdevice.h>
144 #include <net/checksum.h>
145 #include <net/ipv6.h>
146 #include <net/addrconf.h>
147 #include <asm/byteorder.h>
148 #include <linux/rcupdate.h>
149 #include <asm/bitops.h>
150 #include <asm/io.h>
151 #include <asm/dma.h>
152 #include <asm/uaccess.h>
153 #include <asm/div64.h>		/* do_div */
154 #include <asm/timex.h>
155 
156 #define VERSION  "pktgen v2.64: Packet Generator for packet performance testing.\n"
157 
158 /* #define PG_DEBUG(a) a */
159 #define PG_DEBUG(a)
160 
161 /* The buckets are exponential in 'width' */
162 #define LAT_BUCKETS_MAX 32
163 #define IP_NAME_SZ 32
164 
165 /* Device flag bits */
166 #define F_IPSRC_RND   (1<<0)	/* IP-Src Random  */
167 #define F_IPDST_RND   (1<<1)	/* IP-Dst Random  */
168 #define F_UDPSRC_RND  (1<<2)	/* UDP-Src Random */
169 #define F_UDPDST_RND  (1<<3)	/* UDP-Dst Random */
170 #define F_MACSRC_RND  (1<<4)	/* MAC-Src Random */
171 #define F_MACDST_RND  (1<<5)	/* MAC-Dst Random */
172 #define F_TXSIZE_RND  (1<<6)	/* Transmit size is random */
173 #define F_IPV6        (1<<7)	/* Interface in IPV6 Mode */
174 
175 /* Thread control flag bits */
176 #define T_TERMINATE   (1<<0)
177 #define T_STOP        (1<<1)	/* Stop run */
178 #define T_RUN         (1<<2)	/* Start run */
179 #define T_REMDEVALL   (1<<3)	/* Remove all devs */
180 #define T_REMDEV      (1<<4)	/* Remove one dev */
181 
182 /* Locks */
183 #define   thread_lock()        down(&pktgen_sem)
184 #define   thread_unlock()      up(&pktgen_sem)
185 
186 /* If lock -- can be removed after some work */
187 #define   if_lock(t)           spin_lock(&(t->if_lock));
188 #define   if_unlock(t)           spin_unlock(&(t->if_lock));
189 
190 /* Used to help with determining the pkts on receive */
191 #define PKTGEN_MAGIC 0xbe9be955
192 #define PG_PROC_DIR "pktgen"
193 #define PGCTRL	    "pgctrl"
194 static struct proc_dir_entry *pg_proc_dir = NULL;
195 
196 #define MAX_CFLOWS  65536
197 
198 struct flow_state {
199 	__u32 cur_daddr;
200 	int count;
201 };
202 
203 struct pktgen_dev {
204 
205 	/*
206 	 * Try to keep frequent/infrequent used vars. separated.
207 	 */
208 
209 	char ifname[IFNAMSIZ];
210 	char result[512];
211 
212 	struct pktgen_thread *pg_thread;	/* the owner */
213 	struct pktgen_dev *next;	/* Used for chaining in the thread's run-queue */
214 
215 	int running;		/* if this changes to false, the test will stop */
216 
217 	/* If min != max, then we will either do a linear iteration, or
218 	 * we will do a random selection from within the range.
219 	 */
220 	__u32 flags;
221 	int removal_mark;	/* non-zero => the device is marked for
222 				 * removal by worker thread */
223 
224 	int min_pkt_size;	/* = ETH_ZLEN; */
225 	int max_pkt_size;	/* = ETH_ZLEN; */
226 	int nfrags;
227 	__u32 delay_us;		/* Default delay */
228 	__u32 delay_ns;
229 	__u64 count;		/* Default No packets to send */
230 	__u64 sofar;		/* How many pkts we've sent so far */
231 	__u64 tx_bytes;		/* How many bytes we've transmitted */
232 	__u64 errors;		/* Errors when trying to transmit, pkts will be re-sent */
233 
234 	/* runtime counters relating to clone_skb */
235 	__u64 next_tx_us;	/* timestamp of when to tx next */
236 	__u32 next_tx_ns;
237 
238 	__u64 allocated_skbs;
239 	__u32 clone_count;
240 	int last_ok;		/* Was last skb sent?
241 				 * Or a failed transmit of some sort?  This will keep
242 				 * sequence numbers in order, for example.
243 				 */
244 	__u64 started_at;	/* micro-seconds */
245 	__u64 stopped_at;	/* micro-seconds */
246 	__u64 idle_acc;		/* micro-seconds */
247 	__u32 seq_num;
248 
249 	int clone_skb;		/* Use multiple SKBs during packet gen.  If this number
250 				 * is greater than 1, then that many copies of the same
251 				 * packet will be sent before a new packet is allocated.
252 				 * For instance, if you want to send 1024 identical packets
253 				 * before creating a new packet, set clone_skb to 1024.
254 				 */
255 
256 	char dst_min[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
257 	char dst_max[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
258 	char src_min[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
259 	char src_max[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
260 
261 	struct in6_addr in6_saddr;
262 	struct in6_addr in6_daddr;
263 	struct in6_addr cur_in6_daddr;
264 	struct in6_addr cur_in6_saddr;
265 	/* For ranges */
266 	struct in6_addr min_in6_daddr;
267 	struct in6_addr max_in6_daddr;
268 	struct in6_addr min_in6_saddr;
269 	struct in6_addr max_in6_saddr;
270 
271 	/* If we're doing ranges, random or incremental, then this
272 	 * defines the min/max for those ranges.
273 	 */
274 	__u32 saddr_min;	/* inclusive, source IP address */
275 	__u32 saddr_max;	/* exclusive, source IP address */
276 	__u32 daddr_min;	/* inclusive, dest IP address */
277 	__u32 daddr_max;	/* exclusive, dest IP address */
278 
279 	__u16 udp_src_min;	/* inclusive, source UDP port */
280 	__u16 udp_src_max;	/* exclusive, source UDP port */
281 	__u16 udp_dst_min;	/* inclusive, dest UDP port */
282 	__u16 udp_dst_max;	/* exclusive, dest UDP port */
283 
284 	__u32 src_mac_count;	/* How many MACs to iterate through */
285 	__u32 dst_mac_count;	/* How many MACs to iterate through */
286 
287 	unsigned char dst_mac[ETH_ALEN];
288 	unsigned char src_mac[ETH_ALEN];
289 
290 	__u32 cur_dst_mac_offset;
291 	__u32 cur_src_mac_offset;
292 	__u32 cur_saddr;
293 	__u32 cur_daddr;
294 	__u16 cur_udp_dst;
295 	__u16 cur_udp_src;
296 	__u32 cur_pkt_size;
297 
298 	__u8 hh[14];
299 	/* = {
300 	   0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB,
301 
302 	   We fill in SRC address later
303 	   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 	   0x08, 0x00
305 	   };
306 	 */
307 	__u16 pad;		/* pad out the hh struct to an even 16 bytes */
308 
309 	struct sk_buff *skb;	/* skb we are to transmit next, mainly used for when we
310 				 * are transmitting the same one multiple times
311 				 */
312 	struct net_device *odev;	/* The out-going device.  Note that the device should
313 					 * have it's pg_info pointer pointing back to this
314 					 * device.  This will be set when the user specifies
315 					 * the out-going device name (not when the inject is
316 					 * started as it used to do.)
317 					 */
318 	struct flow_state *flows;
319 	unsigned cflows;	/* Concurrent flows (config) */
320 	unsigned lflow;		/* Flow length  (config) */
321 	unsigned nflows;	/* accumulated flows (stats) */
322 };
323 
324 struct pktgen_hdr {
325 	__u32 pgh_magic;
326 	__u32 seq_num;
327 	__u32 tv_sec;
328 	__u32 tv_usec;
329 };
330 
331 struct pktgen_thread {
332 	spinlock_t if_lock;
333 	struct pktgen_dev *if_list;	/* All device here */
334 	struct list_head th_list;
335 	int removed;
336 	char name[32];
337 	char result[512];
338 	u32 max_before_softirq;	/* We'll call do_softirq to prevent starvation. */
339 
340 	/* Field for thread to receive "posted" events terminate, stop ifs etc. */
341 
342 	u32 control;
343 	int pid;
344 	int cpu;
345 
346 	wait_queue_head_t queue;
347 };
348 
349 #define REMOVE 1
350 #define FIND   0
351 
352 /*  This code works around the fact that do_div cannot handle two 64-bit
353     numbers, and regular 64-bit division doesn't work on x86 kernels.
354     --Ben
355 */
356 
357 #define PG_DIV 0
358 
359 /* This was emailed to LMKL by: Chris Caputo <ccaputo@alt.net>
360  * Function copied/adapted/optimized from:
361  *
362  *  nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
363  *
364  * Copyright 1994, University of Cambridge Computer Laboratory
365  * All Rights Reserved.
366  *
367  */
368 static inline s64 divremdi3(s64 x, s64 y, int type)
369 {
370 	u64 a = (x < 0) ? -x : x;
371 	u64 b = (y < 0) ? -y : y;
372 	u64 res = 0, d = 1;
373 
374 	if (b > 0) {
375 		while (b < a) {
376 			b <<= 1;
377 			d <<= 1;
378 		}
379 	}
380 
381 	do {
382 		if (a >= b) {
383 			a -= b;
384 			res += d;
385 		}
386 		b >>= 1;
387 		d >>= 1;
388 	}
389 	while (d);
390 
391 	if (PG_DIV == type) {
392 		return (((x ^ y) & (1ll << 63)) == 0) ? res : -(s64) res;
393 	} else {
394 		return ((x & (1ll << 63)) == 0) ? a : -(s64) a;
395 	}
396 }
397 
398 /* End of hacks to deal with 64-bit math on x86 */
399 
400 /** Convert to milliseconds */
401 static inline __u64 tv_to_ms(const struct timeval *tv)
402 {
403 	__u64 ms = tv->tv_usec / 1000;
404 	ms += (__u64) tv->tv_sec * (__u64) 1000;
405 	return ms;
406 }
407 
408 /** Convert to micro-seconds */
409 static inline __u64 tv_to_us(const struct timeval *tv)
410 {
411 	__u64 us = tv->tv_usec;
412 	us += (__u64) tv->tv_sec * (__u64) 1000000;
413 	return us;
414 }
415 
416 static inline __u64 pg_div(__u64 n, __u32 base)
417 {
418 	__u64 tmp = n;
419 	do_div(tmp, base);
420 	/* printk("pktgen: pg_div, n: %llu  base: %d  rv: %llu\n",
421 	   n, base, tmp); */
422 	return tmp;
423 }
424 
425 static inline __u64 pg_div64(__u64 n, __u64 base)
426 {
427 	__u64 tmp = n;
428 /*
429  * How do we know if the architecture we are running on
430  * supports division with 64 bit base?
431  *
432  */
433 #if defined(__sparc_v9__) || defined(__powerpc64__) || defined(__alpha__) || defined(__x86_64__) || defined(__ia64__)
434 
435 	do_div(tmp, base);
436 #else
437 	tmp = divremdi3(n, base, PG_DIV);
438 #endif
439 	return tmp;
440 }
441 
442 static inline u32 pktgen_random(void)
443 {
444 #if 0
445 	__u32 n;
446 	get_random_bytes(&n, 4);
447 	return n;
448 #else
449 	return net_random();
450 #endif
451 }
452 
453 static inline __u64 getCurMs(void)
454 {
455 	struct timeval tv;
456 	do_gettimeofday(&tv);
457 	return tv_to_ms(&tv);
458 }
459 
460 static inline __u64 getCurUs(void)
461 {
462 	struct timeval tv;
463 	do_gettimeofday(&tv);
464 	return tv_to_us(&tv);
465 }
466 
467 static inline __u64 tv_diff(const struct timeval *a, const struct timeval *b)
468 {
469 	return tv_to_us(a) - tv_to_us(b);
470 }
471 
472 /* old include end */
473 
474 static char version[] __initdata = VERSION;
475 
476 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
477 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
478 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
479 					  const char *ifname);
480 static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
481 static void pktgen_run_all_threads(void);
482 static void pktgen_stop_all_threads_ifs(void);
483 static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
484 static void pktgen_stop(struct pktgen_thread *t);
485 static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
486 static int pktgen_mark_device(const char *ifname);
487 static unsigned int scan_ip6(const char *s, char ip[16]);
488 static unsigned int fmt_ip6(char *s, const char ip[16]);
489 
490 /* Module parameters, defaults. */
491 static int pg_count_d = 1000;	/* 1000 pkts by default */
492 static int pg_delay_d;
493 static int pg_clone_skb_d;
494 static int debug;
495 
496 static DECLARE_MUTEX(pktgen_sem);
497 static LIST_HEAD(pktgen_threads);
498 
499 static struct notifier_block pktgen_notifier_block = {
500 	.notifier_call = pktgen_device_event,
501 };
502 
503 /*
504  * /proc handling functions
505  *
506  */
507 
508 static int pgctrl_show(struct seq_file *seq, void *v)
509 {
510 	seq_puts(seq, VERSION);
511 	return 0;
512 }
513 
514 static ssize_t pgctrl_write(struct file *file, const char __user * buf,
515 			    size_t count, loff_t * ppos)
516 {
517 	int err = 0;
518 	char data[128];
519 
520 	if (!capable(CAP_NET_ADMIN)) {
521 		err = -EPERM;
522 		goto out;
523 	}
524 
525 	if (count > sizeof(data))
526 		count = sizeof(data);
527 
528 	if (copy_from_user(data, buf, count)) {
529 		err = -EFAULT;
530 		goto out;
531 	}
532 	data[count - 1] = 0;	/* Make string */
533 
534 	if (!strcmp(data, "stop"))
535 		pktgen_stop_all_threads_ifs();
536 
537 	else if (!strcmp(data, "start"))
538 		pktgen_run_all_threads();
539 
540 	else
541 		printk("pktgen: Unknown command: %s\n", data);
542 
543 	err = count;
544 
545 out:
546 	return err;
547 }
548 
549 static int pgctrl_open(struct inode *inode, struct file *file)
550 {
551 	return single_open(file, pgctrl_show, PDE(inode)->data);
552 }
553 
554 static struct file_operations pktgen_fops = {
555 	.owner   = THIS_MODULE,
556 	.open    = pgctrl_open,
557 	.read    = seq_read,
558 	.llseek  = seq_lseek,
559 	.write   = pgctrl_write,
560 	.release = single_release,
561 };
562 
563 static int pktgen_if_show(struct seq_file *seq, void *v)
564 {
565 	int i;
566 	struct pktgen_dev *pkt_dev = seq->private;
567 	__u64 sa;
568 	__u64 stopped;
569 	__u64 now = getCurUs();
570 
571 	seq_printf(seq,
572 		   "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
573 		   (unsigned long long)pkt_dev->count, pkt_dev->min_pkt_size,
574 		   pkt_dev->max_pkt_size);
575 
576 	seq_printf(seq,
577 		   "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
578 		   pkt_dev->nfrags,
579 		   1000 * pkt_dev->delay_us + pkt_dev->delay_ns,
580 		   pkt_dev->clone_skb, pkt_dev->ifname);
581 
582 	seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
583 		   pkt_dev->lflow);
584 
585 	if (pkt_dev->flags & F_IPV6) {
586 		char b1[128], b2[128], b3[128];
587 		fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
588 		fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
589 		fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
590 		seq_printf(seq,
591 			   "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1,
592 			   b2, b3);
593 
594 		fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
595 		fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
596 		fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
597 		seq_printf(seq,
598 			   "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1,
599 			   b2, b3);
600 
601 	} else
602 		seq_printf(seq,
603 			   "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
604 			   pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min,
605 			   pkt_dev->src_max);
606 
607 	seq_puts(seq, "     src_mac: ");
608 
609 	if (is_zero_ether_addr(pkt_dev->src_mac))
610 		for (i = 0; i < 6; i++)
611 			seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i],
612 				   i == 5 ? "  " : ":");
613 	else
614 		for (i = 0; i < 6; i++)
615 			seq_printf(seq, "%02X%s", pkt_dev->src_mac[i],
616 				   i == 5 ? "  " : ":");
617 
618 	seq_printf(seq, "dst_mac: ");
619 	for (i = 0; i < 6; i++)
620 		seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i],
621 			   i == 5 ? "\n" : ":");
622 
623 	seq_printf(seq,
624 		   "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
625 		   pkt_dev->udp_src_min, pkt_dev->udp_src_max,
626 		   pkt_dev->udp_dst_min, pkt_dev->udp_dst_max);
627 
628 	seq_printf(seq,
629 		   "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
630 		   pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
631 
632 	if (pkt_dev->flags & F_IPV6)
633 		seq_printf(seq, "IPV6  ");
634 
635 	if (pkt_dev->flags & F_IPSRC_RND)
636 		seq_printf(seq, "IPSRC_RND  ");
637 
638 	if (pkt_dev->flags & F_IPDST_RND)
639 		seq_printf(seq, "IPDST_RND  ");
640 
641 	if (pkt_dev->flags & F_TXSIZE_RND)
642 		seq_printf(seq, "TXSIZE_RND  ");
643 
644 	if (pkt_dev->flags & F_UDPSRC_RND)
645 		seq_printf(seq, "UDPSRC_RND  ");
646 
647 	if (pkt_dev->flags & F_UDPDST_RND)
648 		seq_printf(seq, "UDPDST_RND  ");
649 
650 	if (pkt_dev->flags & F_MACSRC_RND)
651 		seq_printf(seq, "MACSRC_RND  ");
652 
653 	if (pkt_dev->flags & F_MACDST_RND)
654 		seq_printf(seq, "MACDST_RND  ");
655 
656 	seq_puts(seq, "\n");
657 
658 	sa = pkt_dev->started_at;
659 	stopped = pkt_dev->stopped_at;
660 	if (pkt_dev->running)
661 		stopped = now;	/* not really stopped, more like last-running-at */
662 
663 	seq_printf(seq,
664 		   "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
665 		   (unsigned long long)pkt_dev->sofar,
666 		   (unsigned long long)pkt_dev->errors, (unsigned long long)sa,
667 		   (unsigned long long)stopped,
668 		   (unsigned long long)pkt_dev->idle_acc);
669 
670 	seq_printf(seq,
671 		   "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
672 		   pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
673 		   pkt_dev->cur_src_mac_offset);
674 
675 	if (pkt_dev->flags & F_IPV6) {
676 		char b1[128], b2[128];
677 		fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
678 		fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
679 		seq_printf(seq, "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
680 	} else
681 		seq_printf(seq, "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
682 			   pkt_dev->cur_saddr, pkt_dev->cur_daddr);
683 
684 	seq_printf(seq, "     cur_udp_dst: %d  cur_udp_src: %d\n",
685 		   pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
686 
687 	seq_printf(seq, "     flows: %u\n", pkt_dev->nflows);
688 
689 	if (pkt_dev->result[0])
690 		seq_printf(seq, "Result: %s\n", pkt_dev->result);
691 	else
692 		seq_printf(seq, "Result: Idle\n");
693 
694 	return 0;
695 }
696 
697 static int count_trail_chars(const char __user * user_buffer,
698 			     unsigned int maxlen)
699 {
700 	int i;
701 
702 	for (i = 0; i < maxlen; i++) {
703 		char c;
704 		if (get_user(c, &user_buffer[i]))
705 			return -EFAULT;
706 		switch (c) {
707 		case '\"':
708 		case '\n':
709 		case '\r':
710 		case '\t':
711 		case ' ':
712 		case '=':
713 			break;
714 		default:
715 			goto done;
716 		};
717 	}
718 done:
719 	return i;
720 }
721 
722 static unsigned long num_arg(const char __user * user_buffer,
723 			     unsigned long maxlen, unsigned long *num)
724 {
725 	int i = 0;
726 	*num = 0;
727 
728 	for (; i < maxlen; i++) {
729 		char c;
730 		if (get_user(c, &user_buffer[i]))
731 			return -EFAULT;
732 		if ((c >= '0') && (c <= '9')) {
733 			*num *= 10;
734 			*num += c - '0';
735 		} else
736 			break;
737 	}
738 	return i;
739 }
740 
741 static int strn_len(const char __user * user_buffer, unsigned int maxlen)
742 {
743 	int i = 0;
744 
745 	for (; i < maxlen; i++) {
746 		char c;
747 		if (get_user(c, &user_buffer[i]))
748 			return -EFAULT;
749 		switch (c) {
750 		case '\"':
751 		case '\n':
752 		case '\r':
753 		case '\t':
754 		case ' ':
755 			goto done_str;
756 			break;
757 		default:
758 			break;
759 		};
760 	}
761 done_str:
762 	return i;
763 }
764 
765 static ssize_t pktgen_if_write(struct file *file,
766 			       const char __user * user_buffer, size_t count,
767 			       loff_t * offset)
768 {
769 	struct seq_file *seq = (struct seq_file *)file->private_data;
770 	struct pktgen_dev *pkt_dev = seq->private;
771 	int i = 0, max, len;
772 	char name[16], valstr[32];
773 	unsigned long value = 0;
774 	char *pg_result = NULL;
775 	int tmp = 0;
776 	char buf[128];
777 
778 	pg_result = &(pkt_dev->result[0]);
779 
780 	if (count < 1) {
781 		printk("pktgen: wrong command format\n");
782 		return -EINVAL;
783 	}
784 
785 	max = count - i;
786 	tmp = count_trail_chars(&user_buffer[i], max);
787 	if (tmp < 0) {
788 		printk("pktgen: illegal format\n");
789 		return tmp;
790 	}
791 	i += tmp;
792 
793 	/* Read variable name */
794 
795 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
796 	if (len < 0) {
797 		return len;
798 	}
799 	memset(name, 0, sizeof(name));
800 	if (copy_from_user(name, &user_buffer[i], len))
801 		return -EFAULT;
802 	i += len;
803 
804 	max = count - i;
805 	len = count_trail_chars(&user_buffer[i], max);
806 	if (len < 0)
807 		return len;
808 
809 	i += len;
810 
811 	if (debug) {
812 		char tb[count + 1];
813 		if (copy_from_user(tb, user_buffer, count))
814 			return -EFAULT;
815 		tb[count] = 0;
816 		printk("pktgen: %s,%lu  buffer -:%s:-\n", name,
817 		       (unsigned long)count, tb);
818 	}
819 
820 	if (!strcmp(name, "min_pkt_size")) {
821 		len = num_arg(&user_buffer[i], 10, &value);
822 		if (len < 0) {
823 			return len;
824 		}
825 		i += len;
826 		if (value < 14 + 20 + 8)
827 			value = 14 + 20 + 8;
828 		if (value != pkt_dev->min_pkt_size) {
829 			pkt_dev->min_pkt_size = value;
830 			pkt_dev->cur_pkt_size = value;
831 		}
832 		sprintf(pg_result, "OK: min_pkt_size=%u",
833 			pkt_dev->min_pkt_size);
834 		return count;
835 	}
836 
837 	if (!strcmp(name, "max_pkt_size")) {
838 		len = num_arg(&user_buffer[i], 10, &value);
839 		if (len < 0) {
840 			return len;
841 		}
842 		i += len;
843 		if (value < 14 + 20 + 8)
844 			value = 14 + 20 + 8;
845 		if (value != pkt_dev->max_pkt_size) {
846 			pkt_dev->max_pkt_size = value;
847 			pkt_dev->cur_pkt_size = value;
848 		}
849 		sprintf(pg_result, "OK: max_pkt_size=%u",
850 			pkt_dev->max_pkt_size);
851 		return count;
852 	}
853 
854 	/* Shortcut for min = max */
855 
856 	if (!strcmp(name, "pkt_size")) {
857 		len = num_arg(&user_buffer[i], 10, &value);
858 		if (len < 0) {
859 			return len;
860 		}
861 		i += len;
862 		if (value < 14 + 20 + 8)
863 			value = 14 + 20 + 8;
864 		if (value != pkt_dev->min_pkt_size) {
865 			pkt_dev->min_pkt_size = value;
866 			pkt_dev->max_pkt_size = value;
867 			pkt_dev->cur_pkt_size = value;
868 		}
869 		sprintf(pg_result, "OK: pkt_size=%u", pkt_dev->min_pkt_size);
870 		return count;
871 	}
872 
873 	if (!strcmp(name, "debug")) {
874 		len = num_arg(&user_buffer[i], 10, &value);
875 		if (len < 0) {
876 			return len;
877 		}
878 		i += len;
879 		debug = value;
880 		sprintf(pg_result, "OK: debug=%u", debug);
881 		return count;
882 	}
883 
884 	if (!strcmp(name, "frags")) {
885 		len = num_arg(&user_buffer[i], 10, &value);
886 		if (len < 0) {
887 			return len;
888 		}
889 		i += len;
890 		pkt_dev->nfrags = value;
891 		sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
892 		return count;
893 	}
894 	if (!strcmp(name, "delay")) {
895 		len = num_arg(&user_buffer[i], 10, &value);
896 		if (len < 0) {
897 			return len;
898 		}
899 		i += len;
900 		if (value == 0x7FFFFFFF) {
901 			pkt_dev->delay_us = 0x7FFFFFFF;
902 			pkt_dev->delay_ns = 0;
903 		} else {
904 			pkt_dev->delay_us = value / 1000;
905 			pkt_dev->delay_ns = value % 1000;
906 		}
907 		sprintf(pg_result, "OK: delay=%u",
908 			1000 * pkt_dev->delay_us + pkt_dev->delay_ns);
909 		return count;
910 	}
911 	if (!strcmp(name, "udp_src_min")) {
912 		len = num_arg(&user_buffer[i], 10, &value);
913 		if (len < 0) {
914 			return len;
915 		}
916 		i += len;
917 		if (value != pkt_dev->udp_src_min) {
918 			pkt_dev->udp_src_min = value;
919 			pkt_dev->cur_udp_src = value;
920 		}
921 		sprintf(pg_result, "OK: udp_src_min=%u", pkt_dev->udp_src_min);
922 		return count;
923 	}
924 	if (!strcmp(name, "udp_dst_min")) {
925 		len = num_arg(&user_buffer[i], 10, &value);
926 		if (len < 0) {
927 			return len;
928 		}
929 		i += len;
930 		if (value != pkt_dev->udp_dst_min) {
931 			pkt_dev->udp_dst_min = value;
932 			pkt_dev->cur_udp_dst = value;
933 		}
934 		sprintf(pg_result, "OK: udp_dst_min=%u", pkt_dev->udp_dst_min);
935 		return count;
936 	}
937 	if (!strcmp(name, "udp_src_max")) {
938 		len = num_arg(&user_buffer[i], 10, &value);
939 		if (len < 0) {
940 			return len;
941 		}
942 		i += len;
943 		if (value != pkt_dev->udp_src_max) {
944 			pkt_dev->udp_src_max = value;
945 			pkt_dev->cur_udp_src = value;
946 		}
947 		sprintf(pg_result, "OK: udp_src_max=%u", pkt_dev->udp_src_max);
948 		return count;
949 	}
950 	if (!strcmp(name, "udp_dst_max")) {
951 		len = num_arg(&user_buffer[i], 10, &value);
952 		if (len < 0) {
953 			return len;
954 		}
955 		i += len;
956 		if (value != pkt_dev->udp_dst_max) {
957 			pkt_dev->udp_dst_max = value;
958 			pkt_dev->cur_udp_dst = value;
959 		}
960 		sprintf(pg_result, "OK: udp_dst_max=%u", pkt_dev->udp_dst_max);
961 		return count;
962 	}
963 	if (!strcmp(name, "clone_skb")) {
964 		len = num_arg(&user_buffer[i], 10, &value);
965 		if (len < 0) {
966 			return len;
967 		}
968 		i += len;
969 		pkt_dev->clone_skb = value;
970 
971 		sprintf(pg_result, "OK: clone_skb=%d", pkt_dev->clone_skb);
972 		return count;
973 	}
974 	if (!strcmp(name, "count")) {
975 		len = num_arg(&user_buffer[i], 10, &value);
976 		if (len < 0) {
977 			return len;
978 		}
979 		i += len;
980 		pkt_dev->count = value;
981 		sprintf(pg_result, "OK: count=%llu",
982 			(unsigned long long)pkt_dev->count);
983 		return count;
984 	}
985 	if (!strcmp(name, "src_mac_count")) {
986 		len = num_arg(&user_buffer[i], 10, &value);
987 		if (len < 0) {
988 			return len;
989 		}
990 		i += len;
991 		if (pkt_dev->src_mac_count != value) {
992 			pkt_dev->src_mac_count = value;
993 			pkt_dev->cur_src_mac_offset = 0;
994 		}
995 		sprintf(pg_result, "OK: src_mac_count=%d",
996 			pkt_dev->src_mac_count);
997 		return count;
998 	}
999 	if (!strcmp(name, "dst_mac_count")) {
1000 		len = num_arg(&user_buffer[i], 10, &value);
1001 		if (len < 0) {
1002 			return len;
1003 		}
1004 		i += len;
1005 		if (pkt_dev->dst_mac_count != value) {
1006 			pkt_dev->dst_mac_count = value;
1007 			pkt_dev->cur_dst_mac_offset = 0;
1008 		}
1009 		sprintf(pg_result, "OK: dst_mac_count=%d",
1010 			pkt_dev->dst_mac_count);
1011 		return count;
1012 	}
1013 	if (!strcmp(name, "flag")) {
1014 		char f[32];
1015 		memset(f, 0, 32);
1016 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
1017 		if (len < 0) {
1018 			return len;
1019 		}
1020 		if (copy_from_user(f, &user_buffer[i], len))
1021 			return -EFAULT;
1022 		i += len;
1023 		if (strcmp(f, "IPSRC_RND") == 0)
1024 			pkt_dev->flags |= F_IPSRC_RND;
1025 
1026 		else if (strcmp(f, "!IPSRC_RND") == 0)
1027 			pkt_dev->flags &= ~F_IPSRC_RND;
1028 
1029 		else if (strcmp(f, "TXSIZE_RND") == 0)
1030 			pkt_dev->flags |= F_TXSIZE_RND;
1031 
1032 		else if (strcmp(f, "!TXSIZE_RND") == 0)
1033 			pkt_dev->flags &= ~F_TXSIZE_RND;
1034 
1035 		else if (strcmp(f, "IPDST_RND") == 0)
1036 			pkt_dev->flags |= F_IPDST_RND;
1037 
1038 		else if (strcmp(f, "!IPDST_RND") == 0)
1039 			pkt_dev->flags &= ~F_IPDST_RND;
1040 
1041 		else if (strcmp(f, "UDPSRC_RND") == 0)
1042 			pkt_dev->flags |= F_UDPSRC_RND;
1043 
1044 		else if (strcmp(f, "!UDPSRC_RND") == 0)
1045 			pkt_dev->flags &= ~F_UDPSRC_RND;
1046 
1047 		else if (strcmp(f, "UDPDST_RND") == 0)
1048 			pkt_dev->flags |= F_UDPDST_RND;
1049 
1050 		else if (strcmp(f, "!UDPDST_RND") == 0)
1051 			pkt_dev->flags &= ~F_UDPDST_RND;
1052 
1053 		else if (strcmp(f, "MACSRC_RND") == 0)
1054 			pkt_dev->flags |= F_MACSRC_RND;
1055 
1056 		else if (strcmp(f, "!MACSRC_RND") == 0)
1057 			pkt_dev->flags &= ~F_MACSRC_RND;
1058 
1059 		else if (strcmp(f, "MACDST_RND") == 0)
1060 			pkt_dev->flags |= F_MACDST_RND;
1061 
1062 		else if (strcmp(f, "!MACDST_RND") == 0)
1063 			pkt_dev->flags &= ~F_MACDST_RND;
1064 
1065 		else {
1066 			sprintf(pg_result,
1067 				"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
1068 				f,
1069 				"IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
1070 			return count;
1071 		}
1072 		sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
1073 		return count;
1074 	}
1075 	if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
1076 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
1077 		if (len < 0) {
1078 			return len;
1079 		}
1080 
1081 		if (copy_from_user(buf, &user_buffer[i], len))
1082 			return -EFAULT;
1083 		buf[len] = 0;
1084 		if (strcmp(buf, pkt_dev->dst_min) != 0) {
1085 			memset(pkt_dev->dst_min, 0, sizeof(pkt_dev->dst_min));
1086 			strncpy(pkt_dev->dst_min, buf, len);
1087 			pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
1088 			pkt_dev->cur_daddr = pkt_dev->daddr_min;
1089 		}
1090 		if (debug)
1091 			printk("pktgen: dst_min set to: %s\n",
1092 			       pkt_dev->dst_min);
1093 		i += len;
1094 		sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min);
1095 		return count;
1096 	}
1097 	if (!strcmp(name, "dst_max")) {
1098 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
1099 		if (len < 0) {
1100 			return len;
1101 		}
1102 
1103 		if (copy_from_user(buf, &user_buffer[i], len))
1104 			return -EFAULT;
1105 
1106 		buf[len] = 0;
1107 		if (strcmp(buf, pkt_dev->dst_max) != 0) {
1108 			memset(pkt_dev->dst_max, 0, sizeof(pkt_dev->dst_max));
1109 			strncpy(pkt_dev->dst_max, buf, len);
1110 			pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
1111 			pkt_dev->cur_daddr = pkt_dev->daddr_max;
1112 		}
1113 		if (debug)
1114 			printk("pktgen: dst_max set to: %s\n",
1115 			       pkt_dev->dst_max);
1116 		i += len;
1117 		sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max);
1118 		return count;
1119 	}
1120 	if (!strcmp(name, "dst6")) {
1121 		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
1122 		if (len < 0)
1123 			return len;
1124 
1125 		pkt_dev->flags |= F_IPV6;
1126 
1127 		if (copy_from_user(buf, &user_buffer[i], len))
1128 			return -EFAULT;
1129 		buf[len] = 0;
1130 
1131 		scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
1132 		fmt_ip6(buf, pkt_dev->in6_daddr.s6_addr);
1133 
1134 		ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
1135 
1136 		if (debug)
1137 			printk("pktgen: dst6 set to: %s\n", buf);
1138 
1139 		i += len;
1140 		sprintf(pg_result, "OK: dst6=%s", buf);
1141 		return count;
1142 	}
1143 	if (!strcmp(name, "dst6_min")) {
1144 		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
1145 		if (len < 0)
1146 			return len;
1147 
1148 		pkt_dev->flags |= F_IPV6;
1149 
1150 		if (copy_from_user(buf, &user_buffer[i], len))
1151 			return -EFAULT;
1152 		buf[len] = 0;
1153 
1154 		scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
1155 		fmt_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
1156 
1157 		ipv6_addr_copy(&pkt_dev->cur_in6_daddr,
1158 			       &pkt_dev->min_in6_daddr);
1159 		if (debug)
1160 			printk("pktgen: dst6_min set to: %s\n", buf);
1161 
1162 		i += len;
1163 		sprintf(pg_result, "OK: dst6_min=%s", buf);
1164 		return count;
1165 	}
1166 	if (!strcmp(name, "dst6_max")) {
1167 		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
1168 		if (len < 0)
1169 			return len;
1170 
1171 		pkt_dev->flags |= F_IPV6;
1172 
1173 		if (copy_from_user(buf, &user_buffer[i], len))
1174 			return -EFAULT;
1175 		buf[len] = 0;
1176 
1177 		scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
1178 		fmt_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
1179 
1180 		if (debug)
1181 			printk("pktgen: dst6_max set to: %s\n", buf);
1182 
1183 		i += len;
1184 		sprintf(pg_result, "OK: dst6_max=%s", buf);
1185 		return count;
1186 	}
1187 	if (!strcmp(name, "src6")) {
1188 		len = strn_len(&user_buffer[i], sizeof(buf) - 1);
1189 		if (len < 0)
1190 			return len;
1191 
1192 		pkt_dev->flags |= F_IPV6;
1193 
1194 		if (copy_from_user(buf, &user_buffer[i], len))
1195 			return -EFAULT;
1196 		buf[len] = 0;
1197 
1198 		scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
1199 		fmt_ip6(buf, pkt_dev->in6_saddr.s6_addr);
1200 
1201 		ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
1202 
1203 		if (debug)
1204 			printk("pktgen: src6 set to: %s\n", buf);
1205 
1206 		i += len;
1207 		sprintf(pg_result, "OK: src6=%s", buf);
1208 		return count;
1209 	}
1210 	if (!strcmp(name, "src_min")) {
1211 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
1212 		if (len < 0) {
1213 			return len;
1214 		}
1215 		if (copy_from_user(buf, &user_buffer[i], len))
1216 			return -EFAULT;
1217 		buf[len] = 0;
1218 		if (strcmp(buf, pkt_dev->src_min) != 0) {
1219 			memset(pkt_dev->src_min, 0, sizeof(pkt_dev->src_min));
1220 			strncpy(pkt_dev->src_min, buf, len);
1221 			pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
1222 			pkt_dev->cur_saddr = pkt_dev->saddr_min;
1223 		}
1224 		if (debug)
1225 			printk("pktgen: src_min set to: %s\n",
1226 			       pkt_dev->src_min);
1227 		i += len;
1228 		sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min);
1229 		return count;
1230 	}
1231 	if (!strcmp(name, "src_max")) {
1232 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
1233 		if (len < 0) {
1234 			return len;
1235 		}
1236 		if (copy_from_user(buf, &user_buffer[i], len))
1237 			return -EFAULT;
1238 		buf[len] = 0;
1239 		if (strcmp(buf, pkt_dev->src_max) != 0) {
1240 			memset(pkt_dev->src_max, 0, sizeof(pkt_dev->src_max));
1241 			strncpy(pkt_dev->src_max, buf, len);
1242 			pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
1243 			pkt_dev->cur_saddr = pkt_dev->saddr_max;
1244 		}
1245 		if (debug)
1246 			printk("pktgen: src_max set to: %s\n",
1247 			       pkt_dev->src_max);
1248 		i += len;
1249 		sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max);
1250 		return count;
1251 	}
1252 	if (!strcmp(name, "dst_mac")) {
1253 		char *v = valstr;
1254 		unsigned char old_dmac[ETH_ALEN];
1255 		unsigned char *m = pkt_dev->dst_mac;
1256 		memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
1257 
1258 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
1259 		if (len < 0) {
1260 			return len;
1261 		}
1262 		memset(valstr, 0, sizeof(valstr));
1263 		if (copy_from_user(valstr, &user_buffer[i], len))
1264 			return -EFAULT;
1265 		i += len;
1266 
1267 		for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) {
1268 			if (*v >= '0' && *v <= '9') {
1269 				*m *= 16;
1270 				*m += *v - '0';
1271 			}
1272 			if (*v >= 'A' && *v <= 'F') {
1273 				*m *= 16;
1274 				*m += *v - 'A' + 10;
1275 			}
1276 			if (*v >= 'a' && *v <= 'f') {
1277 				*m *= 16;
1278 				*m += *v - 'a' + 10;
1279 			}
1280 			if (*v == ':') {
1281 				m++;
1282 				*m = 0;
1283 			}
1284 		}
1285 
1286 		/* Set up Dest MAC */
1287 		if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
1288 			memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
1289 
1290 		sprintf(pg_result, "OK: dstmac");
1291 		return count;
1292 	}
1293 	if (!strcmp(name, "src_mac")) {
1294 		char *v = valstr;
1295 		unsigned char *m = pkt_dev->src_mac;
1296 
1297 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
1298 		if (len < 0) {
1299 			return len;
1300 		}
1301 		memset(valstr, 0, sizeof(valstr));
1302 		if (copy_from_user(valstr, &user_buffer[i], len))
1303 			return -EFAULT;
1304 		i += len;
1305 
1306 		for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) {
1307 			if (*v >= '0' && *v <= '9') {
1308 				*m *= 16;
1309 				*m += *v - '0';
1310 			}
1311 			if (*v >= 'A' && *v <= 'F') {
1312 				*m *= 16;
1313 				*m += *v - 'A' + 10;
1314 			}
1315 			if (*v >= 'a' && *v <= 'f') {
1316 				*m *= 16;
1317 				*m += *v - 'a' + 10;
1318 			}
1319 			if (*v == ':') {
1320 				m++;
1321 				*m = 0;
1322 			}
1323 		}
1324 
1325 		sprintf(pg_result, "OK: srcmac");
1326 		return count;
1327 	}
1328 
1329 	if (!strcmp(name, "clear_counters")) {
1330 		pktgen_clear_counters(pkt_dev);
1331 		sprintf(pg_result, "OK: Clearing counters.\n");
1332 		return count;
1333 	}
1334 
1335 	if (!strcmp(name, "flows")) {
1336 		len = num_arg(&user_buffer[i], 10, &value);
1337 		if (len < 0) {
1338 			return len;
1339 		}
1340 		i += len;
1341 		if (value > MAX_CFLOWS)
1342 			value = MAX_CFLOWS;
1343 
1344 		pkt_dev->cflows = value;
1345 		sprintf(pg_result, "OK: flows=%u", pkt_dev->cflows);
1346 		return count;
1347 	}
1348 
1349 	if (!strcmp(name, "flowlen")) {
1350 		len = num_arg(&user_buffer[i], 10, &value);
1351 		if (len < 0) {
1352 			return len;
1353 		}
1354 		i += len;
1355 		pkt_dev->lflow = value;
1356 		sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
1357 		return count;
1358 	}
1359 
1360 	sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
1361 	return -EINVAL;
1362 }
1363 
1364 static int pktgen_if_open(struct inode *inode, struct file *file)
1365 {
1366 	return single_open(file, pktgen_if_show, PDE(inode)->data);
1367 }
1368 
1369 static struct file_operations pktgen_if_fops = {
1370 	.owner   = THIS_MODULE,
1371 	.open    = pktgen_if_open,
1372 	.read    = seq_read,
1373 	.llseek  = seq_lseek,
1374 	.write   = pktgen_if_write,
1375 	.release = single_release,
1376 };
1377 
1378 static int pktgen_thread_show(struct seq_file *seq, void *v)
1379 {
1380 	struct pktgen_thread *t = seq->private;
1381 	struct pktgen_dev *pkt_dev = NULL;
1382 
1383 	BUG_ON(!t);
1384 
1385 	seq_printf(seq, "Name: %s  max_before_softirq: %d\n",
1386 		   t->name, t->max_before_softirq);
1387 
1388 	seq_printf(seq, "Running: ");
1389 
1390 	if_lock(t);
1391 	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
1392 		if (pkt_dev->running)
1393 			seq_printf(seq, "%s ", pkt_dev->ifname);
1394 
1395 	seq_printf(seq, "\nStopped: ");
1396 
1397 	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
1398 		if (!pkt_dev->running)
1399 			seq_printf(seq, "%s ", pkt_dev->ifname);
1400 
1401 	if (t->result[0])
1402 		seq_printf(seq, "\nResult: %s\n", t->result);
1403 	else
1404 		seq_printf(seq, "\nResult: NA\n");
1405 
1406 	if_unlock(t);
1407 
1408 	return 0;
1409 }
1410 
1411 static ssize_t pktgen_thread_write(struct file *file,
1412 				   const char __user * user_buffer,
1413 				   size_t count, loff_t * offset)
1414 {
1415 	struct seq_file *seq = (struct seq_file *)file->private_data;
1416 	struct pktgen_thread *t = seq->private;
1417 	int i = 0, max, len, ret;
1418 	char name[40];
1419 	char *pg_result;
1420 	unsigned long value = 0;
1421 
1422 	if (count < 1) {
1423 		//      sprintf(pg_result, "Wrong command format");
1424 		return -EINVAL;
1425 	}
1426 
1427 	max = count - i;
1428 	len = count_trail_chars(&user_buffer[i], max);
1429 	if (len < 0)
1430 		return len;
1431 
1432 	i += len;
1433 
1434 	/* Read variable name */
1435 
1436 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
1437 	if (len < 0)
1438 		return len;
1439 
1440 	memset(name, 0, sizeof(name));
1441 	if (copy_from_user(name, &user_buffer[i], len))
1442 		return -EFAULT;
1443 	i += len;
1444 
1445 	max = count - i;
1446 	len = count_trail_chars(&user_buffer[i], max);
1447 	if (len < 0)
1448 		return len;
1449 
1450 	i += len;
1451 
1452 	if (debug)
1453 		printk("pktgen: t=%s, count=%lu\n", name, (unsigned long)count);
1454 
1455 	if (!t) {
1456 		printk("pktgen: ERROR: No thread\n");
1457 		ret = -EINVAL;
1458 		goto out;
1459 	}
1460 
1461 	pg_result = &(t->result[0]);
1462 
1463 	if (!strcmp(name, "add_device")) {
1464 		char f[32];
1465 		memset(f, 0, 32);
1466 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
1467 		if (len < 0) {
1468 			ret = len;
1469 			goto out;
1470 		}
1471 		if (copy_from_user(f, &user_buffer[i], len))
1472 			return -EFAULT;
1473 		i += len;
1474 		thread_lock();
1475 		pktgen_add_device(t, f);
1476 		thread_unlock();
1477 		ret = count;
1478 		sprintf(pg_result, "OK: add_device=%s", f);
1479 		goto out;
1480 	}
1481 
1482 	if (!strcmp(name, "rem_device_all")) {
1483 		thread_lock();
1484 		t->control |= T_REMDEVALL;
1485 		thread_unlock();
1486 		schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
1487 		ret = count;
1488 		sprintf(pg_result, "OK: rem_device_all");
1489 		goto out;
1490 	}
1491 
1492 	if (!strcmp(name, "max_before_softirq")) {
1493 		len = num_arg(&user_buffer[i], 10, &value);
1494 		thread_lock();
1495 		t->max_before_softirq = value;
1496 		thread_unlock();
1497 		ret = count;
1498 		sprintf(pg_result, "OK: max_before_softirq=%lu", value);
1499 		goto out;
1500 	}
1501 
1502 	ret = -EINVAL;
1503 out:
1504 	return ret;
1505 }
1506 
1507 static int pktgen_thread_open(struct inode *inode, struct file *file)
1508 {
1509 	return single_open(file, pktgen_thread_show, PDE(inode)->data);
1510 }
1511 
1512 static struct file_operations pktgen_thread_fops = {
1513 	.owner   = THIS_MODULE,
1514 	.open    = pktgen_thread_open,
1515 	.read    = seq_read,
1516 	.llseek  = seq_lseek,
1517 	.write   = pktgen_thread_write,
1518 	.release = single_release,
1519 };
1520 
1521 /* Think find or remove for NN */
1522 static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
1523 {
1524 	struct pktgen_thread *t;
1525 	struct pktgen_dev *pkt_dev = NULL;
1526 
1527 	list_for_each_entry(t, &pktgen_threads, th_list) {
1528 		pkt_dev = pktgen_find_dev(t, ifname);
1529 		if (pkt_dev) {
1530 			if (remove) {
1531 				if_lock(t);
1532 				pkt_dev->removal_mark = 1;
1533 				t->control |= T_REMDEV;
1534 				if_unlock(t);
1535 			}
1536 			break;
1537 		}
1538 	}
1539 	return pkt_dev;
1540 }
1541 
1542 /*
1543  * mark a device for removal
1544  */
1545 static int pktgen_mark_device(const char *ifname)
1546 {
1547 	struct pktgen_dev *pkt_dev = NULL;
1548 	const int max_tries = 10, msec_per_try = 125;
1549 	int i = 0;
1550 	int ret = 0;
1551 
1552 	thread_lock();
1553 	PG_DEBUG(printk("pktgen: pktgen_mark_device marking %s for removal\n",
1554 			ifname));
1555 
1556 	while (1) {
1557 
1558 		pkt_dev = __pktgen_NN_threads(ifname, REMOVE);
1559 		if (pkt_dev == NULL)
1560 			break;	/* success */
1561 
1562 		thread_unlock();
1563 		PG_DEBUG(printk("pktgen: pktgen_mark_device waiting for %s "
1564 				"to disappear....\n", ifname));
1565 		schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try));
1566 		thread_lock();
1567 
1568 		if (++i >= max_tries) {
1569 			printk("pktgen_mark_device: timed out after waiting "
1570 			       "%d msec for device %s to be removed\n",
1571 			       msec_per_try * i, ifname);
1572 			ret = 1;
1573 			break;
1574 		}
1575 
1576 	}
1577 
1578 	thread_unlock();
1579 
1580 	return ret;
1581 }
1582 
1583 static int pktgen_device_event(struct notifier_block *unused,
1584 			       unsigned long event, void *ptr)
1585 {
1586 	struct net_device *dev = (struct net_device *)(ptr);
1587 
1588 	/* It is OK that we do not hold the group lock right now,
1589 	 * as we run under the RTNL lock.
1590 	 */
1591 
1592 	switch (event) {
1593 	case NETDEV_CHANGEADDR:
1594 	case NETDEV_GOING_DOWN:
1595 	case NETDEV_DOWN:
1596 	case NETDEV_UP:
1597 		/* Ignore for now */
1598 		break;
1599 
1600 	case NETDEV_UNREGISTER:
1601 		pktgen_mark_device(dev->name);
1602 		break;
1603 	};
1604 
1605 	return NOTIFY_DONE;
1606 }
1607 
1608 /* Associate pktgen_dev with a device. */
1609 
1610 static struct net_device *pktgen_setup_dev(struct pktgen_dev *pkt_dev)
1611 {
1612 	struct net_device *odev;
1613 
1614 	/* Clean old setups */
1615 
1616 	if (pkt_dev->odev) {
1617 		dev_put(pkt_dev->odev);
1618 		pkt_dev->odev = NULL;
1619 	}
1620 
1621 	odev = dev_get_by_name(pkt_dev->ifname);
1622 
1623 	if (!odev) {
1624 		printk("pktgen: no such netdevice: \"%s\"\n", pkt_dev->ifname);
1625 		goto out;
1626 	}
1627 	if (odev->type != ARPHRD_ETHER) {
1628 		printk("pktgen: not an ethernet device: \"%s\"\n",
1629 		       pkt_dev->ifname);
1630 		goto out_put;
1631 	}
1632 	if (!netif_running(odev)) {
1633 		printk("pktgen: device is down: \"%s\"\n", pkt_dev->ifname);
1634 		goto out_put;
1635 	}
1636 	pkt_dev->odev = odev;
1637 
1638 	return pkt_dev->odev;
1639 
1640 out_put:
1641 	dev_put(odev);
1642 out:
1643 	return NULL;
1644 
1645 }
1646 
1647 /* Read pkt_dev from the interface and set up internal pktgen_dev
1648  * structure to have the right information to create/send packets
1649  */
1650 static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1651 {
1652 	/* Try once more, just in case it works now. */
1653 	if (!pkt_dev->odev)
1654 		pktgen_setup_dev(pkt_dev);
1655 
1656 	if (!pkt_dev->odev) {
1657 		printk("pktgen: ERROR: pkt_dev->odev == NULL in setup_inject.\n");
1658 		sprintf(pkt_dev->result,
1659 			"ERROR: pkt_dev->odev == NULL in setup_inject.\n");
1660 		return;
1661 	}
1662 
1663 	/* Default to the interface's mac if not explicitly set. */
1664 
1665 	if (is_zero_ether_addr(pkt_dev->src_mac))
1666 		memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, ETH_ALEN);
1667 
1668 	/* Set up Dest MAC */
1669 	memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
1670 
1671 	/* Set up pkt size */
1672 	pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
1673 
1674 	if (pkt_dev->flags & F_IPV6) {
1675 		/*
1676 		 * Skip this automatic address setting until locks or functions
1677 		 * gets exported
1678 		 */
1679 
1680 #ifdef NOTNOW
1681 		int i, set = 0, err = 1;
1682 		struct inet6_dev *idev;
1683 
1684 		for (i = 0; i < IN6_ADDR_HSIZE; i++)
1685 			if (pkt_dev->cur_in6_saddr.s6_addr[i]) {
1686 				set = 1;
1687 				break;
1688 			}
1689 
1690 		if (!set) {
1691 
1692 			/*
1693 			 * Use linklevel address if unconfigured.
1694 			 *
1695 			 * use ipv6_get_lladdr if/when it's get exported
1696 			 */
1697 
1698 			read_lock(&addrconf_lock);
1699 			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
1700 				struct inet6_ifaddr *ifp;
1701 
1702 				read_lock_bh(&idev->lock);
1703 				for (ifp = idev->addr_list; ifp;
1704 				     ifp = ifp->if_next) {
1705 					if (ifp->scope == IFA_LINK
1706 					    && !(ifp->
1707 						 flags & IFA_F_TENTATIVE)) {
1708 						ipv6_addr_copy(&pkt_dev->
1709 							       cur_in6_saddr,
1710 							       &ifp->addr);
1711 						err = 0;
1712 						break;
1713 					}
1714 				}
1715 				read_unlock_bh(&idev->lock);
1716 			}
1717 			read_unlock(&addrconf_lock);
1718 			if (err)
1719 				printk("pktgen: ERROR: IPv6 link address not availble.\n");
1720 		}
1721 #endif
1722 	} else {
1723 		pkt_dev->saddr_min = 0;
1724 		pkt_dev->saddr_max = 0;
1725 		if (strlen(pkt_dev->src_min) == 0) {
1726 
1727 			struct in_device *in_dev;
1728 
1729 			rcu_read_lock();
1730 			in_dev = __in_dev_get_rcu(pkt_dev->odev);
1731 			if (in_dev) {
1732 				if (in_dev->ifa_list) {
1733 					pkt_dev->saddr_min =
1734 					    in_dev->ifa_list->ifa_address;
1735 					pkt_dev->saddr_max = pkt_dev->saddr_min;
1736 				}
1737 			}
1738 			rcu_read_unlock();
1739 		} else {
1740 			pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
1741 			pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
1742 		}
1743 
1744 		pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
1745 		pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
1746 	}
1747 	/* Initialize current values. */
1748 	pkt_dev->cur_dst_mac_offset = 0;
1749 	pkt_dev->cur_src_mac_offset = 0;
1750 	pkt_dev->cur_saddr = pkt_dev->saddr_min;
1751 	pkt_dev->cur_daddr = pkt_dev->daddr_min;
1752 	pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
1753 	pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
1754 	pkt_dev->nflows = 0;
1755 }
1756 
1757 static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
1758 {
1759 	__u64 start;
1760 	__u64 now;
1761 
1762 	start = now = getCurUs();
1763 	printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
1764 	while (now < spin_until_us) {
1765 		/* TODO: optimize sleeping behavior */
1766 		if (spin_until_us - now > jiffies_to_usecs(1) + 1)
1767 			schedule_timeout_interruptible(1);
1768 		else if (spin_until_us - now > 100) {
1769 			do_softirq();
1770 			if (!pkt_dev->running)
1771 				return;
1772 			if (need_resched())
1773 				schedule();
1774 		}
1775 
1776 		now = getCurUs();
1777 	}
1778 
1779 	pkt_dev->idle_acc += now - start;
1780 }
1781 
1782 /* Increment/randomize headers according to flags and current values
1783  * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
1784  */
1785 static void mod_cur_headers(struct pktgen_dev *pkt_dev)
1786 {
1787 	__u32 imn;
1788 	__u32 imx;
1789 	int flow = 0;
1790 
1791 	if (pkt_dev->cflows) {
1792 		flow = pktgen_random() % pkt_dev->cflows;
1793 
1794 		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
1795 			pkt_dev->flows[flow].count = 0;
1796 	}
1797 
1798 	/*  Deal with source MAC */
1799 	if (pkt_dev->src_mac_count > 1) {
1800 		__u32 mc;
1801 		__u32 tmp;
1802 
1803 		if (pkt_dev->flags & F_MACSRC_RND)
1804 			mc = pktgen_random() % (pkt_dev->src_mac_count);
1805 		else {
1806 			mc = pkt_dev->cur_src_mac_offset++;
1807 			if (pkt_dev->cur_src_mac_offset >
1808 			    pkt_dev->src_mac_count)
1809 				pkt_dev->cur_src_mac_offset = 0;
1810 		}
1811 
1812 		tmp = pkt_dev->src_mac[5] + (mc & 0xFF);
1813 		pkt_dev->hh[11] = tmp;
1814 		tmp = (pkt_dev->src_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
1815 		pkt_dev->hh[10] = tmp;
1816 		tmp = (pkt_dev->src_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
1817 		pkt_dev->hh[9] = tmp;
1818 		tmp = (pkt_dev->src_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
1819 		pkt_dev->hh[8] = tmp;
1820 		tmp = (pkt_dev->src_mac[1] + (tmp >> 8));
1821 		pkt_dev->hh[7] = tmp;
1822 	}
1823 
1824 	/*  Deal with Destination MAC */
1825 	if (pkt_dev->dst_mac_count > 1) {
1826 		__u32 mc;
1827 		__u32 tmp;
1828 
1829 		if (pkt_dev->flags & F_MACDST_RND)
1830 			mc = pktgen_random() % (pkt_dev->dst_mac_count);
1831 
1832 		else {
1833 			mc = pkt_dev->cur_dst_mac_offset++;
1834 			if (pkt_dev->cur_dst_mac_offset >
1835 			    pkt_dev->dst_mac_count) {
1836 				pkt_dev->cur_dst_mac_offset = 0;
1837 			}
1838 		}
1839 
1840 		tmp = pkt_dev->dst_mac[5] + (mc & 0xFF);
1841 		pkt_dev->hh[5] = tmp;
1842 		tmp = (pkt_dev->dst_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
1843 		pkt_dev->hh[4] = tmp;
1844 		tmp = (pkt_dev->dst_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
1845 		pkt_dev->hh[3] = tmp;
1846 		tmp = (pkt_dev->dst_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
1847 		pkt_dev->hh[2] = tmp;
1848 		tmp = (pkt_dev->dst_mac[1] + (tmp >> 8));
1849 		pkt_dev->hh[1] = tmp;
1850 	}
1851 
1852 	if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
1853 		if (pkt_dev->flags & F_UDPSRC_RND)
1854 			pkt_dev->cur_udp_src =
1855 			    ((pktgen_random() %
1856 			      (pkt_dev->udp_src_max - pkt_dev->udp_src_min)) +
1857 			     pkt_dev->udp_src_min);
1858 
1859 		else {
1860 			pkt_dev->cur_udp_src++;
1861 			if (pkt_dev->cur_udp_src >= pkt_dev->udp_src_max)
1862 				pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
1863 		}
1864 	}
1865 
1866 	if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) {
1867 		if (pkt_dev->flags & F_UDPDST_RND) {
1868 			pkt_dev->cur_udp_dst =
1869 			    ((pktgen_random() %
1870 			      (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min)) +
1871 			     pkt_dev->udp_dst_min);
1872 		} else {
1873 			pkt_dev->cur_udp_dst++;
1874 			if (pkt_dev->cur_udp_dst >= pkt_dev->udp_dst_max)
1875 				pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
1876 		}
1877 	}
1878 
1879 	if (!(pkt_dev->flags & F_IPV6)) {
1880 
1881 		if ((imn = ntohl(pkt_dev->saddr_min)) < (imx =
1882 							 ntohl(pkt_dev->
1883 							       saddr_max))) {
1884 			__u32 t;
1885 			if (pkt_dev->flags & F_IPSRC_RND)
1886 				t = ((pktgen_random() % (imx - imn)) + imn);
1887 			else {
1888 				t = ntohl(pkt_dev->cur_saddr);
1889 				t++;
1890 				if (t > imx) {
1891 					t = imn;
1892 				}
1893 			}
1894 			pkt_dev->cur_saddr = htonl(t);
1895 		}
1896 
1897 		if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
1898 			pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
1899 		} else {
1900 
1901 			if ((imn = ntohl(pkt_dev->daddr_min)) < (imx =
1902 								 ntohl(pkt_dev->
1903 								       daddr_max)))
1904 			{
1905 				__u32 t;
1906 				if (pkt_dev->flags & F_IPDST_RND) {
1907 
1908 					t = ((pktgen_random() % (imx - imn)) +
1909 					     imn);
1910 					t = htonl(t);
1911 
1912 					while (LOOPBACK(t) || MULTICAST(t)
1913 					       || BADCLASS(t) || ZERONET(t)
1914 					       || LOCAL_MCAST(t)) {
1915 						t = ((pktgen_random() %
1916 						      (imx - imn)) + imn);
1917 						t = htonl(t);
1918 					}
1919 					pkt_dev->cur_daddr = t;
1920 				}
1921 
1922 				else {
1923 					t = ntohl(pkt_dev->cur_daddr);
1924 					t++;
1925 					if (t > imx) {
1926 						t = imn;
1927 					}
1928 					pkt_dev->cur_daddr = htonl(t);
1929 				}
1930 			}
1931 			if (pkt_dev->cflows) {
1932 				pkt_dev->flows[flow].cur_daddr =
1933 				    pkt_dev->cur_daddr;
1934 				pkt_dev->nflows++;
1935 			}
1936 		}
1937 	} else {		/* IPV6 * */
1938 
1939 		if (pkt_dev->min_in6_daddr.s6_addr32[0] == 0 &&
1940 		    pkt_dev->min_in6_daddr.s6_addr32[1] == 0 &&
1941 		    pkt_dev->min_in6_daddr.s6_addr32[2] == 0 &&
1942 		    pkt_dev->min_in6_daddr.s6_addr32[3] == 0) ;
1943 		else {
1944 			int i;
1945 
1946 			/* Only random destinations yet */
1947 
1948 			for (i = 0; i < 4; i++) {
1949 				pkt_dev->cur_in6_daddr.s6_addr32[i] =
1950 				    ((pktgen_random() |
1951 				      pkt_dev->min_in6_daddr.s6_addr32[i]) &
1952 				     pkt_dev->max_in6_daddr.s6_addr32[i]);
1953 			}
1954 		}
1955 	}
1956 
1957 	if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) {
1958 		__u32 t;
1959 		if (pkt_dev->flags & F_TXSIZE_RND) {
1960 			t = ((pktgen_random() %
1961 			      (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size))
1962 			     + pkt_dev->min_pkt_size);
1963 		} else {
1964 			t = pkt_dev->cur_pkt_size + 1;
1965 			if (t > pkt_dev->max_pkt_size)
1966 				t = pkt_dev->min_pkt_size;
1967 		}
1968 		pkt_dev->cur_pkt_size = t;
1969 	}
1970 
1971 	pkt_dev->flows[flow].count++;
1972 }
1973 
1974 static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
1975 					struct pktgen_dev *pkt_dev)
1976 {
1977 	struct sk_buff *skb = NULL;
1978 	__u8 *eth;
1979 	struct udphdr *udph;
1980 	int datalen, iplen;
1981 	struct iphdr *iph;
1982 	struct pktgen_hdr *pgh = NULL;
1983 
1984 	/* Update any of the values, used when we're incrementing various
1985 	 * fields.
1986 	 */
1987 	mod_cur_headers(pkt_dev);
1988 
1989 	datalen = (odev->hard_header_len + 16) & ~0xf;
1990 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC);
1991 	if (!skb) {
1992 		sprintf(pkt_dev->result, "No memory");
1993 		return NULL;
1994 	}
1995 
1996 	skb_reserve(skb, datalen);
1997 
1998 	/*  Reserve for ethernet and IP header  */
1999 	eth = (__u8 *) skb_push(skb, 14);
2000 	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
2001 	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2002 
2003 	memcpy(eth, pkt_dev->hh, 12);
2004 	*(u16 *) & eth[12] = __constant_htons(ETH_P_IP);
2005 
2006 	datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8;	/* Eth + IPh + UDPh */
2007 	if (datalen < sizeof(struct pktgen_hdr))
2008 		datalen = sizeof(struct pktgen_hdr);
2009 
2010 	udph->source = htons(pkt_dev->cur_udp_src);
2011 	udph->dest = htons(pkt_dev->cur_udp_dst);
2012 	udph->len = htons(datalen + 8);	/* DATA + udphdr */
2013 	udph->check = 0;	/* No checksum */
2014 
2015 	iph->ihl = 5;
2016 	iph->version = 4;
2017 	iph->ttl = 32;
2018 	iph->tos = 0;
2019 	iph->protocol = IPPROTO_UDP;	/* UDP */
2020 	iph->saddr = pkt_dev->cur_saddr;
2021 	iph->daddr = pkt_dev->cur_daddr;
2022 	iph->frag_off = 0;
2023 	iplen = 20 + 8 + datalen;
2024 	iph->tot_len = htons(iplen);
2025 	iph->check = 0;
2026 	iph->check = ip_fast_csum((void *)iph, iph->ihl);
2027 	skb->protocol = __constant_htons(ETH_P_IP);
2028 	skb->mac.raw = ((u8 *) iph) - 14;
2029 	skb->dev = odev;
2030 	skb->pkt_type = PACKET_HOST;
2031 
2032 	if (pkt_dev->nfrags <= 0)
2033 		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
2034 	else {
2035 		int frags = pkt_dev->nfrags;
2036 		int i;
2037 
2038 		pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
2039 
2040 		if (frags > MAX_SKB_FRAGS)
2041 			frags = MAX_SKB_FRAGS;
2042 		if (datalen > frags * PAGE_SIZE) {
2043 			skb_put(skb, datalen - frags * PAGE_SIZE);
2044 			datalen = frags * PAGE_SIZE;
2045 		}
2046 
2047 		i = 0;
2048 		while (datalen > 0) {
2049 			struct page *page = alloc_pages(GFP_KERNEL, 0);
2050 			skb_shinfo(skb)->frags[i].page = page;
2051 			skb_shinfo(skb)->frags[i].page_offset = 0;
2052 			skb_shinfo(skb)->frags[i].size =
2053 			    (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
2054 			datalen -= skb_shinfo(skb)->frags[i].size;
2055 			skb->len += skb_shinfo(skb)->frags[i].size;
2056 			skb->data_len += skb_shinfo(skb)->frags[i].size;
2057 			i++;
2058 			skb_shinfo(skb)->nr_frags = i;
2059 		}
2060 
2061 		while (i < frags) {
2062 			int rem;
2063 
2064 			if (i == 0)
2065 				break;
2066 
2067 			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
2068 			if (rem == 0)
2069 				break;
2070 
2071 			skb_shinfo(skb)->frags[i - 1].size -= rem;
2072 
2073 			skb_shinfo(skb)->frags[i] =
2074 			    skb_shinfo(skb)->frags[i - 1];
2075 			get_page(skb_shinfo(skb)->frags[i].page);
2076 			skb_shinfo(skb)->frags[i].page =
2077 			    skb_shinfo(skb)->frags[i - 1].page;
2078 			skb_shinfo(skb)->frags[i].page_offset +=
2079 			    skb_shinfo(skb)->frags[i - 1].size;
2080 			skb_shinfo(skb)->frags[i].size = rem;
2081 			i++;
2082 			skb_shinfo(skb)->nr_frags = i;
2083 		}
2084 	}
2085 
2086 	/* Stamp the time, and sequence number, convert them to network byte order */
2087 
2088 	if (pgh) {
2089 		struct timeval timestamp;
2090 
2091 		pgh->pgh_magic = htonl(PKTGEN_MAGIC);
2092 		pgh->seq_num = htonl(pkt_dev->seq_num);
2093 
2094 		do_gettimeofday(&timestamp);
2095 		pgh->tv_sec = htonl(timestamp.tv_sec);
2096 		pgh->tv_usec = htonl(timestamp.tv_usec);
2097 	}
2098 	pkt_dev->seq_num++;
2099 
2100 	return skb;
2101 }
2102 
2103 /*
2104  * scan_ip6, fmt_ip taken from dietlibc-0.21
2105  * Author Felix von Leitner <felix-dietlibc@fefe.de>
2106  *
2107  * Slightly modified for kernel.
2108  * Should be candidate for net/ipv4/utils.c
2109  * --ro
2110  */
2111 
2112 static unsigned int scan_ip6(const char *s, char ip[16])
2113 {
2114 	unsigned int i;
2115 	unsigned int len = 0;
2116 	unsigned long u;
2117 	char suffix[16];
2118 	unsigned int prefixlen = 0;
2119 	unsigned int suffixlen = 0;
2120 	__u32 tmp;
2121 
2122 	for (i = 0; i < 16; i++)
2123 		ip[i] = 0;
2124 
2125 	for (;;) {
2126 		if (*s == ':') {
2127 			len++;
2128 			if (s[1] == ':') {	/* Found "::", skip to part 2 */
2129 				s += 2;
2130 				len++;
2131 				break;
2132 			}
2133 			s++;
2134 		}
2135 		{
2136 			char *tmp;
2137 			u = simple_strtoul(s, &tmp, 16);
2138 			i = tmp - s;
2139 		}
2140 
2141 		if (!i)
2142 			return 0;
2143 		if (prefixlen == 12 && s[i] == '.') {
2144 
2145 			/* the last 4 bytes may be written as IPv4 address */
2146 
2147 			tmp = in_aton(s);
2148 			memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp));
2149 			return i + len;
2150 		}
2151 		ip[prefixlen++] = (u >> 8);
2152 		ip[prefixlen++] = (u & 255);
2153 		s += i;
2154 		len += i;
2155 		if (prefixlen == 16)
2156 			return len;
2157 	}
2158 
2159 /* part 2, after "::" */
2160 	for (;;) {
2161 		if (*s == ':') {
2162 			if (suffixlen == 0)
2163 				break;
2164 			s++;
2165 			len++;
2166 		} else if (suffixlen != 0)
2167 			break;
2168 		{
2169 			char *tmp;
2170 			u = simple_strtol(s, &tmp, 16);
2171 			i = tmp - s;
2172 		}
2173 		if (!i) {
2174 			if (*s)
2175 				len--;
2176 			break;
2177 		}
2178 		if (suffixlen + prefixlen <= 12 && s[i] == '.') {
2179 			tmp = in_aton(s);
2180 			memcpy((struct in_addr *)(suffix + suffixlen), &tmp,
2181 			       sizeof(tmp));
2182 			suffixlen += 4;
2183 			len += strlen(s);
2184 			break;
2185 		}
2186 		suffix[suffixlen++] = (u >> 8);
2187 		suffix[suffixlen++] = (u & 255);
2188 		s += i;
2189 		len += i;
2190 		if (prefixlen + suffixlen == 16)
2191 			break;
2192 	}
2193 	for (i = 0; i < suffixlen; i++)
2194 		ip[16 - suffixlen + i] = suffix[i];
2195 	return len;
2196 }
2197 
2198 static char tohex(char hexdigit)
2199 {
2200 	return hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
2201 }
2202 
2203 static int fmt_xlong(char *s, unsigned int i)
2204 {
2205 	char *bak = s;
2206 	*s = tohex((i >> 12) & 0xf);
2207 	if (s != bak || *s != '0')
2208 		++s;
2209 	*s = tohex((i >> 8) & 0xf);
2210 	if (s != bak || *s != '0')
2211 		++s;
2212 	*s = tohex((i >> 4) & 0xf);
2213 	if (s != bak || *s != '0')
2214 		++s;
2215 	*s = tohex(i & 0xf);
2216 	return s - bak + 1;
2217 }
2218 
2219 static unsigned int fmt_ip6(char *s, const char ip[16])
2220 {
2221 	unsigned int len;
2222 	unsigned int i;
2223 	unsigned int temp;
2224 	unsigned int compressing;
2225 	int j;
2226 
2227 	len = 0;
2228 	compressing = 0;
2229 	for (j = 0; j < 16; j += 2) {
2230 
2231 #ifdef V4MAPPEDPREFIX
2232 		if (j == 12 && !memcmp(ip, V4mappedprefix, 12)) {
2233 			inet_ntoa_r(*(struct in_addr *)(ip + 12), s);
2234 			temp = strlen(s);
2235 			return len + temp;
2236 		}
2237 #endif
2238 		temp = ((unsigned long)(unsigned char)ip[j] << 8) +
2239 		    (unsigned long)(unsigned char)ip[j + 1];
2240 		if (temp == 0) {
2241 			if (!compressing) {
2242 				compressing = 1;
2243 				if (j == 0) {
2244 					*s++ = ':';
2245 					++len;
2246 				}
2247 			}
2248 		} else {
2249 			if (compressing) {
2250 				compressing = 0;
2251 				*s++ = ':';
2252 				++len;
2253 			}
2254 			i = fmt_xlong(s, temp);
2255 			len += i;
2256 			s += i;
2257 			if (j < 14) {
2258 				*s++ = ':';
2259 				++len;
2260 			}
2261 		}
2262 	}
2263 	if (compressing) {
2264 		*s++ = ':';
2265 		++len;
2266 	}
2267 	*s = 0;
2268 	return len;
2269 }
2270 
2271 static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2272 					struct pktgen_dev *pkt_dev)
2273 {
2274 	struct sk_buff *skb = NULL;
2275 	__u8 *eth;
2276 	struct udphdr *udph;
2277 	int datalen;
2278 	struct ipv6hdr *iph;
2279 	struct pktgen_hdr *pgh = NULL;
2280 
2281 	/* Update any of the values, used when we're incrementing various
2282 	 * fields.
2283 	 */
2284 	mod_cur_headers(pkt_dev);
2285 
2286 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
2287 	if (!skb) {
2288 		sprintf(pkt_dev->result, "No memory");
2289 		return NULL;
2290 	}
2291 
2292 	skb_reserve(skb, 16);
2293 
2294 	/*  Reserve for ethernet and IP header  */
2295 	eth = (__u8 *) skb_push(skb, 14);
2296 	iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
2297 	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2298 
2299 	memcpy(eth, pkt_dev->hh, 12);
2300 	*(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6);
2301 
2302 	datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr);	/* Eth + IPh + UDPh */
2303 
2304 	if (datalen < sizeof(struct pktgen_hdr)) {
2305 		datalen = sizeof(struct pktgen_hdr);
2306 		if (net_ratelimit())
2307 			printk(KERN_INFO "pktgen: increased datalen to %d\n",
2308 			       datalen);
2309 	}
2310 
2311 	udph->source = htons(pkt_dev->cur_udp_src);
2312 	udph->dest = htons(pkt_dev->cur_udp_dst);
2313 	udph->len = htons(datalen + sizeof(struct udphdr));
2314 	udph->check = 0;	/* No checksum */
2315 
2316 	*(u32 *) iph = __constant_htonl(0x60000000);	/* Version + flow */
2317 
2318 	iph->hop_limit = 32;
2319 
2320 	iph->payload_len = htons(sizeof(struct udphdr) + datalen);
2321 	iph->nexthdr = IPPROTO_UDP;
2322 
2323 	ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
2324 	ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
2325 
2326 	skb->mac.raw = ((u8 *) iph) - 14;
2327 	skb->protocol = __constant_htons(ETH_P_IPV6);
2328 	skb->dev = odev;
2329 	skb->pkt_type = PACKET_HOST;
2330 
2331 	if (pkt_dev->nfrags <= 0)
2332 		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
2333 	else {
2334 		int frags = pkt_dev->nfrags;
2335 		int i;
2336 
2337 		pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8);
2338 
2339 		if (frags > MAX_SKB_FRAGS)
2340 			frags = MAX_SKB_FRAGS;
2341 		if (datalen > frags * PAGE_SIZE) {
2342 			skb_put(skb, datalen - frags * PAGE_SIZE);
2343 			datalen = frags * PAGE_SIZE;
2344 		}
2345 
2346 		i = 0;
2347 		while (datalen > 0) {
2348 			struct page *page = alloc_pages(GFP_KERNEL, 0);
2349 			skb_shinfo(skb)->frags[i].page = page;
2350 			skb_shinfo(skb)->frags[i].page_offset = 0;
2351 			skb_shinfo(skb)->frags[i].size =
2352 			    (datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
2353 			datalen -= skb_shinfo(skb)->frags[i].size;
2354 			skb->len += skb_shinfo(skb)->frags[i].size;
2355 			skb->data_len += skb_shinfo(skb)->frags[i].size;
2356 			i++;
2357 			skb_shinfo(skb)->nr_frags = i;
2358 		}
2359 
2360 		while (i < frags) {
2361 			int rem;
2362 
2363 			if (i == 0)
2364 				break;
2365 
2366 			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
2367 			if (rem == 0)
2368 				break;
2369 
2370 			skb_shinfo(skb)->frags[i - 1].size -= rem;
2371 
2372 			skb_shinfo(skb)->frags[i] =
2373 			    skb_shinfo(skb)->frags[i - 1];
2374 			get_page(skb_shinfo(skb)->frags[i].page);
2375 			skb_shinfo(skb)->frags[i].page =
2376 			    skb_shinfo(skb)->frags[i - 1].page;
2377 			skb_shinfo(skb)->frags[i].page_offset +=
2378 			    skb_shinfo(skb)->frags[i - 1].size;
2379 			skb_shinfo(skb)->frags[i].size = rem;
2380 			i++;
2381 			skb_shinfo(skb)->nr_frags = i;
2382 		}
2383 	}
2384 
2385 	/* Stamp the time, and sequence number, convert them to network byte order */
2386 	/* should we update cloned packets too ? */
2387 	if (pgh) {
2388 		struct timeval timestamp;
2389 
2390 		pgh->pgh_magic = htonl(PKTGEN_MAGIC);
2391 		pgh->seq_num = htonl(pkt_dev->seq_num);
2392 
2393 		do_gettimeofday(&timestamp);
2394 		pgh->tv_sec = htonl(timestamp.tv_sec);
2395 		pgh->tv_usec = htonl(timestamp.tv_usec);
2396 	}
2397 	pkt_dev->seq_num++;
2398 
2399 	return skb;
2400 }
2401 
2402 static inline struct sk_buff *fill_packet(struct net_device *odev,
2403 					  struct pktgen_dev *pkt_dev)
2404 {
2405 	if (pkt_dev->flags & F_IPV6)
2406 		return fill_packet_ipv6(odev, pkt_dev);
2407 	else
2408 		return fill_packet_ipv4(odev, pkt_dev);
2409 }
2410 
2411 static void pktgen_clear_counters(struct pktgen_dev *pkt_dev)
2412 {
2413 	pkt_dev->seq_num = 1;
2414 	pkt_dev->idle_acc = 0;
2415 	pkt_dev->sofar = 0;
2416 	pkt_dev->tx_bytes = 0;
2417 	pkt_dev->errors = 0;
2418 }
2419 
2420 /* Set up structure for sending pkts, clear counters */
2421 
2422 static void pktgen_run(struct pktgen_thread *t)
2423 {
2424 	struct pktgen_dev *pkt_dev = NULL;
2425 	int started = 0;
2426 
2427 	PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
2428 
2429 	if_lock(t);
2430 	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
2431 
2432 		/*
2433 		 * setup odev and create initial packet.
2434 		 */
2435 		pktgen_setup_inject(pkt_dev);
2436 
2437 		if (pkt_dev->odev) {
2438 			pktgen_clear_counters(pkt_dev);
2439 			pkt_dev->running = 1;	/* Cranke yeself! */
2440 			pkt_dev->skb = NULL;
2441 			pkt_dev->started_at = getCurUs();
2442 			pkt_dev->next_tx_us = getCurUs();	/* Transmit immediately */
2443 			pkt_dev->next_tx_ns = 0;
2444 
2445 			strcpy(pkt_dev->result, "Starting");
2446 			started++;
2447 		} else
2448 			strcpy(pkt_dev->result, "Error starting");
2449 	}
2450 	if_unlock(t);
2451 	if (started)
2452 		t->control &= ~(T_STOP);
2453 }
2454 
2455 static void pktgen_stop_all_threads_ifs(void)
2456 {
2457 	struct pktgen_thread *t;
2458 
2459 	PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n"));
2460 
2461 	thread_lock();
2462 
2463 	list_for_each_entry(t, &pktgen_threads, th_list)
2464 		t->control |= T_STOP;
2465 
2466 	thread_unlock();
2467 }
2468 
2469 static int thread_is_running(struct pktgen_thread *t)
2470 {
2471 	struct pktgen_dev *next;
2472 	int res = 0;
2473 
2474 	for (next = t->if_list; next; next = next->next) {
2475 		if (next->running) {
2476 			res = 1;
2477 			break;
2478 		}
2479 	}
2480 	return res;
2481 }
2482 
2483 static int pktgen_wait_thread_run(struct pktgen_thread *t)
2484 {
2485 	if_lock(t);
2486 
2487 	while (thread_is_running(t)) {
2488 
2489 		if_unlock(t);
2490 
2491 		msleep_interruptible(100);
2492 
2493 		if (signal_pending(current))
2494 			goto signal;
2495 		if_lock(t);
2496 	}
2497 	if_unlock(t);
2498 	return 1;
2499 signal:
2500 	return 0;
2501 }
2502 
2503 static int pktgen_wait_all_threads_run(void)
2504 {
2505 	struct pktgen_thread *t;
2506 	int sig = 1;
2507 
2508 	thread_lock();
2509 
2510 	list_for_each_entry(t, &pktgen_threads, th_list) {
2511 		sig = pktgen_wait_thread_run(t);
2512 		if (sig == 0)
2513 			break;
2514 	}
2515 
2516 	if (sig == 0)
2517 		list_for_each_entry(t, &pktgen_threads, th_list)
2518 			t->control |= (T_STOP);
2519 
2520 	thread_unlock();
2521 	return sig;
2522 }
2523 
2524 static void pktgen_run_all_threads(void)
2525 {
2526 	struct pktgen_thread *t;
2527 
2528 	PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
2529 
2530 	thread_lock();
2531 
2532 	list_for_each_entry(t, &pktgen_threads, th_list)
2533 		t->control |= (T_RUN);
2534 
2535 	thread_unlock();
2536 
2537 	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
2538 
2539 	pktgen_wait_all_threads_run();
2540 }
2541 
2542 static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
2543 {
2544 	__u64 total_us, bps, mbps, pps, idle;
2545 	char *p = pkt_dev->result;
2546 
2547 	total_us = pkt_dev->stopped_at - pkt_dev->started_at;
2548 
2549 	idle = pkt_dev->idle_acc;
2550 
2551 	p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
2552 		     (unsigned long long)total_us,
2553 		     (unsigned long long)(total_us - idle),
2554 		     (unsigned long long)idle,
2555 		     (unsigned long long)pkt_dev->sofar,
2556 		     pkt_dev->cur_pkt_size, nr_frags);
2557 
2558 	pps = pkt_dev->sofar * USEC_PER_SEC;
2559 
2560 	while ((total_us >> 32) != 0) {
2561 		pps >>= 1;
2562 		total_us >>= 1;
2563 	}
2564 
2565 	do_div(pps, total_us);
2566 
2567 	bps = pps * 8 * pkt_dev->cur_pkt_size;
2568 
2569 	mbps = bps;
2570 	do_div(mbps, 1000000);
2571 	p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",
2572 		     (unsigned long long)pps,
2573 		     (unsigned long long)mbps,
2574 		     (unsigned long long)bps,
2575 		     (unsigned long long)pkt_dev->errors);
2576 }
2577 
2578 /* Set stopped-at timer, remove from running list, do counters & statistics */
2579 
2580 static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
2581 {
2582 	int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1;
2583 
2584 	if (!pkt_dev->running) {
2585 		printk("pktgen: interface: %s is already stopped\n",
2586 		       pkt_dev->ifname);
2587 		return -EINVAL;
2588 	}
2589 
2590 	pkt_dev->stopped_at = getCurUs();
2591 	pkt_dev->running = 0;
2592 
2593 	show_results(pkt_dev, nr_frags);
2594 
2595 	return 0;
2596 }
2597 
2598 static struct pktgen_dev *next_to_run(struct pktgen_thread *t)
2599 {
2600 	struct pktgen_dev *next, *best = NULL;
2601 
2602 	if_lock(t);
2603 
2604 	for (next = t->if_list; next; next = next->next) {
2605 		if (!next->running)
2606 			continue;
2607 		if (best == NULL)
2608 			best = next;
2609 		else if (next->next_tx_us < best->next_tx_us)
2610 			best = next;
2611 	}
2612 	if_unlock(t);
2613 	return best;
2614 }
2615 
2616 static void pktgen_stop(struct pktgen_thread *t)
2617 {
2618 	struct pktgen_dev *next = NULL;
2619 
2620 	PG_DEBUG(printk("pktgen: entering pktgen_stop\n"));
2621 
2622 	if_lock(t);
2623 
2624 	for (next = t->if_list; next; next = next->next) {
2625 		pktgen_stop_device(next);
2626 		if (next->skb)
2627 			kfree_skb(next->skb);
2628 
2629 		next->skb = NULL;
2630 	}
2631 
2632 	if_unlock(t);
2633 }
2634 
2635 /*
2636  * one of our devices needs to be removed - find it
2637  * and remove it
2638  */
2639 static void pktgen_rem_one_if(struct pktgen_thread *t)
2640 {
2641 	struct pktgen_dev *cur, *next = NULL;
2642 
2643 	PG_DEBUG(printk("pktgen: entering pktgen_rem_one_if\n"));
2644 
2645 	if_lock(t);
2646 
2647 	for (cur = t->if_list; cur; cur = next) {
2648 		next = cur->next;
2649 
2650 		if (!cur->removal_mark)
2651 			continue;
2652 
2653 		if (cur->skb)
2654 			kfree_skb(cur->skb);
2655 		cur->skb = NULL;
2656 
2657 		pktgen_remove_device(t, cur);
2658 
2659 		break;
2660 	}
2661 
2662 	if_unlock(t);
2663 }
2664 
2665 static void pktgen_rem_all_ifs(struct pktgen_thread *t)
2666 {
2667 	struct pktgen_dev *cur, *next = NULL;
2668 
2669 	/* Remove all devices, free mem */
2670 
2671 	PG_DEBUG(printk("pktgen: entering pktgen_rem_all_ifs\n"));
2672 	if_lock(t);
2673 
2674 	for (cur = t->if_list; cur; cur = next) {
2675 		next = cur->next;
2676 
2677 		if (cur->skb)
2678 			kfree_skb(cur->skb);
2679 		cur->skb = NULL;
2680 
2681 		pktgen_remove_device(t, cur);
2682 	}
2683 
2684 	if_unlock(t);
2685 }
2686 
2687 static void pktgen_rem_thread(struct pktgen_thread *t)
2688 {
2689 	/* Remove from the thread list */
2690 
2691 	remove_proc_entry(t->name, pg_proc_dir);
2692 
2693 	thread_lock();
2694 
2695 	list_del(&t->th_list);
2696 
2697 	thread_unlock();
2698 }
2699 
2700 static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
2701 {
2702 	struct net_device *odev = NULL;
2703 	__u64 idle_start = 0;
2704 	int ret;
2705 
2706 	odev = pkt_dev->odev;
2707 
2708 	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
2709 		u64 now;
2710 
2711 		now = getCurUs();
2712 		if (now < pkt_dev->next_tx_us)
2713 			spin(pkt_dev, pkt_dev->next_tx_us);
2714 
2715 		/* This is max DELAY, this has special meaning of
2716 		 * "never transmit"
2717 		 */
2718 		if (pkt_dev->delay_us == 0x7FFFFFFF) {
2719 			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
2720 			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
2721 			goto out;
2722 		}
2723 	}
2724 
2725 	if (netif_queue_stopped(odev) || need_resched()) {
2726 		idle_start = getCurUs();
2727 
2728 		if (!netif_running(odev)) {
2729 			pktgen_stop_device(pkt_dev);
2730 			if (pkt_dev->skb)
2731 				kfree_skb(pkt_dev->skb);
2732 			pkt_dev->skb = NULL;
2733 			goto out;
2734 		}
2735 		if (need_resched())
2736 			schedule();
2737 
2738 		pkt_dev->idle_acc += getCurUs() - idle_start;
2739 
2740 		if (netif_queue_stopped(odev)) {
2741 			pkt_dev->next_tx_us = getCurUs();	/* TODO */
2742 			pkt_dev->next_tx_ns = 0;
2743 			goto out;	/* Try the next interface */
2744 		}
2745 	}
2746 
2747 	if (pkt_dev->last_ok || !pkt_dev->skb) {
2748 		if ((++pkt_dev->clone_count >= pkt_dev->clone_skb)
2749 		    || (!pkt_dev->skb)) {
2750 			/* build a new pkt */
2751 			if (pkt_dev->skb)
2752 				kfree_skb(pkt_dev->skb);
2753 
2754 			pkt_dev->skb = fill_packet(odev, pkt_dev);
2755 			if (pkt_dev->skb == NULL) {
2756 				printk("pktgen: ERROR: couldn't allocate skb in fill_packet.\n");
2757 				schedule();
2758 				pkt_dev->clone_count--;	/* back out increment, OOM */
2759 				goto out;
2760 			}
2761 			pkt_dev->allocated_skbs++;
2762 			pkt_dev->clone_count = 0;	/* reset counter */
2763 		}
2764 	}
2765 
2766 	spin_lock_bh(&odev->xmit_lock);
2767 	if (!netif_queue_stopped(odev)) {
2768 
2769 		atomic_inc(&(pkt_dev->skb->users));
2770 	      retry_now:
2771 		ret = odev->hard_start_xmit(pkt_dev->skb, odev);
2772 		if (likely(ret == NETDEV_TX_OK)) {
2773 			pkt_dev->last_ok = 1;
2774 			pkt_dev->sofar++;
2775 			pkt_dev->seq_num++;
2776 			pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
2777 
2778 		} else if (ret == NETDEV_TX_LOCKED
2779 			   && (odev->features & NETIF_F_LLTX)) {
2780 			cpu_relax();
2781 			goto retry_now;
2782 		} else {	/* Retry it next time */
2783 
2784 			atomic_dec(&(pkt_dev->skb->users));
2785 
2786 			if (debug && net_ratelimit())
2787 				printk(KERN_INFO "pktgen: Hard xmit error\n");
2788 
2789 			pkt_dev->errors++;
2790 			pkt_dev->last_ok = 0;
2791 		}
2792 
2793 		pkt_dev->next_tx_us = getCurUs();
2794 		pkt_dev->next_tx_ns = 0;
2795 
2796 		pkt_dev->next_tx_us += pkt_dev->delay_us;
2797 		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
2798 
2799 		if (pkt_dev->next_tx_ns > 1000) {
2800 			pkt_dev->next_tx_us++;
2801 			pkt_dev->next_tx_ns -= 1000;
2802 		}
2803 	}
2804 
2805 	else {			/* Retry it next time */
2806 		pkt_dev->last_ok = 0;
2807 		pkt_dev->next_tx_us = getCurUs();	/* TODO */
2808 		pkt_dev->next_tx_ns = 0;
2809 	}
2810 
2811 	spin_unlock_bh(&odev->xmit_lock);
2812 
2813 	/* If pkt_dev->count is zero, then run forever */
2814 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
2815 		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
2816 			idle_start = getCurUs();
2817 			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
2818 				if (signal_pending(current)) {
2819 					break;
2820 				}
2821 				schedule();
2822 			}
2823 			pkt_dev->idle_acc += getCurUs() - idle_start;
2824 		}
2825 
2826 		/* Done with this */
2827 		pktgen_stop_device(pkt_dev);
2828 		if (pkt_dev->skb)
2829 			kfree_skb(pkt_dev->skb);
2830 		pkt_dev->skb = NULL;
2831 	}
2832 out:;
2833 }
2834 
2835 /*
2836  * Main loop of the thread goes here
2837  */
2838 
2839 static void pktgen_thread_worker(struct pktgen_thread *t)
2840 {
2841 	DEFINE_WAIT(wait);
2842 	struct pktgen_dev *pkt_dev = NULL;
2843 	int cpu = t->cpu;
2844 	sigset_t tmpsig;
2845 	u32 max_before_softirq;
2846 	u32 tx_since_softirq = 0;
2847 
2848 	daemonize("pktgen/%d", cpu);
2849 
2850 	/* Block all signals except SIGKILL, SIGSTOP and SIGTERM */
2851 
2852 	spin_lock_irq(&current->sighand->siglock);
2853 	tmpsig = current->blocked;
2854 	siginitsetinv(&current->blocked,
2855 		      sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM));
2856 
2857 	recalc_sigpending();
2858 	spin_unlock_irq(&current->sighand->siglock);
2859 
2860 	/* Migrate to the right CPU */
2861 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
2862 	if (smp_processor_id() != cpu)
2863 		BUG();
2864 
2865 	init_waitqueue_head(&t->queue);
2866 
2867 	t->control &= ~(T_TERMINATE);
2868 	t->control &= ~(T_RUN);
2869 	t->control &= ~(T_STOP);
2870 	t->control &= ~(T_REMDEVALL);
2871 	t->control &= ~(T_REMDEV);
2872 
2873 	t->pid = current->pid;
2874 
2875 	PG_DEBUG(printk("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid));
2876 
2877 	max_before_softirq = t->max_before_softirq;
2878 
2879 	__set_current_state(TASK_INTERRUPTIBLE);
2880 	mb();
2881 
2882 	while (1) {
2883 
2884 		__set_current_state(TASK_RUNNING);
2885 
2886 		/*
2887 		 * Get next dev to xmit -- if any.
2888 		 */
2889 
2890 		pkt_dev = next_to_run(t);
2891 
2892 		if (pkt_dev) {
2893 
2894 			pktgen_xmit(pkt_dev);
2895 
2896 			/*
2897 			 * We like to stay RUNNING but must also give
2898 			 * others fair share.
2899 			 */
2900 
2901 			tx_since_softirq += pkt_dev->last_ok;
2902 
2903 			if (tx_since_softirq > max_before_softirq) {
2904 				if (local_softirq_pending())
2905 					do_softirq();
2906 				tx_since_softirq = 0;
2907 			}
2908 		} else {
2909 			prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE);
2910 			schedule_timeout(HZ / 10);
2911 			finish_wait(&(t->queue), &wait);
2912 		}
2913 
2914 		/*
2915 		 * Back from sleep, either due to the timeout or signal.
2916 		 * We check if we have any "posted" work for us.
2917 		 */
2918 
2919 		if (t->control & T_TERMINATE || signal_pending(current))
2920 			/* we received a request to terminate ourself */
2921 			break;
2922 
2923 		if (t->control & T_STOP) {
2924 			pktgen_stop(t);
2925 			t->control &= ~(T_STOP);
2926 		}
2927 
2928 		if (t->control & T_RUN) {
2929 			pktgen_run(t);
2930 			t->control &= ~(T_RUN);
2931 		}
2932 
2933 		if (t->control & T_REMDEVALL) {
2934 			pktgen_rem_all_ifs(t);
2935 			t->control &= ~(T_REMDEVALL);
2936 		}
2937 
2938 		if (t->control & T_REMDEV) {
2939 			pktgen_rem_one_if(t);
2940 			t->control &= ~(T_REMDEV);
2941 		}
2942 
2943 		if (need_resched())
2944 			schedule();
2945 	}
2946 
2947 	PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name));
2948 	pktgen_stop(t);
2949 
2950 	PG_DEBUG(printk("pktgen: %s removing all device\n", t->name));
2951 	pktgen_rem_all_ifs(t);
2952 
2953 	PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
2954 	pktgen_rem_thread(t);
2955 
2956 	t->removed = 1;
2957 }
2958 
2959 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
2960 					  const char *ifname)
2961 {
2962 	struct pktgen_dev *pkt_dev = NULL;
2963 	if_lock(t);
2964 
2965 	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
2966 		if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
2967 			break;
2968 		}
2969 	}
2970 
2971 	if_unlock(t);
2972 	PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev));
2973 	return pkt_dev;
2974 }
2975 
2976 /*
2977  * Adds a dev at front of if_list.
2978  */
2979 
2980 static int add_dev_to_thread(struct pktgen_thread *t,
2981 			     struct pktgen_dev *pkt_dev)
2982 {
2983 	int rv = 0;
2984 
2985 	if_lock(t);
2986 
2987 	if (pkt_dev->pg_thread) {
2988 		printk("pktgen: ERROR:  already assigned to a thread.\n");
2989 		rv = -EBUSY;
2990 		goto out;
2991 	}
2992 	pkt_dev->next = t->if_list;
2993 	t->if_list = pkt_dev;
2994 	pkt_dev->pg_thread = t;
2995 	pkt_dev->running = 0;
2996 
2997 out:
2998 	if_unlock(t);
2999 	return rv;
3000 }
3001 
3002 /* Called under thread lock */
3003 
3004 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3005 {
3006 	struct pktgen_dev *pkt_dev;
3007 	struct proc_dir_entry *pe;
3008 
3009 	/* We don't allow a device to be on several threads */
3010 
3011 	pkt_dev = __pktgen_NN_threads(ifname, FIND);
3012 	if (pkt_dev) {
3013 		printk("pktgen: ERROR: interface already used.\n");
3014 		return -EBUSY;
3015 	}
3016 
3017 	pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
3018 	if (!pkt_dev)
3019 		return -ENOMEM;
3020 
3021 	pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state));
3022 	if (pkt_dev->flows == NULL) {
3023 		kfree(pkt_dev);
3024 		return -ENOMEM;
3025 	}
3026 	memset(pkt_dev->flows, 0, MAX_CFLOWS * sizeof(struct flow_state));
3027 
3028 	pkt_dev->removal_mark = 0;
3029 	pkt_dev->min_pkt_size = ETH_ZLEN;
3030 	pkt_dev->max_pkt_size = ETH_ZLEN;
3031 	pkt_dev->nfrags = 0;
3032 	pkt_dev->clone_skb = pg_clone_skb_d;
3033 	pkt_dev->delay_us = pg_delay_d / 1000;
3034 	pkt_dev->delay_ns = pg_delay_d % 1000;
3035 	pkt_dev->count = pg_count_d;
3036 	pkt_dev->sofar = 0;
3037 	pkt_dev->udp_src_min = 9;	/* sink port */
3038 	pkt_dev->udp_src_max = 9;
3039 	pkt_dev->udp_dst_min = 9;
3040 	pkt_dev->udp_dst_max = 9;
3041 
3042 	strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
3043 
3044 	if (!pktgen_setup_dev(pkt_dev)) {
3045 		printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
3046 		if (pkt_dev->flows)
3047 			vfree(pkt_dev->flows);
3048 		kfree(pkt_dev);
3049 		return -ENODEV;
3050 	}
3051 
3052 	pe = create_proc_entry(ifname, 0600, pg_proc_dir);
3053 	if (!pe) {
3054 		printk("pktgen: cannot create %s/%s procfs entry.\n",
3055 		       PG_PROC_DIR, ifname);
3056 		if (pkt_dev->flows)
3057 			vfree(pkt_dev->flows);
3058 		kfree(pkt_dev);
3059 		return -EINVAL;
3060 	}
3061 	pe->proc_fops = &pktgen_if_fops;
3062 	pe->data = pkt_dev;
3063 
3064 	return add_dev_to_thread(t, pkt_dev);
3065 }
3066 
3067 static struct pktgen_thread *__init pktgen_find_thread(const char *name)
3068 {
3069 	struct pktgen_thread *t;
3070 
3071 	thread_lock();
3072 
3073 	list_for_each_entry(t, &pktgen_threads, th_list)
3074 		if (strcmp(t->name, name) == 0) {
3075 			thread_unlock();
3076 			return t;
3077 		}
3078 
3079 	thread_unlock();
3080 	return NULL;
3081 }
3082 
3083 static int __init pktgen_create_thread(const char *name, int cpu)
3084 {
3085 	int err;
3086 	struct pktgen_thread *t = NULL;
3087 	struct proc_dir_entry *pe;
3088 
3089 	if (strlen(name) > 31) {
3090 		printk("pktgen: ERROR:  Thread name cannot be more than 31 characters.\n");
3091 		return -EINVAL;
3092 	}
3093 
3094 	if (pktgen_find_thread(name)) {
3095 		printk("pktgen: ERROR: thread: %s already exists\n", name);
3096 		return -EINVAL;
3097 	}
3098 
3099 	t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
3100 	if (!t) {
3101 		printk("pktgen: ERROR: out of memory, can't create new thread.\n");
3102 		return -ENOMEM;
3103 	}
3104 
3105 	strcpy(t->name, name);
3106 	spin_lock_init(&t->if_lock);
3107 	t->cpu = cpu;
3108 
3109 	pe = create_proc_entry(t->name, 0600, pg_proc_dir);
3110 	if (!pe) {
3111 		printk("pktgen: cannot create %s/%s procfs entry.\n",
3112 		       PG_PROC_DIR, t->name);
3113 		kfree(t);
3114 		return -EINVAL;
3115 	}
3116 
3117 	pe->proc_fops = &pktgen_thread_fops;
3118 	pe->data = t;
3119 
3120 	list_add_tail(&t->th_list, &pktgen_threads);
3121 
3122 	t->removed = 0;
3123 
3124 	err = kernel_thread((void *)pktgen_thread_worker, (void *)t,
3125 			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
3126 	if (err < 0) {
3127 		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
3128 		remove_proc_entry(t->name, pg_proc_dir);
3129 		list_del(&t->th_list);
3130 		kfree(t);
3131 		return err;
3132 	}
3133 
3134 	return 0;
3135 }
3136 
3137 /*
3138  * Removes a device from the thread if_list.
3139  */
3140 static void _rem_dev_from_if_list(struct pktgen_thread *t,
3141 				  struct pktgen_dev *pkt_dev)
3142 {
3143 	struct pktgen_dev *i, *prev = NULL;
3144 
3145 	i = t->if_list;
3146 
3147 	while (i) {
3148 		if (i == pkt_dev) {
3149 			if (prev)
3150 				prev->next = i->next;
3151 			else
3152 				t->if_list = NULL;
3153 			break;
3154 		}
3155 		prev = i;
3156 		i = i->next;
3157 	}
3158 }
3159 
3160 static int pktgen_remove_device(struct pktgen_thread *t,
3161 				struct pktgen_dev *pkt_dev)
3162 {
3163 
3164 	PG_DEBUG(printk("pktgen: remove_device pkt_dev=%p\n", pkt_dev));
3165 
3166 	if (pkt_dev->running) {
3167 		printk("pktgen:WARNING: trying to remove a running interface, stopping it now.\n");
3168 		pktgen_stop_device(pkt_dev);
3169 	}
3170 
3171 	/* Dis-associate from the interface */
3172 
3173 	if (pkt_dev->odev) {
3174 		dev_put(pkt_dev->odev);
3175 		pkt_dev->odev = NULL;
3176 	}
3177 
3178 	/* And update the thread if_list */
3179 
3180 	_rem_dev_from_if_list(t, pkt_dev);
3181 
3182 	/* Clean up proc file system */
3183 
3184 	remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
3185 
3186 	if (pkt_dev->flows)
3187 		vfree(pkt_dev->flows);
3188 	kfree(pkt_dev);
3189 	return 0;
3190 }
3191 
3192 static int __init pg_init(void)
3193 {
3194 	int cpu;
3195 	struct proc_dir_entry *pe;
3196 
3197 	printk(version);
3198 
3199 	pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
3200 	if (!pg_proc_dir)
3201 		return -ENODEV;
3202 	pg_proc_dir->owner = THIS_MODULE;
3203 
3204 	pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
3205 	if (pe == NULL) {
3206 		printk("pktgen: ERROR: cannot create %s procfs entry.\n",
3207 		       PGCTRL);
3208 		proc_net_remove(PG_PROC_DIR);
3209 		return -EINVAL;
3210 	}
3211 
3212 	pe->proc_fops = &pktgen_fops;
3213 	pe->data = NULL;
3214 
3215 	/* Register us to receive netdevice events */
3216 	register_netdevice_notifier(&pktgen_notifier_block);
3217 
3218 	for_each_online_cpu(cpu) {
3219 		char buf[30];
3220 
3221 		sprintf(buf, "kpktgend_%i", cpu);
3222 		pktgen_create_thread(buf, cpu);
3223 	}
3224 	return 0;
3225 }
3226 
3227 static void __exit pg_cleanup(void)
3228 {
3229 	struct pktgen_thread *t;
3230 	struct list_head *q, *n;
3231 	wait_queue_head_t queue;
3232 	init_waitqueue_head(&queue);
3233 
3234 	/* Stop all interfaces & threads */
3235 
3236 	list_for_each_safe(q, n, &pktgen_threads) {
3237 		t = list_entry(q, struct pktgen_thread, th_list);
3238 		t->control |= (T_TERMINATE);
3239 
3240 		wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
3241 	}
3242 
3243 	/* Un-register us from receiving netdevice events */
3244 	unregister_netdevice_notifier(&pktgen_notifier_block);
3245 
3246 	/* Clean up proc file system */
3247 	remove_proc_entry(PGCTRL, pg_proc_dir);
3248 	proc_net_remove(PG_PROC_DIR);
3249 }
3250 
3251 module_init(pg_init);
3252 module_exit(pg_cleanup);
3253 
3254 MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
3255 MODULE_DESCRIPTION("Packet Generator tool");
3256 MODULE_LICENSE("GPL");
3257 module_param(pg_count_d, int, 0);
3258 module_param(pg_delay_d, int, 0);
3259 module_param(pg_clone_skb_d, int, 0);
3260 module_param(debug, int, 0);
3261