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