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