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