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