diff options
| author | Stephen Hemminger <shemminger@osdl.org> | 2005-10-14 18:42:33 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-10-25 22:12:18 -0400 |
| commit | d50a6b56f0f239cf061630c85add121dc3555339 (patch) | |
| tree | 98012391b898e4ef4ccd59a41e75cdf65114353c /net/core | |
| parent | b4099fab75d5e3eae8d207c0d7159e2f3348686e (diff) | |
[PKTGEN]: proc interface revision
The code to handle the /proc interface can be cleaned up in several places:
* use seq_file for read
* don't need to remember all the filenames separately
* use for_online_cpu's
* don't vmalloc a buffer for small command from user.
Committer note:
This patch clashed with John Hawkes's "[NET]: Wider use of for_each_*cpu()",
so I fixed it up manually.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/pktgen.c | 472 |
1 files changed, 215 insertions, 257 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index ad053c8cb7fc..7fc3e9e28c34 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -137,6 +137,7 @@ | |||
| 137 | #include <linux/ipv6.h> | 137 | #include <linux/ipv6.h> |
| 138 | #include <linux/udp.h> | 138 | #include <linux/udp.h> |
| 139 | #include <linux/proc_fs.h> | 139 | #include <linux/proc_fs.h> |
| 140 | #include <linux/seq_file.h> | ||
| 140 | #include <linux/wait.h> | 141 | #include <linux/wait.h> |
| 141 | #include <net/checksum.h> | 142 | #include <net/checksum.h> |
| 142 | #include <net/ipv6.h> | 143 | #include <net/ipv6.h> |
| @@ -151,7 +152,7 @@ | |||
| 151 | #include <asm/timex.h> | 152 | #include <asm/timex.h> |
| 152 | 153 | ||
| 153 | 154 | ||
| 154 | #define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n" | 155 | #define VERSION "pktgen v2.63: Packet Generator for packet performance testing.\n" |
| 155 | 156 | ||
| 156 | /* #define PG_DEBUG(a) a */ | 157 | /* #define PG_DEBUG(a) a */ |
| 157 | #define PG_DEBUG(a) | 158 | #define PG_DEBUG(a) |
| @@ -186,7 +187,9 @@ | |||
| 186 | 187 | ||
| 187 | /* Used to help with determining the pkts on receive */ | 188 | /* Used to help with determining the pkts on receive */ |
| 188 | #define PKTGEN_MAGIC 0xbe9be955 | 189 | #define PKTGEN_MAGIC 0xbe9be955 |
| 189 | #define PG_PROC_DIR "net/pktgen" | 190 | #define PG_PROC_DIR "pktgen" |
| 191 | #define PGCTRL "pgctrl" | ||
| 192 | static struct proc_dir_entry *pg_proc_dir = NULL; | ||
| 190 | 193 | ||
| 191 | #define MAX_CFLOWS 65536 | 194 | #define MAX_CFLOWS 65536 |
| 192 | 195 | ||
| @@ -202,11 +205,8 @@ struct pktgen_dev { | |||
| 202 | * Try to keep frequent/infrequent used vars. separated. | 205 | * Try to keep frequent/infrequent used vars. separated. |
| 203 | */ | 206 | */ |
| 204 | 207 | ||
| 205 | char ifname[32]; | 208 | char ifname[IFNAMSIZ]; |
| 206 | struct proc_dir_entry *proc_ent; | ||
| 207 | char result[512]; | 209 | char result[512]; |
| 208 | /* proc file names */ | ||
| 209 | char fname[80]; | ||
| 210 | 210 | ||
| 211 | struct pktgen_thread* pg_thread; /* the owner */ | 211 | struct pktgen_thread* pg_thread; /* the owner */ |
| 212 | struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */ | 212 | struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */ |
| @@ -330,8 +330,6 @@ struct pktgen_thread { | |||
| 330 | struct pktgen_dev *if_list; /* All device here */ | 330 | struct pktgen_dev *if_list; /* All device here */ |
| 331 | struct pktgen_thread* next; | 331 | struct pktgen_thread* next; |
| 332 | char name[32]; | 332 | char name[32]; |
| 333 | char fname[128]; /* name of proc file */ | ||
| 334 | struct proc_dir_entry *proc_ent; | ||
| 335 | char result[512]; | 333 | char result[512]; |
| 336 | u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ | 334 | u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ |
| 337 | 335 | ||
| @@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b) | |||
| 473 | 471 | ||
| 474 | static char version[] __initdata = VERSION; | 472 | static char version[] __initdata = VERSION; |
| 475 | 473 | ||
| 476 | static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos); | ||
| 477 | static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos); | ||
| 478 | static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data); | ||
| 479 | |||
| 480 | static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data); | ||
| 481 | static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data); | ||
| 482 | static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data); | ||
| 483 | static int create_proc_dir(void); | ||
| 484 | static int remove_proc_dir(void); | ||
| 485 | |||
| 486 | static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i); | 474 | static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i); |
| 487 | static int pktgen_add_device(struct pktgen_thread* t, const char* ifname); | 475 | static int pktgen_add_device(struct pktgen_thread* t, const char* ifname); |
| 488 | static struct pktgen_thread* pktgen_find_thread(const char* name); | 476 | static struct pktgen_thread* pktgen_find_thread(const char* name); |
| @@ -506,80 +494,38 @@ static int debug = 0; | |||
| 506 | static DECLARE_MUTEX(pktgen_sem); | 494 | static DECLARE_MUTEX(pktgen_sem); |
| 507 | static struct pktgen_thread *pktgen_threads = NULL; | 495 | static struct pktgen_thread *pktgen_threads = NULL; |
| 508 | 496 | ||
| 509 | static char module_fname[128]; | ||
| 510 | static struct proc_dir_entry *module_proc_ent = NULL; | ||
| 511 | |||
| 512 | static struct notifier_block pktgen_notifier_block = { | 497 | static struct notifier_block pktgen_notifier_block = { |
| 513 | .notifier_call = pktgen_device_event, | 498 | .notifier_call = pktgen_device_event, |
| 514 | }; | 499 | }; |
| 515 | 500 | ||
| 516 | static struct file_operations pktgen_fops = { | ||
| 517 | .read = proc_pgctrl_read, | ||
| 518 | .write = proc_pgctrl_write, | ||
| 519 | /* .ioctl = pktgen_ioctl, later maybe */ | ||
| 520 | }; | ||
| 521 | |||
| 522 | /* | 501 | /* |
| 523 | * /proc handling functions | 502 | * /proc handling functions |
| 524 | * | 503 | * |
| 525 | */ | 504 | */ |
| 526 | 505 | ||
| 527 | static struct proc_dir_entry *pg_proc_dir = NULL; | 506 | static int pgctrl_show(struct seq_file *seq, void *v) |
| 528 | static int proc_pgctrl_read_eof=0; | ||
| 529 | |||
| 530 | static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, | ||
| 531 | size_t count, loff_t *ppos) | ||
| 532 | { | 507 | { |
| 533 | char data[200]; | 508 | seq_puts(seq, VERSION); |
| 534 | int len = 0; | 509 | return 0; |
| 535 | |||
| 536 | if(proc_pgctrl_read_eof) { | ||
| 537 | proc_pgctrl_read_eof=0; | ||
| 538 | len = 0; | ||
| 539 | goto out; | ||
| 540 | } | ||
| 541 | |||
| 542 | sprintf(data, "%s", VERSION); | ||
| 543 | |||
| 544 | len = strlen(data); | ||
| 545 | |||
| 546 | if(len > count) { | ||
| 547 | len = -EFAULT; | ||
| 548 | goto out; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (copy_to_user(buf, data, len)) { | ||
| 552 | len = -EFAULT; | ||
| 553 | goto out; | ||
| 554 | } | ||
| 555 | |||
| 556 | *ppos += len; | ||
| 557 | proc_pgctrl_read_eof=1; /* EOF next call */ | ||
| 558 | |||
| 559 | out: | ||
| 560 | return len; | ||
| 561 | } | 510 | } |
| 562 | 511 | ||
| 563 | static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf, | 512 | static ssize_t pgctrl_write(struct file* file,const char __user * buf, |
| 564 | size_t count, loff_t *ppos) | 513 | size_t count, loff_t *ppos) |
| 565 | { | 514 | { |
| 566 | char *data = NULL; | ||
| 567 | int err = 0; | 515 | int err = 0; |
| 516 | char data[128]; | ||
| 568 | 517 | ||
| 569 | if (!capable(CAP_NET_ADMIN)){ | 518 | if (!capable(CAP_NET_ADMIN)){ |
| 570 | err = -EPERM; | 519 | err = -EPERM; |
| 571 | goto out; | 520 | goto out; |
| 572 | } | 521 | } |
| 573 | 522 | ||
| 574 | data = (void*)vmalloc ((unsigned int)count); | 523 | if (count > sizeof(data)) |
| 524 | count = sizeof(data); | ||
| 575 | 525 | ||
| 576 | if(!data) { | ||
| 577 | err = -ENOMEM; | ||
| 578 | goto out; | ||
| 579 | } | ||
| 580 | if (copy_from_user(data, buf, count)) { | 526 | if (copy_from_user(data, buf, count)) { |
| 581 | err = -EFAULT; | 527 | err = -EFAULT; |
| 582 | goto out_free; | 528 | goto out; |
| 583 | } | 529 | } |
| 584 | data[count-1] = 0; /* Make string */ | 530 | data[count-1] = 0; /* Make string */ |
| 585 | 531 | ||
| @@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf, | |||
| 594 | 540 | ||
| 595 | err = count; | 541 | err = count; |
| 596 | 542 | ||
| 597 | out_free: | ||
| 598 | vfree (data); | ||
| 599 | out: | 543 | out: |
| 600 | return err; | 544 | return err; |
| 601 | } | 545 | } |
| 602 | 546 | ||
| 603 | static int proc_if_read(char *buf , char **start, off_t offset, | 547 | static int pgctrl_open(struct inode *inode, struct file *file) |
| 604 | int len, int *eof, void *data) | 548 | { |
| 549 | return single_open(file, pgctrl_show, PDE(inode)->data); | ||
| 550 | } | ||
| 551 | |||
| 552 | static struct file_operations pktgen_fops = { | ||
| 553 | .owner = THIS_MODULE, | ||
| 554 | .open = pgctrl_open, | ||
| 555 | .read = seq_read, | ||
| 556 | .llseek = seq_lseek, | ||
| 557 | .write = pgctrl_write, | ||
| 558 | .release = single_release, | ||
| 559 | }; | ||
| 560 | |||
| 561 | static int pktgen_if_show(struct seq_file *seq, void *v) | ||
| 605 | { | 562 | { |
| 606 | char *p; | ||
| 607 | int i; | 563 | int i; |
| 608 | struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data); | 564 | struct pktgen_dev *pkt_dev = seq->private; |
| 609 | __u64 sa; | 565 | __u64 sa; |
| 610 | __u64 stopped; | 566 | __u64 stopped; |
| 611 | __u64 now = getCurUs(); | 567 | __u64 now = getCurUs(); |
| 612 | 568 | ||
| 613 | p = buf; | 569 | seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n", |
| 614 | p += sprintf(p, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n", | 570 | (unsigned long long) pkt_dev->count, |
| 615 | (unsigned long long) pkt_dev->count, | 571 | pkt_dev->min_pkt_size, pkt_dev->max_pkt_size); |
| 616 | pkt_dev->min_pkt_size, pkt_dev->max_pkt_size); | ||
| 617 | 572 | ||
| 618 | p += sprintf(p, " frags: %d delay: %u clone_skb: %d ifname: %s\n", | 573 | seq_printf(seq, " frags: %d delay: %u clone_skb: %d ifname: %s\n", |
| 619 | pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname); | 574 | pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname); |
| 620 | 575 | ||
| 621 | p += sprintf(p, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow); | 576 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow); |
| 622 | 577 | ||
| 623 | 578 | ||
| 624 | if(pkt_dev->flags & F_IPV6) { | 579 | if(pkt_dev->flags & F_IPV6) { |
| @@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char **start, off_t offset, | |||
| 626 | fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); | 581 | fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); |
| 627 | fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr); | 582 | fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr); |
| 628 | fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr); | 583 | fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr); |
| 629 | p += sprintf(p, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3); | 584 | seq_printf(seq, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3); |
| 630 | 585 | ||
| 631 | fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr); | 586 | fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr); |
| 632 | fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr); | 587 | fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr); |
| 633 | fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr); | 588 | fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr); |
| 634 | p += sprintf(p, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3); | 589 | seq_printf(seq, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3); |
| 635 | 590 | ||
| 636 | } | 591 | } |
| 637 | else | 592 | else |
| 638 | p += sprintf(p, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n", | 593 | seq_printf(seq," dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n", |
| 639 | pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max); | 594 | pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max); |
| 640 | 595 | ||
| 641 | p += sprintf(p, " src_mac: "); | 596 | seq_puts(seq, " src_mac: "); |
| 642 | 597 | ||
| 643 | if ((pkt_dev->src_mac[0] == 0) && | 598 | if ((pkt_dev->src_mac[0] == 0) && |
| 644 | (pkt_dev->src_mac[1] == 0) && | 599 | (pkt_dev->src_mac[1] == 0) && |
| @@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char **start, off_t offset, | |||
| 648 | (pkt_dev->src_mac[5] == 0)) | 603 | (pkt_dev->src_mac[5] == 0)) |
| 649 | 604 | ||
| 650 | for (i = 0; i < 6; i++) | 605 | for (i = 0; i < 6; i++) |
| 651 | p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":"); | 606 | seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":"); |
| 652 | 607 | ||
| 653 | else | 608 | else |
| 654 | for (i = 0; i < 6; i++) | 609 | for (i = 0; i < 6; i++) |
| 655 | p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":"); | 610 | seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":"); |
| 656 | 611 | ||
| 657 | p += sprintf(p, "dst_mac: "); | 612 | seq_printf(seq, "dst_mac: "); |
| 658 | for (i = 0; i < 6; i++) | 613 | for (i = 0; i < 6; i++) |
| 659 | p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":"); | 614 | seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":"); |
| 660 | 615 | ||
| 661 | p += sprintf(p, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", | 616 | seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", |
| 662 | pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min, | 617 | pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min, |
| 663 | pkt_dev->udp_dst_max); | 618 | pkt_dev->udp_dst_max); |
| 664 | 619 | ||
| 665 | p += sprintf(p, " src_mac_count: %d dst_mac_count: %d \n Flags: ", | 620 | seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ", |
| 666 | pkt_dev->src_mac_count, pkt_dev->dst_mac_count); | 621 | pkt_dev->src_mac_count, pkt_dev->dst_mac_count); |
| 667 | 622 | ||
| 668 | 623 | ||
| 669 | if (pkt_dev->flags & F_IPV6) | 624 | if (pkt_dev->flags & F_IPV6) |
| 670 | p += sprintf(p, "IPV6 "); | 625 | seq_printf(seq, "IPV6 "); |
| 671 | 626 | ||
| 672 | if (pkt_dev->flags & F_IPSRC_RND) | 627 | if (pkt_dev->flags & F_IPSRC_RND) |
| 673 | p += sprintf(p, "IPSRC_RND "); | 628 | seq_printf(seq, "IPSRC_RND "); |
| 674 | 629 | ||
| 675 | if (pkt_dev->flags & F_IPDST_RND) | 630 | if (pkt_dev->flags & F_IPDST_RND) |
| 676 | p += sprintf(p, "IPDST_RND "); | 631 | seq_printf(seq, "IPDST_RND "); |
| 677 | 632 | ||
| 678 | if (pkt_dev->flags & F_TXSIZE_RND) | 633 | if (pkt_dev->flags & F_TXSIZE_RND) |
| 679 | p += sprintf(p, "TXSIZE_RND "); | 634 | seq_printf(seq, "TXSIZE_RND "); |
| 680 | 635 | ||
| 681 | if (pkt_dev->flags & F_UDPSRC_RND) | 636 | if (pkt_dev->flags & F_UDPSRC_RND) |
| 682 | p += sprintf(p, "UDPSRC_RND "); | 637 | seq_printf(seq, "UDPSRC_RND "); |
| 683 | 638 | ||
| 684 | if (pkt_dev->flags & F_UDPDST_RND) | 639 | if (pkt_dev->flags & F_UDPDST_RND) |
| 685 | p += sprintf(p, "UDPDST_RND "); | 640 | seq_printf(seq, "UDPDST_RND "); |
| 686 | 641 | ||
| 687 | if (pkt_dev->flags & F_MACSRC_RND) | 642 | if (pkt_dev->flags & F_MACSRC_RND) |
| 688 | p += sprintf(p, "MACSRC_RND "); | 643 | seq_printf(seq, "MACSRC_RND "); |
| 689 | 644 | ||
| 690 | if (pkt_dev->flags & F_MACDST_RND) | 645 | if (pkt_dev->flags & F_MACDST_RND) |
| 691 | p += sprintf(p, "MACDST_RND "); | 646 | seq_printf(seq, "MACDST_RND "); |
| 692 | 647 | ||
| 693 | 648 | ||
| 694 | p += sprintf(p, "\n"); | 649 | seq_puts(seq, "\n"); |
| 695 | 650 | ||
| 696 | sa = pkt_dev->started_at; | 651 | sa = pkt_dev->started_at; |
| 697 | stopped = pkt_dev->stopped_at; | 652 | stopped = pkt_dev->stopped_at; |
| 698 | if (pkt_dev->running) | 653 | if (pkt_dev->running) |
| 699 | stopped = now; /* not really stopped, more like last-running-at */ | 654 | stopped = now; /* not really stopped, more like last-running-at */ |
| 700 | 655 | ||
| 701 | p += sprintf(p, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n", | 656 | seq_printf(seq, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n", |
| 702 | (unsigned long long) pkt_dev->sofar, | 657 | (unsigned long long) pkt_dev->sofar, |
| 703 | (unsigned long long) pkt_dev->errors, | 658 | (unsigned long long) pkt_dev->errors, |
| 704 | (unsigned long long) sa, | 659 | (unsigned long long) sa, |
| 705 | (unsigned long long) stopped, | 660 | (unsigned long long) stopped, |
| 706 | (unsigned long long) pkt_dev->idle_acc); | 661 | (unsigned long long) pkt_dev->idle_acc); |
| 707 | 662 | ||
| 708 | p += sprintf(p, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n", | 663 | seq_printf(seq, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n", |
| 709 | pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset); | 664 | pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, |
| 665 | pkt_dev->cur_src_mac_offset); | ||
| 710 | 666 | ||
| 711 | if(pkt_dev->flags & F_IPV6) { | 667 | if(pkt_dev->flags & F_IPV6) { |
| 712 | char b1[128], b2[128]; | 668 | char b1[128], b2[128]; |
| 713 | fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr); | 669 | fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr); |
| 714 | fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr); | 670 | fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr); |
| 715 | p += sprintf(p, " cur_saddr: %s cur_daddr: %s\n", b2, b1); | 671 | seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1); |
| 716 | } | 672 | } |
| 717 | else | 673 | else |
| 718 | p += sprintf(p, " cur_saddr: 0x%x cur_daddr: 0x%x\n", | 674 | seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n", |
| 719 | pkt_dev->cur_saddr, pkt_dev->cur_daddr); | 675 | pkt_dev->cur_saddr, pkt_dev->cur_daddr); |
| 720 | 676 | ||
| 721 | 677 | ||
| 722 | p += sprintf(p, " cur_udp_dst: %d cur_udp_src: %d\n", | 678 | seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", |
| 723 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); | 679 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); |
| 724 | 680 | ||
| 725 | p += sprintf(p, " flows: %u\n", pkt_dev->nflows); | 681 | seq_printf(seq, " flows: %u\n", pkt_dev->nflows); |
| 726 | 682 | ||
| 727 | if (pkt_dev->result[0]) | 683 | if (pkt_dev->result[0]) |
| 728 | p += sprintf(p, "Result: %s\n", pkt_dev->result); | 684 | seq_printf(seq, "Result: %s\n", pkt_dev->result); |
| 729 | else | 685 | else |
| 730 | p += sprintf(p, "Result: Idle\n"); | 686 | seq_printf(seq, "Result: Idle\n"); |
| 731 | *eof = 1; | ||
| 732 | 687 | ||
| 733 | return p - buf; | 688 | return 0; |
| 734 | } | 689 | } |
| 735 | 690 | ||
| 736 | 691 | ||
| @@ -802,13 +757,14 @@ done_str: | |||
| 802 | return i; | 757 | return i; |
| 803 | } | 758 | } |
| 804 | 759 | ||
| 805 | static int proc_if_write(struct file *file, const char __user *user_buffer, | 760 | static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer, |
| 806 | unsigned long count, void *data) | 761 | size_t count, loff_t *offset) |
| 807 | { | 762 | { |
| 763 | struct seq_file *seq = (struct seq_file *) file->private_data; | ||
| 764 | struct pktgen_dev *pkt_dev = seq->private; | ||
| 808 | int i = 0, max, len; | 765 | int i = 0, max, len; |
| 809 | char name[16], valstr[32]; | 766 | char name[16], valstr[32]; |
| 810 | unsigned long value = 0; | 767 | unsigned long value = 0; |
| 811 | struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data); | ||
| 812 | char* pg_result = NULL; | 768 | char* pg_result = NULL; |
| 813 | int tmp = 0; | 769 | int tmp = 0; |
| 814 | char buf[128]; | 770 | char buf[128]; |
| @@ -849,7 +805,8 @@ static int proc_if_write(struct file *file, const char __user *user_buffer, | |||
| 849 | if (copy_from_user(tb, user_buffer, count)) | 805 | if (copy_from_user(tb, user_buffer, count)) |
| 850 | return -EFAULT; | 806 | return -EFAULT; |
| 851 | tb[count] = 0; | 807 | tb[count] = 0; |
| 852 | printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb); | 808 | printk("pktgen: %s,%lu buffer -:%s:-\n", name, |
| 809 | (unsigned long) count, tb); | ||
| 853 | } | 810 | } |
| 854 | 811 | ||
| 855 | if (!strcmp(name, "min_pkt_size")) { | 812 | if (!strcmp(name, "min_pkt_size")) { |
| @@ -1335,92 +1292,98 @@ static int proc_if_write(struct file *file, const char __user *user_buffer, | |||
| 1335 | return -EINVAL; | 1292 | return -EINVAL; |
| 1336 | } | 1293 | } |
| 1337 | 1294 | ||
| 1338 | static int proc_thread_read(char *buf , char **start, off_t offset, | 1295 | static int pktgen_if_open(struct inode *inode, struct file *file) |
| 1339 | int len, int *eof, void *data) | ||
| 1340 | { | 1296 | { |
| 1341 | char *p; | 1297 | return single_open(file, pktgen_if_show, PDE(inode)->data); |
| 1342 | struct pktgen_thread *t = (struct pktgen_thread*)(data); | 1298 | } |
| 1343 | struct pktgen_dev *pkt_dev = NULL; | ||
| 1344 | 1299 | ||
| 1300 | static struct file_operations pktgen_if_fops = { | ||
| 1301 | .owner = THIS_MODULE, | ||
| 1302 | .open = pktgen_if_open, | ||
| 1303 | .read = seq_read, | ||
| 1304 | .llseek = seq_lseek, | ||
| 1305 | .write = pktgen_if_write, | ||
| 1306 | .release = single_release, | ||
| 1307 | }; | ||
| 1345 | 1308 | ||
| 1346 | if (!t) { | 1309 | static int pktgen_thread_show(struct seq_file *seq, void *v) |
| 1347 | printk("pktgen: ERROR: could not find thread in proc_thread_read\n"); | 1310 | { |
| 1348 | return -EINVAL; | 1311 | struct pktgen_thread *t = seq->private; |
| 1349 | } | 1312 | struct pktgen_dev *pkt_dev = NULL; |
| 1313 | |||
| 1314 | BUG_ON(!t); | ||
| 1350 | 1315 | ||
| 1351 | p = buf; | 1316 | seq_printf(seq, "Name: %s max_before_softirq: %d\n", |
| 1352 | p += sprintf(p, "Name: %s max_before_softirq: %d\n", | ||
| 1353 | t->name, t->max_before_softirq); | 1317 | t->name, t->max_before_softirq); |
| 1354 | 1318 | ||
| 1355 | p += sprintf(p, "Running: "); | 1319 | seq_printf(seq, "Running: "); |
| 1356 | 1320 | ||
| 1357 | if_lock(t); | 1321 | if_lock(t); |
| 1358 | for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) | 1322 | for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) |
| 1359 | if(pkt_dev->running) | 1323 | if(pkt_dev->running) |
| 1360 | p += sprintf(p, "%s ", pkt_dev->ifname); | 1324 | seq_printf(seq, "%s ", pkt_dev->ifname); |
| 1361 | 1325 | ||
| 1362 | p += sprintf(p, "\nStopped: "); | 1326 | seq_printf(seq, "\nStopped: "); |
| 1363 | 1327 | ||
| 1364 | for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) | 1328 | for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) |
| 1365 | if(!pkt_dev->running) | 1329 | if(!pkt_dev->running) |
| 1366 | p += sprintf(p, "%s ", pkt_dev->ifname); | 1330 | seq_printf(seq, "%s ", pkt_dev->ifname); |
| 1367 | 1331 | ||
| 1368 | if (t->result[0]) | 1332 | if (t->result[0]) |
| 1369 | p += sprintf(p, "\nResult: %s\n", t->result); | 1333 | seq_printf(seq, "\nResult: %s\n", t->result); |
| 1370 | else | 1334 | else |
| 1371 | p += sprintf(p, "\nResult: NA\n"); | 1335 | seq_printf(seq, "\nResult: NA\n"); |
| 1372 | |||
| 1373 | *eof = 1; | ||
| 1374 | 1336 | ||
| 1375 | if_unlock(t); | 1337 | if_unlock(t); |
| 1376 | 1338 | ||
| 1377 | return p - buf; | 1339 | return 0; |
| 1378 | } | 1340 | } |
| 1379 | 1341 | ||
| 1380 | static int proc_thread_write(struct file *file, const char __user *user_buffer, | 1342 | static ssize_t pktgen_thread_write(struct file *file, |
| 1381 | unsigned long count, void *data) | 1343 | const char __user *user_buffer, |
| 1344 | size_t count, loff_t *offset) | ||
| 1382 | { | 1345 | { |
| 1346 | struct seq_file *seq = (struct seq_file *) file->private_data; | ||
| 1347 | struct pktgen_thread *t = seq->private; | ||
| 1383 | int i = 0, max, len, ret; | 1348 | int i = 0, max, len, ret; |
| 1384 | char name[40]; | 1349 | char name[40]; |
| 1385 | struct pktgen_thread *t; | ||
| 1386 | char *pg_result; | 1350 | char *pg_result; |
| 1387 | unsigned long value = 0; | 1351 | unsigned long value = 0; |
| 1388 | 1352 | ||
| 1389 | if (count < 1) { | 1353 | if (count < 1) { |
| 1390 | // sprintf(pg_result, "Wrong command format"); | 1354 | // sprintf(pg_result, "Wrong command format"); |
| 1391 | return -EINVAL; | 1355 | return -EINVAL; |
| 1392 | } | 1356 | } |
| 1393 | 1357 | ||
| 1394 | max = count - i; | 1358 | max = count - i; |
| 1395 | len = count_trail_chars(&user_buffer[i], max); | 1359 | len = count_trail_chars(&user_buffer[i], max); |
| 1396 | if (len < 0) | 1360 | if (len < 0) |
| 1397 | return len; | 1361 | return len; |
| 1398 | 1362 | ||
| 1399 | i += len; | 1363 | i += len; |
| 1400 | 1364 | ||
| 1401 | /* Read variable name */ | 1365 | /* Read variable name */ |
| 1402 | 1366 | ||
| 1403 | len = strn_len(&user_buffer[i], sizeof(name) - 1); | 1367 | len = strn_len(&user_buffer[i], sizeof(name) - 1); |
| 1404 | if (len < 0) | 1368 | if (len < 0) |
| 1405 | return len; | 1369 | return len; |
| 1406 | 1370 | ||
| 1407 | memset(name, 0, sizeof(name)); | 1371 | memset(name, 0, sizeof(name)); |
| 1408 | if (copy_from_user(name, &user_buffer[i], len)) | 1372 | if (copy_from_user(name, &user_buffer[i], len)) |
| 1409 | return -EFAULT; | 1373 | return -EFAULT; |
| 1410 | i += len; | 1374 | i += len; |
| 1411 | 1375 | ||
| 1412 | max = count -i; | 1376 | max = count -i; |
| 1413 | len = count_trail_chars(&user_buffer[i], max); | 1377 | len = count_trail_chars(&user_buffer[i], max); |
| 1414 | if (len < 0) | 1378 | if (len < 0) |
| 1415 | return len; | 1379 | return len; |
| 1416 | 1380 | ||
| 1417 | i += len; | 1381 | i += len; |
| 1418 | 1382 | ||
| 1419 | if (debug) | 1383 | if (debug) |
| 1420 | printk("pktgen: t=%s, count=%lu\n", name, count); | 1384 | printk("pktgen: t=%s, count=%lu\n", name, |
| 1421 | 1385 | (unsigned long) count); | |
| 1422 | 1386 | ||
| 1423 | t = (struct pktgen_thread*)(data); | ||
| 1424 | if(!t) { | 1387 | if(!t) { |
| 1425 | printk("pktgen: ERROR: No thread\n"); | 1388 | printk("pktgen: ERROR: No thread\n"); |
| 1426 | ret = -EINVAL; | 1389 | ret = -EINVAL; |
| @@ -1474,21 +1437,19 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer, | |||
| 1474 | return ret; | 1437 | return ret; |
| 1475 | } | 1438 | } |
| 1476 | 1439 | ||
| 1477 | static int create_proc_dir(void) | 1440 | static int pktgen_thread_open(struct inode *inode, struct file *file) |
| 1478 | { | 1441 | { |
| 1479 | pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL); | 1442 | return single_open(file, pktgen_thread_show, PDE(inode)->data); |
| 1480 | |||
| 1481 | if (!pg_proc_dir) | ||
| 1482 | return -ENODEV; | ||
| 1483 | |||
| 1484 | return 0; | ||
| 1485 | } | 1443 | } |
| 1486 | 1444 | ||
| 1487 | static int remove_proc_dir(void) | 1445 | static struct file_operations pktgen_thread_fops = { |
| 1488 | { | 1446 | .owner = THIS_MODULE, |
| 1489 | remove_proc_entry(PG_PROC_DIR, NULL); | 1447 | .open = pktgen_thread_open, |
| 1490 | return 0; | 1448 | .read = seq_read, |
| 1491 | } | 1449 | .llseek = seq_lseek, |
| 1450 | .write = pktgen_thread_write, | ||
| 1451 | .release = single_release, | ||
| 1452 | }; | ||
| 1492 | 1453 | ||
| 1493 | /* Think find or remove for NN */ | 1454 | /* Think find or remove for NN */ |
| 1494 | static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) | 1455 | static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) |
| @@ -2552,8 +2513,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t) | |||
| 2552 | 2513 | ||
| 2553 | struct pktgen_thread *tmp = pktgen_threads; | 2514 | struct pktgen_thread *tmp = pktgen_threads; |
| 2554 | 2515 | ||
| 2555 | if (strlen(t->fname)) | 2516 | remove_proc_entry(t->name, pg_proc_dir); |
| 2556 | remove_proc_entry(t->fname, NULL); | ||
| 2557 | 2517 | ||
| 2558 | thread_lock(); | 2518 | thread_lock(); |
| 2559 | 2519 | ||
| @@ -2825,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* i | |||
| 2825 | if_lock(t); | 2785 | if_lock(t); |
| 2826 | 2786 | ||
| 2827 | for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) { | 2787 | for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) { |
| 2828 | if (strcmp(pkt_dev->ifname, ifname) == 0) { | 2788 | if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) { |
| 2829 | break; | 2789 | break; |
| 2830 | } | 2790 | } |
| 2831 | } | 2791 | } |
| @@ -2864,65 +2824,63 @@ static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev | |||
| 2864 | static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) | 2824 | static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) |
| 2865 | { | 2825 | { |
| 2866 | struct pktgen_dev *pkt_dev; | 2826 | struct pktgen_dev *pkt_dev; |
| 2827 | struct proc_dir_entry *pe; | ||
| 2867 | 2828 | ||
| 2868 | /* We don't allow a device to be on several threads */ | 2829 | /* We don't allow a device to be on several threads */ |
| 2869 | 2830 | ||
| 2870 | if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) { | 2831 | pkt_dev = __pktgen_NN_threads(ifname, FIND); |
| 2871 | 2832 | if (pkt_dev) { | |
| 2872 | pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL); | ||
| 2873 | if (!pkt_dev) | ||
| 2874 | return -ENOMEM; | ||
| 2875 | |||
| 2876 | pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state)); | ||
| 2877 | if (pkt_dev->flows == NULL) { | ||
| 2878 | kfree(pkt_dev); | ||
| 2879 | return -ENOMEM; | ||
| 2880 | } | ||
| 2881 | memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state)); | ||
| 2882 | |||
| 2883 | pkt_dev->min_pkt_size = ETH_ZLEN; | ||
| 2884 | pkt_dev->max_pkt_size = ETH_ZLEN; | ||
| 2885 | pkt_dev->nfrags = 0; | ||
| 2886 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
| 2887 | pkt_dev->delay_us = pg_delay_d / 1000; | ||
| 2888 | pkt_dev->delay_ns = pg_delay_d % 1000; | ||
| 2889 | pkt_dev->count = pg_count_d; | ||
| 2890 | pkt_dev->sofar = 0; | ||
| 2891 | pkt_dev->udp_src_min = 9; /* sink port */ | ||
| 2892 | pkt_dev->udp_src_max = 9; | ||
| 2893 | pkt_dev->udp_dst_min = 9; | ||
| 2894 | pkt_dev->udp_dst_max = 9; | ||
| 2895 | |||
| 2896 | strncpy(pkt_dev->ifname, ifname, 31); | ||
| 2897 | sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname); | ||
| 2898 | |||
| 2899 | if (! pktgen_setup_dev(pkt_dev)) { | ||
| 2900 | printk("pktgen: ERROR: pktgen_setup_dev failed.\n"); | ||
| 2901 | if (pkt_dev->flows) | ||
| 2902 | vfree(pkt_dev->flows); | ||
| 2903 | kfree(pkt_dev); | ||
| 2904 | return -ENODEV; | ||
| 2905 | } | ||
| 2906 | |||
| 2907 | pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL); | ||
| 2908 | if (!pkt_dev->proc_ent) { | ||
| 2909 | printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname); | ||
| 2910 | if (pkt_dev->flows) | ||
| 2911 | vfree(pkt_dev->flows); | ||
| 2912 | kfree(pkt_dev); | ||
| 2913 | return -EINVAL; | ||
| 2914 | } | ||
| 2915 | pkt_dev->proc_ent->read_proc = proc_if_read; | ||
| 2916 | pkt_dev->proc_ent->write_proc = proc_if_write; | ||
| 2917 | pkt_dev->proc_ent->data = (void*)(pkt_dev); | ||
| 2918 | pkt_dev->proc_ent->owner = THIS_MODULE; | ||
| 2919 | |||
| 2920 | return add_dev_to_thread(t, pkt_dev); | ||
| 2921 | } | ||
| 2922 | else { | ||
| 2923 | printk("pktgen: ERROR: interface already used.\n"); | 2833 | printk("pktgen: ERROR: interface already used.\n"); |
| 2924 | return -EBUSY; | 2834 | return -EBUSY; |
| 2925 | } | 2835 | } |
| 2836 | |||
| 2837 | pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL); | ||
| 2838 | if (!pkt_dev) | ||
| 2839 | return -ENOMEM; | ||
| 2840 | |||
| 2841 | pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state)); | ||
| 2842 | if (pkt_dev->flows == NULL) { | ||
| 2843 | kfree(pkt_dev); | ||
| 2844 | return -ENOMEM; | ||
| 2845 | } | ||
| 2846 | memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state)); | ||
| 2847 | |||
| 2848 | pkt_dev->min_pkt_size = ETH_ZLEN; | ||
| 2849 | pkt_dev->max_pkt_size = ETH_ZLEN; | ||
| 2850 | pkt_dev->nfrags = 0; | ||
| 2851 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
| 2852 | pkt_dev->delay_us = pg_delay_d / 1000; | ||
| 2853 | pkt_dev->delay_ns = pg_delay_d % 1000; | ||
| 2854 | pkt_dev->count = pg_count_d; | ||
| 2855 | pkt_dev->sofar = 0; | ||
| 2856 | pkt_dev->udp_src_min = 9; /* sink port */ | ||
| 2857 | pkt_dev->udp_src_max = 9; | ||
| 2858 | pkt_dev->udp_dst_min = 9; | ||
| 2859 | pkt_dev->udp_dst_max = 9; | ||
| 2860 | |||
| 2861 | strncpy(pkt_dev->ifname, ifname, IFNAMSIZ); | ||
| 2862 | |||
| 2863 | if (! pktgen_setup_dev(pkt_dev)) { | ||
| 2864 | printk("pktgen: ERROR: pktgen_setup_dev failed.\n"); | ||
| 2865 | if (pkt_dev->flows) | ||
| 2866 | vfree(pkt_dev->flows); | ||
| 2867 | kfree(pkt_dev); | ||
| 2868 | return -ENODEV; | ||
| 2869 | } | ||
| 2870 | |||
| 2871 | pe = create_proc_entry(ifname, 0600, pg_proc_dir); | ||
| 2872 | if (!pe) { | ||
| 2873 | printk("pktgen: cannot create %s/%s procfs entry.\n", | ||
| 2874 | PG_PROC_DIR, ifname); | ||
| 2875 | if (pkt_dev->flows) | ||
| 2876 | vfree(pkt_dev->flows); | ||
| 2877 | kfree(pkt_dev); | ||
| 2878 | return -EINVAL; | ||
| 2879 | } | ||
| 2880 | pe->proc_fops = &pktgen_if_fops; | ||
| 2881 | pe->data = pkt_dev; | ||
| 2882 | |||
| 2883 | return add_dev_to_thread(t, pkt_dev); | ||
| 2926 | } | 2884 | } |
| 2927 | 2885 | ||
| 2928 | static struct pktgen_thread *pktgen_find_thread(const char* name) | 2886 | static struct pktgen_thread *pktgen_find_thread(const char* name) |
| @@ -2945,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name) | |||
| 2945 | static int pktgen_create_thread(const char* name, int cpu) | 2903 | static int pktgen_create_thread(const char* name, int cpu) |
| 2946 | { | 2904 | { |
| 2947 | struct pktgen_thread *t = NULL; | 2905 | struct pktgen_thread *t = NULL; |
| 2906 | struct proc_dir_entry *pe; | ||
| 2948 | 2907 | ||
| 2949 | if (strlen(name) > 31) { | 2908 | if (strlen(name) > 31) { |
| 2950 | printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); | 2909 | printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); |
| @@ -2966,17 +2925,16 @@ static int pktgen_create_thread(const char* name, int cpu) | |||
| 2966 | spin_lock_init(&t->if_lock); | 2925 | spin_lock_init(&t->if_lock); |
| 2967 | t->cpu = cpu; | 2926 | t->cpu = cpu; |
| 2968 | 2927 | ||
| 2969 | sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name); | 2928 | pe = create_proc_entry(t->name, 0600, pg_proc_dir); |
| 2970 | t->proc_ent = create_proc_entry(t->fname, 0600, NULL); | 2929 | if (!pe) { |
| 2971 | if (!t->proc_ent) { | 2930 | printk("pktgen: cannot create %s/%s procfs entry.\n", |
| 2972 | printk("pktgen: cannot create %s procfs entry.\n", t->fname); | 2931 | PG_PROC_DIR, t->name); |
| 2973 | kfree(t); | 2932 | kfree(t); |
| 2974 | return -EINVAL; | 2933 | return -EINVAL; |
| 2975 | } | 2934 | } |
| 2976 | t->proc_ent->read_proc = proc_thread_read; | 2935 | |
| 2977 | t->proc_ent->write_proc = proc_thread_write; | 2936 | pe->proc_fops = &pktgen_thread_fops; |
| 2978 | t->proc_ent->data = (void*)(t); | 2937 | pe->data = t; |
| 2979 | t->proc_ent->owner = THIS_MODULE; | ||
| 2980 | 2938 | ||
| 2981 | t->next = pktgen_threads; | 2939 | t->next = pktgen_threads; |
| 2982 | pktgen_threads = t; | 2940 | pktgen_threads = t; |
| @@ -3031,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_ | |||
| 3031 | 2989 | ||
| 3032 | /* Clean up proc file system */ | 2990 | /* Clean up proc file system */ |
| 3033 | 2991 | ||
| 3034 | if (strlen(pkt_dev->fname)) | 2992 | remove_proc_entry(pkt_dev->ifname, pg_proc_dir); |
| 3035 | remove_proc_entry(pkt_dev->fname, NULL); | ||
| 3036 | 2993 | ||
| 3037 | if (pkt_dev->flows) | 2994 | if (pkt_dev->flows) |
| 3038 | vfree(pkt_dev->flows); | 2995 | vfree(pkt_dev->flows); |
| @@ -3043,21 +3000,24 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_ | |||
| 3043 | static int __init pg_init(void) | 3000 | static int __init pg_init(void) |
| 3044 | { | 3001 | { |
| 3045 | int cpu; | 3002 | int cpu; |
| 3046 | printk(version); | 3003 | struct proc_dir_entry *pe; |
| 3047 | 3004 | ||
| 3048 | module_fname[0] = 0; | 3005 | printk(version); |
| 3049 | 3006 | ||
| 3050 | create_proc_dir(); | 3007 | pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net); |
| 3008 | if (!pg_proc_dir) | ||
| 3009 | return -ENODEV; | ||
| 3010 | pg_proc_dir->owner = THIS_MODULE; | ||
| 3051 | 3011 | ||
| 3052 | sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR); | 3012 | pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir); |
| 3053 | module_proc_ent = create_proc_entry(module_fname, 0600, NULL); | 3013 | if (pe == NULL) { |
| 3054 | if (!module_proc_ent) { | 3014 | printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL); |
| 3055 | printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname); | 3015 | proc_net_remove(PG_PROC_DIR); |
| 3056 | return -EINVAL; | 3016 | return -EINVAL; |
| 3057 | } | 3017 | } |
| 3058 | 3018 | ||
| 3059 | module_proc_ent->proc_fops = &pktgen_fops; | 3019 | pe->proc_fops = &pktgen_fops; |
| 3060 | module_proc_ent->data = NULL; | 3020 | pe->data = NULL; |
| 3061 | 3021 | ||
| 3062 | /* Register us to receive netdevice events */ | 3022 | /* Register us to receive netdevice events */ |
| 3063 | register_netdevice_notifier(&pktgen_notifier_block); | 3023 | register_netdevice_notifier(&pktgen_notifier_block); |
| @@ -3089,10 +3049,8 @@ static void __exit pg_cleanup(void) | |||
| 3089 | unregister_netdevice_notifier(&pktgen_notifier_block); | 3049 | unregister_netdevice_notifier(&pktgen_notifier_block); |
| 3090 | 3050 | ||
| 3091 | /* Clean up proc file system */ | 3051 | /* Clean up proc file system */ |
| 3092 | 3052 | remove_proc_entry(PGCTRL, pg_proc_dir); | |
| 3093 | remove_proc_entry(module_fname, NULL); | 3053 | proc_net_remove(PG_PROC_DIR); |
| 3094 | |||
| 3095 | remove_proc_dir(); | ||
| 3096 | } | 3054 | } |
| 3097 | 3055 | ||
| 3098 | 3056 | ||
