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