diff options
| -rw-r--r-- | include/linux/skbuff.h | 3 | ||||
| -rw-r--r-- | include/net/dst.h | 1 | ||||
| -rw-r--r-- | net/core/neighbour.c | 5 | ||||
| -rw-r--r-- | net/core/pktgen.c | 506 | ||||
| -rw-r--r-- | net/core/skbuff.c | 2 | ||||
| -rw-r--r-- | net/decnet/af_decnet.c | 13 | ||||
| -rw-r--r-- | net/ipv4/devinet.c | 3 | ||||
| -rw-r--r-- | net/ipv4/fib_trie.c | 2 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 5 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 5 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 132 | ||||
| -rw-r--r-- | net/ipv4/proc.c | 4 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 9 | ||||
| -rw-r--r-- | net/ipv6/proc.c | 4 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 3 | ||||
| -rw-r--r-- | net/rose/rose_route.c | 2 | ||||
| -rw-r--r-- | net/sctp/proc.c | 4 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 43 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 6 |
19 files changed, 346 insertions, 406 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8f5d9e7f8734..b756935da9c8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -171,7 +171,6 @@ enum { | |||
| 171 | * struct sk_buff - socket buffer | 171 | * struct sk_buff - socket buffer |
| 172 | * @next: Next buffer in list | 172 | * @next: Next buffer in list |
| 173 | * @prev: Previous buffer in list | 173 | * @prev: Previous buffer in list |
| 174 | * @list: List we are on | ||
| 175 | * @sk: Socket we are owned by | 174 | * @sk: Socket we are owned by |
| 176 | * @tstamp: Time we arrived | 175 | * @tstamp: Time we arrived |
| 177 | * @dev: Device we arrived on/are leaving by | 176 | * @dev: Device we arrived on/are leaving by |
| @@ -190,6 +189,7 @@ enum { | |||
| 190 | * @cloned: Head may be cloned (check refcnt to be sure) | 189 | * @cloned: Head may be cloned (check refcnt to be sure) |
| 191 | * @nohdr: Payload reference only, must not modify header | 190 | * @nohdr: Payload reference only, must not modify header |
| 192 | * @pkt_type: Packet class | 191 | * @pkt_type: Packet class |
| 192 | * @fclone: skbuff clone status | ||
| 193 | * @ip_summed: Driver fed us an IP checksum | 193 | * @ip_summed: Driver fed us an IP checksum |
| 194 | * @priority: Packet queueing priority | 194 | * @priority: Packet queueing priority |
| 195 | * @users: User count - see {datagram,tcp}.c | 195 | * @users: User count - see {datagram,tcp}.c |
| @@ -202,6 +202,7 @@ enum { | |||
| 202 | * @destructor: Destruct function | 202 | * @destructor: Destruct function |
| 203 | * @nfmark: Can be used for communication between hooks | 203 | * @nfmark: Can be used for communication between hooks |
| 204 | * @nfct: Associated connection, if any | 204 | * @nfct: Associated connection, if any |
| 205 | * @ipvs_property: skbuff is owned by ipvs | ||
| 205 | * @nfctinfo: Relationship of this skb to the connection | 206 | * @nfctinfo: Relationship of this skb to the connection |
| 206 | * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c | 207 | * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c |
| 207 | * @tc_index: Traffic control index | 208 | * @tc_index: Traffic control index |
diff --git a/include/net/dst.h b/include/net/dst.h index 4a056a682435..6c196a5baf24 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
| @@ -94,7 +94,6 @@ struct dst_ops | |||
| 94 | struct dst_entry * (*negative_advice)(struct dst_entry *); | 94 | struct dst_entry * (*negative_advice)(struct dst_entry *); |
| 95 | void (*link_failure)(struct sk_buff *); | 95 | void (*link_failure)(struct sk_buff *); |
| 96 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); | 96 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); |
| 97 | int (*get_mss)(struct dst_entry *dst, u32 mtu); | ||
| 98 | int entry_size; | 97 | int entry_size; |
| 99 | 98 | ||
| 100 | atomic_t entries; | 99 | atomic_t entries; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 1dcf7fa1f0fe..e68700f950a5 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -1625,12 +1625,9 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | |||
| 1625 | 1625 | ||
| 1626 | memset(&ndst, 0, sizeof(ndst)); | 1626 | memset(&ndst, 0, sizeof(ndst)); |
| 1627 | 1627 | ||
| 1628 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 1628 | for_each_cpu(cpu) { |
| 1629 | struct neigh_statistics *st; | 1629 | struct neigh_statistics *st; |
| 1630 | 1630 | ||
| 1631 | if (!cpu_possible(cpu)) | ||
| 1632 | continue; | ||
| 1633 | |||
| 1634 | st = per_cpu_ptr(tbl->stats, cpu); | 1631 | st = per_cpu_ptr(tbl->stats, cpu); |
| 1635 | ndst.ndts_allocs += st->allocs; | 1632 | ndst.ndts_allocs += st->allocs; |
| 1636 | ndst.ndts_destroys += st->destroys; | 1633 | ndst.ndts_destroys += st->destroys; |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 5f043d346694..7fc3e9e28c34 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -75,7 +75,7 @@ | |||
| 75 | * By design there should only be *one* "controlling" process. In practice | 75 | * By design there should only be *one* "controlling" process. In practice |
| 76 | * multiple write accesses gives unpredictable result. Understood by "write" | 76 | * multiple write accesses gives unpredictable result. Understood by "write" |
| 77 | * to /proc gives result code thats should be read be the "writer". | 77 | * to /proc gives result code thats should be read be the "writer". |
| 78 | * For pratical use this should be no problem. | 78 | * For practical use this should be no problem. |
| 79 | * | 79 | * |
| 80 | * Note when adding devices to a specific CPU there good idea to also assign | 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. | 81 | * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU. |
| @@ -96,7 +96,7 @@ | |||
| 96 | * New xmit() return, do_div and misc clean up by Stephen Hemminger | 96 | * New xmit() return, do_div and misc clean up by Stephen Hemminger |
| 97 | * <shemminger@osdl.org> 040923 | 97 | * <shemminger@osdl.org> 040923 |
| 98 | * | 98 | * |
| 99 | * Rany Dunlap fixed u64 printk compiler waring | 99 | * Randy Dunlap fixed u64 printk compiler waring |
| 100 | * | 100 | * |
| 101 | * Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org> | 101 | * Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org> |
| 102 | * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213 | 102 | * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213 |
| @@ -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) |
| @@ -177,8 +178,8 @@ | |||
| 177 | #define T_REMDEV (1<<3) /* Remove all devs */ | 178 | #define T_REMDEV (1<<3) /* Remove all devs */ |
| 178 | 179 | ||
| 179 | /* Locks */ | 180 | /* Locks */ |
| 180 | #define thread_lock() spin_lock(&_thread_lock) | 181 | #define thread_lock() down(&pktgen_sem) |
| 181 | #define thread_unlock() spin_unlock(&_thread_lock) | 182 | #define thread_unlock() up(&pktgen_sem) |
| 182 | 183 | ||
| 183 | /* If lock -- can be removed after some work */ | 184 | /* If lock -- can be removed after some work */ |
| 184 | #define if_lock(t) spin_lock(&(t->if_lock)); | 185 | #define if_lock(t) spin_lock(&(t->if_lock)); |
| @@ -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 */ |
| @@ -244,7 +244,7 @@ struct pktgen_dev { | |||
| 244 | __u32 seq_num; | 244 | __u32 seq_num; |
| 245 | 245 | ||
| 246 | int clone_skb; /* Use multiple SKBs during packet gen. If this number | 246 | int clone_skb; /* Use multiple SKBs during packet gen. If this number |
| 247 | * is greater than 1, then that many coppies of the same | 247 | * is greater than 1, then that many copies of the same |
| 248 | * packet will be sent before a new packet is allocated. | 248 | * packet will be sent before a new packet is allocated. |
| 249 | * For instance, if you want to send 1024 identical packets | 249 | * For instance, if you want to send 1024 identical packets |
| 250 | * before creating a new packet, set clone_skb to 1024. | 250 | * before creating a new packet, set clone_skb to 1024. |
| @@ -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 | ||
| @@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y, int type) | |||
| 396 | 394 | ||
| 397 | /* End of hacks to deal with 64-bit math on x86 */ | 395 | /* End of hacks to deal with 64-bit math on x86 */ |
| 398 | 396 | ||
| 399 | /** Convert to miliseconds */ | 397 | /** Convert to milliseconds */ |
| 400 | static inline __u64 tv_to_ms(const struct timeval* tv) | 398 | static inline __u64 tv_to_ms(const struct timeval* tv) |
| 401 | { | 399 | { |
| 402 | __u64 ms = tv->tv_usec / 1000; | 400 | __u64 ms = tv->tv_usec / 1000; |
| @@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __u64 base) | |||
| 425 | { | 423 | { |
| 426 | __u64 tmp = n; | 424 | __u64 tmp = n; |
| 427 | /* | 425 | /* |
| 428 | * How do we know if the architectrure we are running on | 426 | * How do we know if the architecture we are running on |
| 429 | * supports division with 64 bit base? | 427 | * supports division with 64 bit base? |
| 430 | * | 428 | * |
| 431 | */ | 429 | */ |
| @@ -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); |
| @@ -503,83 +491,41 @@ static int pg_delay_d = 0; | |||
| 503 | static int pg_clone_skb_d = 0; | 491 | static int pg_clone_skb_d = 0; |
| 504 | static int debug = 0; | 492 | static int debug = 0; |
| 505 | 493 | ||
| 506 | static DEFINE_SPINLOCK(_thread_lock); | 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) |
| @@ -1702,7 +1663,7 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us) | |||
| 1702 | start = now = getCurUs(); | 1663 | start = now = getCurUs(); |
| 1703 | printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now)); | 1664 | printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now)); |
| 1704 | while (now < spin_until_us) { | 1665 | while (now < spin_until_us) { |
| 1705 | /* TODO: optimise sleeping behavior */ | 1666 | /* TODO: optimize sleeping behavior */ |
| 1706 | if (spin_until_us - now > jiffies_to_usecs(1)+1) | 1667 | if (spin_until_us - now > jiffies_to_usecs(1)+1) |
| 1707 | schedule_timeout_interruptible(1); | 1668 | schedule_timeout_interruptible(1); |
| 1708 | else if (spin_until_us - now > 100) { | 1669 | else if (spin_until_us - now > 100) { |
| @@ -2361,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(void) | |||
| 2361 | pktgen_stop(t); | 2322 | pktgen_stop(t); |
| 2362 | t = t->next; | 2323 | t = t->next; |
| 2363 | } | 2324 | } |
| 2364 | thread_unlock(); | 2325 | thread_unlock(); |
| 2365 | } | 2326 | } |
| 2366 | 2327 | ||
| 2367 | static int thread_is_running(struct pktgen_thread *t ) | 2328 | static int thread_is_running(struct pktgen_thread *t ) |
| @@ -2552,10 +2513,9 @@ 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 | ||
| 2560 | if (tmp == t) | 2520 | if (tmp == t) |
| 2561 | pktgen_threads = tmp->next; | 2521 | pktgen_threads = tmp->next; |
| @@ -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,74 +2824,70 @@ 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 = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL); | 2833 | printk("pktgen: ERROR: interface already used.\n"); |
| 2873 | if (!pkt_dev) | 2834 | return -EBUSY; |
| 2874 | return -ENOMEM; | 2835 | } |
| 2875 | 2836 | ||
| 2876 | memset(pkt_dev, 0, sizeof(struct pktgen_dev)); | 2837 | pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL); |
| 2838 | if (!pkt_dev) | ||
| 2839 | return -ENOMEM; | ||
| 2877 | 2840 | ||
| 2878 | pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state)); | 2841 | pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state)); |
| 2879 | if (pkt_dev->flows == NULL) { | 2842 | if (pkt_dev->flows == NULL) { |
| 2880 | kfree(pkt_dev); | 2843 | kfree(pkt_dev); |
| 2881 | return -ENOMEM; | 2844 | return -ENOMEM; |
| 2882 | } | 2845 | } |
| 2883 | memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state)); | 2846 | memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state)); |
| 2884 | |||
| 2885 | pkt_dev->min_pkt_size = ETH_ZLEN; | ||
| 2886 | pkt_dev->max_pkt_size = ETH_ZLEN; | ||
| 2887 | pkt_dev->nfrags = 0; | ||
| 2888 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
| 2889 | pkt_dev->delay_us = pg_delay_d / 1000; | ||
| 2890 | pkt_dev->delay_ns = pg_delay_d % 1000; | ||
| 2891 | pkt_dev->count = pg_count_d; | ||
| 2892 | pkt_dev->sofar = 0; | ||
| 2893 | pkt_dev->udp_src_min = 9; /* sink port */ | ||
| 2894 | pkt_dev->udp_src_max = 9; | ||
| 2895 | pkt_dev->udp_dst_min = 9; | ||
| 2896 | pkt_dev->udp_dst_max = 9; | ||
| 2897 | |||
| 2898 | strncpy(pkt_dev->ifname, ifname, 31); | ||
| 2899 | sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname); | ||
| 2900 | |||
| 2901 | if (! pktgen_setup_dev(pkt_dev)) { | ||
| 2902 | printk("pktgen: ERROR: pktgen_setup_dev failed.\n"); | ||
| 2903 | if (pkt_dev->flows) | ||
| 2904 | vfree(pkt_dev->flows); | ||
| 2905 | kfree(pkt_dev); | ||
| 2906 | return -ENODEV; | ||
| 2907 | } | ||
| 2908 | 2847 | ||
| 2909 | pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL); | 2848 | pkt_dev->min_pkt_size = ETH_ZLEN; |
| 2910 | if (!pkt_dev->proc_ent) { | 2849 | pkt_dev->max_pkt_size = ETH_ZLEN; |
| 2911 | printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname); | 2850 | pkt_dev->nfrags = 0; |
| 2912 | if (pkt_dev->flows) | 2851 | pkt_dev->clone_skb = pg_clone_skb_d; |
| 2913 | vfree(pkt_dev->flows); | 2852 | pkt_dev->delay_us = pg_delay_d / 1000; |
| 2914 | kfree(pkt_dev); | 2853 | pkt_dev->delay_ns = pg_delay_d % 1000; |
| 2915 | return -EINVAL; | 2854 | pkt_dev->count = pg_count_d; |
| 2916 | } | 2855 | pkt_dev->sofar = 0; |
| 2917 | pkt_dev->proc_ent->read_proc = proc_if_read; | 2856 | pkt_dev->udp_src_min = 9; /* sink port */ |
| 2918 | pkt_dev->proc_ent->write_proc = proc_if_write; | 2857 | pkt_dev->udp_src_max = 9; |
| 2919 | pkt_dev->proc_ent->data = (void*)(pkt_dev); | 2858 | pkt_dev->udp_dst_min = 9; |
| 2920 | pkt_dev->proc_ent->owner = THIS_MODULE; | 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; | ||
| 2921 | 2882 | ||
| 2922 | return add_dev_to_thread(t, pkt_dev); | 2883 | return add_dev_to_thread(t, pkt_dev); |
| 2923 | } | ||
| 2924 | else { | ||
| 2925 | printk("pktgen: ERROR: interface already used.\n"); | ||
| 2926 | return -EBUSY; | ||
| 2927 | } | ||
| 2928 | } | 2884 | } |
| 2929 | 2885 | ||
| 2930 | static struct pktgen_thread *pktgen_find_thread(const char* name) | 2886 | static struct pktgen_thread *pktgen_find_thread(const char* name) |
| 2931 | { | 2887 | { |
| 2932 | struct pktgen_thread *t = NULL; | 2888 | struct pktgen_thread *t = NULL; |
| 2933 | 2889 | ||
| 2934 | thread_lock(); | 2890 | thread_lock(); |
| 2935 | 2891 | ||
| 2936 | t = pktgen_threads; | 2892 | t = pktgen_threads; |
| 2937 | while (t) { | 2893 | while (t) { |
| @@ -2947,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name) | |||
| 2947 | static int pktgen_create_thread(const char* name, int cpu) | 2903 | static int pktgen_create_thread(const char* name, int cpu) |
| 2948 | { | 2904 | { |
| 2949 | struct pktgen_thread *t = NULL; | 2905 | struct pktgen_thread *t = NULL; |
| 2906 | struct proc_dir_entry *pe; | ||
| 2950 | 2907 | ||
| 2951 | if (strlen(name) > 31) { | 2908 | if (strlen(name) > 31) { |
| 2952 | 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"); |
| @@ -2958,28 +2915,26 @@ static int pktgen_create_thread(const char* name, int cpu) | |||
| 2958 | return -EINVAL; | 2915 | return -EINVAL; |
| 2959 | } | 2916 | } |
| 2960 | 2917 | ||
| 2961 | t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL)); | 2918 | t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); |
| 2962 | if (!t) { | 2919 | if (!t) { |
| 2963 | printk("pktgen: ERROR: out of memory, can't create new thread.\n"); | 2920 | printk("pktgen: ERROR: out of memory, can't create new thread.\n"); |
| 2964 | return -ENOMEM; | 2921 | return -ENOMEM; |
| 2965 | } | 2922 | } |
| 2966 | 2923 | ||
| 2967 | memset(t, 0, sizeof(struct pktgen_thread)); | ||
| 2968 | strcpy(t->name, name); | 2924 | strcpy(t->name, name); |
| 2969 | spin_lock_init(&t->if_lock); | 2925 | spin_lock_init(&t->if_lock); |
| 2970 | t->cpu = cpu; | 2926 | t->cpu = cpu; |
| 2971 | 2927 | ||
| 2972 | sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name); | 2928 | pe = create_proc_entry(t->name, 0600, pg_proc_dir); |
| 2973 | t->proc_ent = create_proc_entry(t->fname, 0600, NULL); | 2929 | if (!pe) { |
| 2974 | if (!t->proc_ent) { | 2930 | printk("pktgen: cannot create %s/%s procfs entry.\n", |
| 2975 | printk("pktgen: cannot create %s procfs entry.\n", t->fname); | 2931 | PG_PROC_DIR, t->name); |
| 2976 | kfree(t); | 2932 | kfree(t); |
| 2977 | return -EINVAL; | 2933 | return -EINVAL; |
| 2978 | } | 2934 | } |
| 2979 | t->proc_ent->read_proc = proc_thread_read; | 2935 | |
| 2980 | t->proc_ent->write_proc = proc_thread_write; | 2936 | pe->proc_fops = &pktgen_thread_fops; |
| 2981 | t->proc_ent->data = (void*)(t); | 2937 | pe->data = t; |
| 2982 | t->proc_ent->owner = THIS_MODULE; | ||
| 2983 | 2938 | ||
| 2984 | t->next = pktgen_threads; | 2939 | t->next = pktgen_threads; |
| 2985 | pktgen_threads = t; | 2940 | pktgen_threads = t; |
| @@ -3034,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_ | |||
| 3034 | 2989 | ||
| 3035 | /* Clean up proc file system */ | 2990 | /* Clean up proc file system */ |
| 3036 | 2991 | ||
| 3037 | if (strlen(pkt_dev->fname)) | 2992 | remove_proc_entry(pkt_dev->ifname, pg_proc_dir); |
| 3038 | remove_proc_entry(pkt_dev->fname, NULL); | ||
| 3039 | 2993 | ||
| 3040 | if (pkt_dev->flows) | 2994 | if (pkt_dev->flows) |
| 3041 | vfree(pkt_dev->flows); | 2995 | vfree(pkt_dev->flows); |
| @@ -3046,31 +3000,31 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_ | |||
| 3046 | static int __init pg_init(void) | 3000 | static int __init pg_init(void) |
| 3047 | { | 3001 | { |
| 3048 | int cpu; | 3002 | int cpu; |
| 3049 | printk(version); | 3003 | struct proc_dir_entry *pe; |
| 3050 | 3004 | ||
| 3051 | module_fname[0] = 0; | 3005 | printk(version); |
| 3052 | 3006 | ||
| 3053 | 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; | ||
| 3054 | 3011 | ||
| 3055 | sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR); | 3012 | pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir); |
| 3056 | module_proc_ent = create_proc_entry(module_fname, 0600, NULL); | 3013 | if (pe == NULL) { |
| 3057 | if (!module_proc_ent) { | 3014 | printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL); |
| 3058 | printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname); | 3015 | proc_net_remove(PG_PROC_DIR); |
| 3059 | return -EINVAL; | 3016 | return -EINVAL; |
| 3060 | } | 3017 | } |
| 3061 | 3018 | ||
| 3062 | module_proc_ent->proc_fops = &pktgen_fops; | 3019 | pe->proc_fops = &pktgen_fops; |
| 3063 | module_proc_ent->data = NULL; | 3020 | pe->data = NULL; |
| 3064 | 3021 | ||
| 3065 | /* Register us to receive netdevice events */ | 3022 | /* Register us to receive netdevice events */ |
| 3066 | register_netdevice_notifier(&pktgen_notifier_block); | 3023 | register_netdevice_notifier(&pktgen_notifier_block); |
| 3067 | 3024 | ||
| 3068 | for (cpu = 0; cpu < NR_CPUS ; cpu++) { | 3025 | for_each_online_cpu(cpu) { |
| 3069 | char buf[30]; | 3026 | char buf[30]; |
| 3070 | 3027 | ||
| 3071 | if (!cpu_online(cpu)) | ||
| 3072 | continue; | ||
| 3073 | |||
| 3074 | sprintf(buf, "kpktgend_%i", cpu); | 3028 | sprintf(buf, "kpktgend_%i", cpu); |
| 3075 | pktgen_create_thread(buf, cpu); | 3029 | pktgen_create_thread(buf, cpu); |
| 3076 | } | 3030 | } |
| @@ -3095,10 +3049,8 @@ static void __exit pg_cleanup(void) | |||
| 3095 | unregister_netdevice_notifier(&pktgen_notifier_block); | 3049 | unregister_netdevice_notifier(&pktgen_notifier_block); |
| 3096 | 3050 | ||
| 3097 | /* Clean up proc file system */ | 3051 | /* Clean up proc file system */ |
| 3098 | 3052 | remove_proc_entry(PGCTRL, pg_proc_dir); | |
| 3099 | remove_proc_entry(module_fname, NULL); | 3053 | proc_net_remove(PG_PROC_DIR); |
| 3100 | |||
| 3101 | remove_proc_dir(); | ||
| 3102 | } | 3054 | } |
| 3103 | 3055 | ||
| 3104 | 3056 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 02cd4cde2112..ef9d46b91eb9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -122,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
| 122 | * __alloc_skb - allocate a network buffer | 122 | * __alloc_skb - allocate a network buffer |
| 123 | * @size: size to allocate | 123 | * @size: size to allocate |
| 124 | * @gfp_mask: allocation mask | 124 | * @gfp_mask: allocation mask |
| 125 | * @fclone: allocate from fclone cache instead of head cache | ||
| 126 | * and allocate a cloned (child) skb | ||
| 125 | * | 127 | * |
| 126 | * Allocate a new &sk_buff. The returned buffer has no headroom and a | 128 | * Allocate a new &sk_buff. The returned buffer has no headroom and a |
| 127 | * tail room of size bytes. The object has a reference count of one. | 129 | * tail room of size bytes. The object has a reference count of one. |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 1186dc44cdff..3f25cadccddd 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
| @@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 719 | if (saddr->sdn_flags & ~SDF_WILD) | 719 | if (saddr->sdn_flags & ~SDF_WILD) |
| 720 | return -EINVAL; | 720 | return -EINVAL; |
| 721 | 721 | ||
| 722 | #if 1 | ||
| 723 | if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum || | 722 | if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum || |
| 724 | (saddr->sdn_flags & SDF_WILD))) | 723 | (saddr->sdn_flags & SDF_WILD))) |
| 725 | return -EACCES; | 724 | return -EACCES; |
| 726 | #else | ||
| 727 | /* | ||
| 728 | * Maybe put the default actions in the default security ops for | ||
| 729 | * dn_prot_sock ? Would be nice if the capable call would go there | ||
| 730 | * too. | ||
| 731 | */ | ||
| 732 | if (security_dn_prot_sock(saddr) && | ||
| 733 | !capable(CAP_NET_BIND_SERVICE) || | ||
| 734 | saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD)) | ||
| 735 | return -EACCES; | ||
| 736 | #endif | ||
| 737 | |||
| 738 | 725 | ||
| 739 | if (!(saddr->sdn_flags & SDF_WILD)) { | 726 | if (!(saddr->sdn_flags & SDF_WILD)) { |
| 740 | if (dn_ntohs(saddr->sdn_nodeaddrl)) { | 727 | if (dn_ntohs(saddr->sdn_nodeaddrl)) { |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 74f2207e131a..4ec4b2ca6ab1 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) | |||
| 715 | break; | 715 | break; |
| 716 | ret = 0; | 716 | ret = 0; |
| 717 | if (ifa->ifa_mask != sin->sin_addr.s_addr) { | 717 | if (ifa->ifa_mask != sin->sin_addr.s_addr) { |
| 718 | u32 old_mask = ifa->ifa_mask; | ||
| 718 | inet_del_ifa(in_dev, ifap, 0); | 719 | inet_del_ifa(in_dev, ifap, 0); |
| 719 | ifa->ifa_mask = sin->sin_addr.s_addr; | 720 | ifa->ifa_mask = sin->sin_addr.s_addr; |
| 720 | ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask); | 721 | ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask); |
| @@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) | |||
| 728 | if ((dev->flags & IFF_BROADCAST) && | 729 | if ((dev->flags & IFF_BROADCAST) && |
| 729 | (ifa->ifa_prefixlen < 31) && | 730 | (ifa->ifa_prefixlen < 31) && |
| 730 | (ifa->ifa_broadcast == | 731 | (ifa->ifa_broadcast == |
| 731 | (ifa->ifa_local|~ifa->ifa_mask))) { | 732 | (ifa->ifa_local|~old_mask))) { |
| 732 | ifa->ifa_broadcast = (ifa->ifa_local | | 733 | ifa->ifa_broadcast = (ifa->ifa_local | |
| 733 | ~sin->sin_addr.s_addr); | 734 | ~sin->sin_addr.s_addr); |
| 734 | } | 735 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0093ea08c7f5..66247f38b371 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
| @@ -2404,7 +2404,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) | |||
| 2404 | prefix = htonl(l->key); | 2404 | prefix = htonl(l->key); |
| 2405 | 2405 | ||
| 2406 | list_for_each_entry_rcu(fa, &li->falh, fa_list) { | 2406 | list_for_each_entry_rcu(fa, &li->falh, fa_list) { |
| 2407 | const struct fib_info *fi = rcu_dereference(fa->fa_info); | 2407 | const struct fib_info *fi = fa->fa_info; |
| 2408 | unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); | 2408 | unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); |
| 2409 | 2409 | ||
| 2410 | if (fa->fa_type == RTN_BROADCAST | 2410 | if (fa->fa_type == RTN_BROADCAST |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 90dca711ac9f..175e093ec564 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_family *ops) | |||
| 1108 | struct inet_sock *inet; | 1108 | struct inet_sock *inet; |
| 1109 | int i; | 1109 | int i; |
| 1110 | 1110 | ||
| 1111 | for (i = 0; i < NR_CPUS; i++) { | 1111 | for_each_cpu(i) { |
| 1112 | int err; | 1112 | int err; |
| 1113 | 1113 | ||
| 1114 | if (!cpu_possible(i)) | ||
| 1115 | continue; | ||
| 1116 | |||
| 1117 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1114 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, |
| 1118 | &per_cpu(__icmp_socket, i)); | 1115 | &per_cpu(__icmp_socket, i)); |
| 1119 | 1116 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 1ad5202e556b..87e350069abb 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -1023,10 +1023,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, | |||
| 1023 | int alloclen; | 1023 | int alloclen; |
| 1024 | 1024 | ||
| 1025 | skb_prev = skb; | 1025 | skb_prev = skb; |
| 1026 | if (skb_prev) | 1026 | fraggap = skb_prev->len - maxfraglen; |
| 1027 | fraggap = skb_prev->len - maxfraglen; | ||
| 1028 | else | ||
| 1029 | fraggap = 0; | ||
| 1030 | 1027 | ||
| 1031 | alloclen = fragheaderlen + hh_len + fraggap + 15; | 1028 | alloclen = fragheaderlen + hh_len + fraggap + 15; |
| 1032 | skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation); | 1029 | skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation); |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 07a80b56e8dc..422ab68ee7fb 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 50 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
| 51 | #include <linux/netfilter_ipv4/listhelp.h> | 51 | #include <linux/netfilter_ipv4/listhelp.h> |
| 52 | 52 | ||
| 53 | #define IP_CONNTRACK_VERSION "2.3" | 53 | #define IP_CONNTRACK_VERSION "2.4" |
| 54 | 54 | ||
| 55 | #if 0 | 55 | #if 0 |
| 56 | #define DEBUGP printk | 56 | #define DEBUGP printk |
| @@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat); | |||
| 148 | static int ip_conntrack_hash_rnd_initted; | 148 | static int ip_conntrack_hash_rnd_initted; |
| 149 | static unsigned int ip_conntrack_hash_rnd; | 149 | static unsigned int ip_conntrack_hash_rnd; |
| 150 | 150 | ||
| 151 | static u_int32_t | 151 | static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple, |
| 152 | hash_conntrack(const struct ip_conntrack_tuple *tuple) | 152 | unsigned int size, unsigned int rnd) |
| 153 | { | 153 | { |
| 154 | #if 0 | ||
| 155 | dump_tuple(tuple); | ||
| 156 | #endif | ||
| 157 | return (jhash_3words(tuple->src.ip, | 154 | return (jhash_3words(tuple->src.ip, |
| 158 | (tuple->dst.ip ^ tuple->dst.protonum), | 155 | (tuple->dst.ip ^ tuple->dst.protonum), |
| 159 | (tuple->src.u.all | (tuple->dst.u.all << 16)), | 156 | (tuple->src.u.all | (tuple->dst.u.all << 16)), |
| 160 | ip_conntrack_hash_rnd) % ip_conntrack_htable_size); | 157 | rnd) % size); |
| 158 | } | ||
| 159 | |||
| 160 | static u_int32_t | ||
| 161 | hash_conntrack(const struct ip_conntrack_tuple *tuple) | ||
| 162 | { | ||
| 163 | return __hash_conntrack(tuple, ip_conntrack_htable_size, | ||
| 164 | ip_conntrack_hash_rnd); | ||
| 161 | } | 165 | } |
| 162 | 166 | ||
| 163 | int | 167 | int |
| @@ -1341,14 +1345,13 @@ static int kill_all(struct ip_conntrack *i, void *data) | |||
| 1341 | return 1; | 1345 | return 1; |
| 1342 | } | 1346 | } |
| 1343 | 1347 | ||
| 1344 | static void free_conntrack_hash(void) | 1348 | static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size) |
| 1345 | { | 1349 | { |
| 1346 | if (ip_conntrack_vmalloc) | 1350 | if (vmalloced) |
| 1347 | vfree(ip_conntrack_hash); | 1351 | vfree(hash); |
| 1348 | else | 1352 | else |
| 1349 | free_pages((unsigned long)ip_conntrack_hash, | 1353 | free_pages((unsigned long)hash, |
| 1350 | get_order(sizeof(struct list_head) | 1354 | get_order(sizeof(struct list_head) * size)); |
| 1351 | * ip_conntrack_htable_size)); | ||
| 1352 | } | 1355 | } |
| 1353 | 1356 | ||
| 1354 | void ip_conntrack_flush() | 1357 | void ip_conntrack_flush() |
| @@ -1378,12 +1381,83 @@ void ip_conntrack_cleanup(void) | |||
| 1378 | ip_conntrack_flush(); | 1381 | ip_conntrack_flush(); |
| 1379 | kmem_cache_destroy(ip_conntrack_cachep); | 1382 | kmem_cache_destroy(ip_conntrack_cachep); |
| 1380 | kmem_cache_destroy(ip_conntrack_expect_cachep); | 1383 | kmem_cache_destroy(ip_conntrack_expect_cachep); |
| 1381 | free_conntrack_hash(); | 1384 | free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc, |
| 1385 | ip_conntrack_htable_size); | ||
| 1382 | nf_unregister_sockopt(&so_getorigdst); | 1386 | nf_unregister_sockopt(&so_getorigdst); |
| 1383 | } | 1387 | } |
| 1384 | 1388 | ||
| 1385 | static int hashsize; | 1389 | static struct list_head *alloc_hashtable(int size, int *vmalloced) |
| 1386 | module_param(hashsize, int, 0400); | 1390 | { |
| 1391 | struct list_head *hash; | ||
| 1392 | unsigned int i; | ||
| 1393 | |||
| 1394 | *vmalloced = 0; | ||
| 1395 | hash = (void*)__get_free_pages(GFP_KERNEL, | ||
| 1396 | get_order(sizeof(struct list_head) | ||
| 1397 | * size)); | ||
| 1398 | if (!hash) { | ||
| 1399 | *vmalloced = 1; | ||
| 1400 | printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n"); | ||
| 1401 | hash = vmalloc(sizeof(struct list_head) * size); | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | if (hash) | ||
| 1405 | for (i = 0; i < size; i++) | ||
| 1406 | INIT_LIST_HEAD(&hash[i]); | ||
| 1407 | |||
| 1408 | return hash; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | int set_hashsize(const char *val, struct kernel_param *kp) | ||
| 1412 | { | ||
| 1413 | int i, bucket, hashsize, vmalloced; | ||
| 1414 | int old_vmalloced, old_size; | ||
| 1415 | int rnd; | ||
| 1416 | struct list_head *hash, *old_hash; | ||
| 1417 | struct ip_conntrack_tuple_hash *h; | ||
| 1418 | |||
| 1419 | /* On boot, we can set this without any fancy locking. */ | ||
| 1420 | if (!ip_conntrack_htable_size) | ||
| 1421 | return param_set_int(val, kp); | ||
| 1422 | |||
| 1423 | hashsize = simple_strtol(val, NULL, 0); | ||
| 1424 | if (!hashsize) | ||
| 1425 | return -EINVAL; | ||
| 1426 | |||
| 1427 | hash = alloc_hashtable(hashsize, &vmalloced); | ||
| 1428 | if (!hash) | ||
| 1429 | return -ENOMEM; | ||
| 1430 | |||
| 1431 | /* We have to rehash for the new table anyway, so we also can | ||
| 1432 | * use a new random seed */ | ||
| 1433 | get_random_bytes(&rnd, 4); | ||
| 1434 | |||
| 1435 | write_lock_bh(&ip_conntrack_lock); | ||
| 1436 | for (i = 0; i < ip_conntrack_htable_size; i++) { | ||
| 1437 | while (!list_empty(&ip_conntrack_hash[i])) { | ||
| 1438 | h = list_entry(ip_conntrack_hash[i].next, | ||
| 1439 | struct ip_conntrack_tuple_hash, list); | ||
| 1440 | list_del(&h->list); | ||
| 1441 | bucket = __hash_conntrack(&h->tuple, hashsize, rnd); | ||
| 1442 | list_add_tail(&h->list, &hash[bucket]); | ||
| 1443 | } | ||
| 1444 | } | ||
| 1445 | old_size = ip_conntrack_htable_size; | ||
| 1446 | old_vmalloced = ip_conntrack_vmalloc; | ||
| 1447 | old_hash = ip_conntrack_hash; | ||
| 1448 | |||
| 1449 | ip_conntrack_htable_size = hashsize; | ||
| 1450 | ip_conntrack_vmalloc = vmalloced; | ||
| 1451 | ip_conntrack_hash = hash; | ||
| 1452 | ip_conntrack_hash_rnd = rnd; | ||
| 1453 | write_unlock_bh(&ip_conntrack_lock); | ||
| 1454 | |||
| 1455 | free_conntrack_hash(old_hash, old_vmalloced, old_size); | ||
| 1456 | return 0; | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | module_param_call(hashsize, set_hashsize, param_get_uint, | ||
| 1460 | &ip_conntrack_htable_size, 0600); | ||
| 1387 | 1461 | ||
| 1388 | int __init ip_conntrack_init(void) | 1462 | int __init ip_conntrack_init(void) |
| 1389 | { | 1463 | { |
| @@ -1392,9 +1466,7 @@ int __init ip_conntrack_init(void) | |||
| 1392 | 1466 | ||
| 1393 | /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB | 1467 | /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB |
| 1394 | * machine has 256 buckets. >= 1GB machines have 8192 buckets. */ | 1468 | * machine has 256 buckets. >= 1GB machines have 8192 buckets. */ |
| 1395 | if (hashsize) { | 1469 | if (!ip_conntrack_htable_size) { |
| 1396 | ip_conntrack_htable_size = hashsize; | ||
| 1397 | } else { | ||
| 1398 | ip_conntrack_htable_size | 1470 | ip_conntrack_htable_size |
| 1399 | = (((num_physpages << PAGE_SHIFT) / 16384) | 1471 | = (((num_physpages << PAGE_SHIFT) / 16384) |
| 1400 | / sizeof(struct list_head)); | 1472 | / sizeof(struct list_head)); |
| @@ -1416,20 +1488,8 @@ int __init ip_conntrack_init(void) | |||
| 1416 | return ret; | 1488 | return ret; |
| 1417 | } | 1489 | } |
| 1418 | 1490 | ||
| 1419 | /* AK: the hash table is twice as big than needed because it | 1491 | ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size, |
| 1420 | uses list_head. it would be much nicer to caches to use a | 1492 | &ip_conntrack_vmalloc); |
| 1421 | single pointer list head here. */ | ||
| 1422 | ip_conntrack_vmalloc = 0; | ||
| 1423 | ip_conntrack_hash | ||
| 1424 | =(void*)__get_free_pages(GFP_KERNEL, | ||
| 1425 | get_order(sizeof(struct list_head) | ||
| 1426 | *ip_conntrack_htable_size)); | ||
| 1427 | if (!ip_conntrack_hash) { | ||
| 1428 | ip_conntrack_vmalloc = 1; | ||
| 1429 | printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n"); | ||
| 1430 | ip_conntrack_hash = vmalloc(sizeof(struct list_head) | ||
| 1431 | * ip_conntrack_htable_size); | ||
| 1432 | } | ||
| 1433 | if (!ip_conntrack_hash) { | 1493 | if (!ip_conntrack_hash) { |
| 1434 | printk(KERN_ERR "Unable to create ip_conntrack_hash\n"); | 1494 | printk(KERN_ERR "Unable to create ip_conntrack_hash\n"); |
| 1435 | goto err_unreg_sockopt; | 1495 | goto err_unreg_sockopt; |
| @@ -1461,9 +1521,6 @@ int __init ip_conntrack_init(void) | |||
| 1461 | ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp; | 1521 | ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp; |
| 1462 | write_unlock_bh(&ip_conntrack_lock); | 1522 | write_unlock_bh(&ip_conntrack_lock); |
| 1463 | 1523 | ||
| 1464 | for (i = 0; i < ip_conntrack_htable_size; i++) | ||
| 1465 | INIT_LIST_HEAD(&ip_conntrack_hash[i]); | ||
| 1466 | |||
| 1467 | /* For use by ipt_REJECT */ | 1524 | /* For use by ipt_REJECT */ |
| 1468 | ip_ct_attach = ip_conntrack_attach; | 1525 | ip_ct_attach = ip_conntrack_attach; |
| 1469 | 1526 | ||
| @@ -1478,7 +1535,8 @@ int __init ip_conntrack_init(void) | |||
| 1478 | err_free_conntrack_slab: | 1535 | err_free_conntrack_slab: |
| 1479 | kmem_cache_destroy(ip_conntrack_cachep); | 1536 | kmem_cache_destroy(ip_conntrack_cachep); |
| 1480 | err_free_hash: | 1537 | err_free_hash: |
| 1481 | free_conntrack_hash(); | 1538 | free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc, |
| 1539 | ip_conntrack_htable_size); | ||
| 1482 | err_unreg_sockopt: | 1540 | err_unreg_sockopt: |
| 1483 | nf_unregister_sockopt(&so_getorigdst); | 1541 | nf_unregister_sockopt(&so_getorigdst); |
| 1484 | 1542 | ||
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index f7943ba1f43c..a65e508fbd40 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -90,9 +90,7 @@ fold_field(void *mib[], int offt) | |||
| 90 | unsigned long res = 0; | 90 | unsigned long res = 0; |
| 91 | int i; | 91 | int i; |
| 92 | 92 | ||
| 93 | for (i = 0; i < NR_CPUS; i++) { | 93 | for_each_cpu(i) { |
| 94 | if (!cpu_possible(i)) | ||
| 95 | continue; | ||
| 96 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); | 94 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); |
| 97 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); | 95 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); |
| 98 | } | 96 | } |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index b7185fb3377c..23e540365a14 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -700,10 +700,7 @@ int __init icmpv6_init(struct net_proto_family *ops) | |||
| 700 | struct sock *sk; | 700 | struct sock *sk; |
| 701 | int err, i, j; | 701 | int err, i, j; |
| 702 | 702 | ||
| 703 | for (i = 0; i < NR_CPUS; i++) { | 703 | for_each_cpu(i) { |
| 704 | if (!cpu_possible(i)) | ||
| 705 | continue; | ||
| 706 | |||
| 707 | err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, | 704 | err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, |
| 708 | &per_cpu(__icmpv6_socket, i)); | 705 | &per_cpu(__icmpv6_socket, i)); |
| 709 | if (err < 0) { | 706 | if (err < 0) { |
| @@ -749,9 +746,7 @@ void icmpv6_cleanup(void) | |||
| 749 | { | 746 | { |
| 750 | int i; | 747 | int i; |
| 751 | 748 | ||
| 752 | for (i = 0; i < NR_CPUS; i++) { | 749 | for_each_cpu(i) { |
| 753 | if (!cpu_possible(i)) | ||
| 754 | continue; | ||
| 755 | sock_release(per_cpu(__icmpv6_socket, i)); | 750 | sock_release(per_cpu(__icmpv6_socket, i)); |
| 756 | } | 751 | } |
| 757 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); | 752 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 334a5967831e..50a13e75d70e 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
| @@ -140,9 +140,7 @@ fold_field(void *mib[], int offt) | |||
| 140 | unsigned long res = 0; | 140 | unsigned long res = 0; |
| 141 | int i; | 141 | int i; |
| 142 | 142 | ||
| 143 | for (i = 0; i < NR_CPUS; i++) { | 143 | for_each_cpu(i) { |
| 144 | if (!cpu_possible(i)) | ||
| 145 | continue; | ||
| 146 | res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); | 144 | res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); |
| 147 | res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); | 145 | res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); |
| 148 | } | 146 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 291df2e4c492..5ca283537bc6 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -740,11 +740,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t | |||
| 740 | 740 | ||
| 741 | int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol) | 741 | int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol) |
| 742 | { | 742 | { |
| 743 | struct netlink_sock *nlk; | ||
| 744 | int len = skb->len; | 743 | int len = skb->len; |
| 745 | 744 | ||
| 746 | nlk = nlk_sk(sk); | ||
| 747 | |||
| 748 | skb_queue_tail(&sk->sk_receive_queue, skb); | 745 | skb_queue_tail(&sk->sk_receive_queue, skb); |
| 749 | sk->sk_data_ready(sk, len); | 746 | sk->sk_data_ready(sk, len); |
| 750 | sock_put(sk); | 747 | sock_put(sk); |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index e556d92c0bc4..b18fe5043019 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -727,7 +727,7 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg) | |||
| 727 | } | 727 | } |
| 728 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ | 728 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ |
| 729 | return -EINVAL; | 729 | return -EINVAL; |
| 730 | if (rose_route.ndigis > 8) /* No more than 8 digipeats */ | 730 | if (rose_route.ndigis > AX25_MAX_DIGIS) |
| 731 | return -EINVAL; | 731 | return -EINVAL; |
| 732 | err = rose_add_node(&rose_route, dev); | 732 | err = rose_add_node(&rose_route, dev); |
| 733 | dev_put(dev); | 733 | dev_put(dev); |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index b74f7772b576..6e4dc28874d7 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -69,9 +69,7 @@ fold_field(void *mib[], int nr) | |||
| 69 | unsigned long res = 0; | 69 | unsigned long res = 0; |
| 70 | int i; | 70 | int i; |
| 71 | 71 | ||
| 72 | for (i = 0; i < NR_CPUS; i++) { | 72 | for_each_cpu(i) { |
| 73 | if (!cpu_possible(i)) | ||
| 74 | continue; | ||
| 75 | res += | 73 | res += |
| 76 | *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + | 74 | *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + |
| 77 | sizeof (unsigned long) * nr)); | 75 | sizeof (unsigned long) * nr)); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cbb0ba34a600..0db9e57013fd 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family) | |||
| 1192 | 1192 | ||
| 1193 | EXPORT_SYMBOL(xfrm_bundle_ok); | 1193 | EXPORT_SYMBOL(xfrm_bundle_ok); |
| 1194 | 1194 | ||
| 1195 | /* Well... that's _TASK_. We need to scan through transformation | ||
| 1196 | * list and figure out what mss tcp should generate in order to | ||
| 1197 | * final datagram fit to mtu. Mama mia... :-) | ||
| 1198 | * | ||
| 1199 | * Apparently, some easy way exists, but we used to choose the most | ||
| 1200 | * bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta. | ||
| 1201 | * | ||
| 1202 | * Consider this function as something like dark humour. :-) | ||
| 1203 | */ | ||
| 1204 | static int xfrm_get_mss(struct dst_entry *dst, u32 mtu) | ||
| 1205 | { | ||
| 1206 | int res = mtu - dst->header_len; | ||
| 1207 | |||
| 1208 | for (;;) { | ||
| 1209 | struct dst_entry *d = dst; | ||
| 1210 | int m = res; | ||
| 1211 | |||
| 1212 | do { | ||
| 1213 | struct xfrm_state *x = d->xfrm; | ||
| 1214 | if (x) { | ||
| 1215 | spin_lock_bh(&x->lock); | ||
| 1216 | if (x->km.state == XFRM_STATE_VALID && | ||
| 1217 | x->type && x->type->get_max_size) | ||
| 1218 | m = x->type->get_max_size(d->xfrm, m); | ||
| 1219 | else | ||
| 1220 | m += x->props.header_len; | ||
| 1221 | spin_unlock_bh(&x->lock); | ||
| 1222 | } | ||
| 1223 | } while ((d = d->child) != NULL); | ||
| 1224 | |||
| 1225 | if (m <= mtu) | ||
| 1226 | break; | ||
| 1227 | res -= (m - mtu); | ||
| 1228 | if (res < 88) | ||
| 1229 | return mtu; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | return res + dst->header_len; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 1195 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
| 1236 | { | 1196 | { |
| 1237 | int err = 0; | 1197 | int err = 0; |
| @@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1252 | dst_ops->negative_advice = xfrm_negative_advice; | 1212 | dst_ops->negative_advice = xfrm_negative_advice; |
| 1253 | if (likely(dst_ops->link_failure == NULL)) | 1213 | if (likely(dst_ops->link_failure == NULL)) |
| 1254 | dst_ops->link_failure = xfrm_link_failure; | 1214 | dst_ops->link_failure = xfrm_link_failure; |
| 1255 | if (likely(dst_ops->get_mss == NULL)) | ||
| 1256 | dst_ops->get_mss = xfrm_get_mss; | ||
| 1257 | if (likely(afinfo->garbage_collect == NULL)) | 1215 | if (likely(afinfo->garbage_collect == NULL)) |
| 1258 | afinfo->garbage_collect = __xfrm_garbage_collect; | 1216 | afinfo->garbage_collect = __xfrm_garbage_collect; |
| 1259 | xfrm_policy_afinfo[afinfo->family] = afinfo; | 1217 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
| @@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1281 | dst_ops->check = NULL; | 1239 | dst_ops->check = NULL; |
| 1282 | dst_ops->negative_advice = NULL; | 1240 | dst_ops->negative_advice = NULL; |
| 1283 | dst_ops->link_failure = NULL; | 1241 | dst_ops->link_failure = NULL; |
| 1284 | dst_ops->get_mss = NULL; | ||
| 1285 | afinfo->garbage_collect = NULL; | 1242 | afinfo->garbage_collect = NULL; |
| 1286 | } | 1243 | } |
| 1287 | } | 1244 | } |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 9d206c282cf1..8b9a4747417d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -1026,6 +1026,12 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x) | |||
| 1026 | } | 1026 | } |
| 1027 | EXPORT_SYMBOL(xfrm_state_delete_tunnel); | 1027 | EXPORT_SYMBOL(xfrm_state_delete_tunnel); |
| 1028 | 1028 | ||
| 1029 | /* | ||
| 1030 | * This function is NOT optimal. For example, with ESP it will give an | ||
| 1031 | * MTU that's usually two bytes short of being optimal. However, it will | ||
| 1032 | * usually give an answer that's a multiple of 4 provided the input is | ||
| 1033 | * also a multiple of 4. | ||
| 1034 | */ | ||
| 1029 | int xfrm_state_mtu(struct xfrm_state *x, int mtu) | 1035 | int xfrm_state_mtu(struct xfrm_state *x, int mtu) |
| 1030 | { | 1036 | { |
| 1031 | int res = mtu; | 1037 | int res = mtu; |
