mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-04 05:11:46 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.15
This commit is contained in:
commit
236fa08168
19 changed files with 347 additions and 407 deletions
|
@ -171,7 +171,6 @@ enum {
|
||||||
* struct sk_buff - socket buffer
|
* struct sk_buff - socket buffer
|
||||||
* @next: Next buffer in list
|
* @next: Next buffer in list
|
||||||
* @prev: Previous buffer in list
|
* @prev: Previous buffer in list
|
||||||
* @list: List we are on
|
|
||||||
* @sk: Socket we are owned by
|
* @sk: Socket we are owned by
|
||||||
* @tstamp: Time we arrived
|
* @tstamp: Time we arrived
|
||||||
* @dev: Device we arrived on/are leaving by
|
* @dev: Device we arrived on/are leaving by
|
||||||
|
@ -190,6 +189,7 @@ enum {
|
||||||
* @cloned: Head may be cloned (check refcnt to be sure)
|
* @cloned: Head may be cloned (check refcnt to be sure)
|
||||||
* @nohdr: Payload reference only, must not modify header
|
* @nohdr: Payload reference only, must not modify header
|
||||||
* @pkt_type: Packet class
|
* @pkt_type: Packet class
|
||||||
|
* @fclone: skbuff clone status
|
||||||
* @ip_summed: Driver fed us an IP checksum
|
* @ip_summed: Driver fed us an IP checksum
|
||||||
* @priority: Packet queueing priority
|
* @priority: Packet queueing priority
|
||||||
* @users: User count - see {datagram,tcp}.c
|
* @users: User count - see {datagram,tcp}.c
|
||||||
|
@ -202,6 +202,7 @@ enum {
|
||||||
* @destructor: Destruct function
|
* @destructor: Destruct function
|
||||||
* @nfmark: Can be used for communication between hooks
|
* @nfmark: Can be used for communication between hooks
|
||||||
* @nfct: Associated connection, if any
|
* @nfct: Associated connection, if any
|
||||||
|
* @ipvs_property: skbuff is owned by ipvs
|
||||||
* @nfctinfo: Relationship of this skb to the connection
|
* @nfctinfo: Relationship of this skb to the connection
|
||||||
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
|
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
|
||||||
* @tc_index: Traffic control index
|
* @tc_index: Traffic control index
|
||||||
|
|
|
@ -94,7 +94,6 @@ struct dst_ops
|
||||||
struct dst_entry * (*negative_advice)(struct dst_entry *);
|
struct dst_entry * (*negative_advice)(struct dst_entry *);
|
||||||
void (*link_failure)(struct sk_buff *);
|
void (*link_failure)(struct sk_buff *);
|
||||||
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
|
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
|
||||||
int (*get_mss)(struct dst_entry *dst, u32 mtu);
|
|
||||||
int entry_size;
|
int entry_size;
|
||||||
|
|
||||||
atomic_t entries;
|
atomic_t entries;
|
||||||
|
|
|
@ -1625,12 +1625,9 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
|
||||||
|
|
||||||
memset(&ndst, 0, sizeof(ndst));
|
memset(&ndst, 0, sizeof(ndst));
|
||||||
|
|
||||||
for (cpu = 0; cpu < NR_CPUS; cpu++) {
|
for_each_cpu(cpu) {
|
||||||
struct neigh_statistics *st;
|
struct neigh_statistics *st;
|
||||||
|
|
||||||
if (!cpu_possible(cpu))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
st = per_cpu_ptr(tbl->stats, cpu);
|
st = per_cpu_ptr(tbl->stats, cpu);
|
||||||
ndst.ndts_allocs += st->allocs;
|
ndst.ndts_allocs += st->allocs;
|
||||||
ndst.ndts_destroys += st->destroys;
|
ndst.ndts_destroys += st->destroys;
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
* By design there should only be *one* "controlling" process. In practice
|
* By design there should only be *one* "controlling" process. In practice
|
||||||
* multiple write accesses gives unpredictable result. Understood by "write"
|
* multiple write accesses gives unpredictable result. Understood by "write"
|
||||||
* to /proc gives result code thats should be read be the "writer".
|
* to /proc gives result code thats should be read be the "writer".
|
||||||
* For pratical use this should be no problem.
|
* For practical use this should be no problem.
|
||||||
*
|
*
|
||||||
* Note when adding devices to a specific CPU there good idea to also assign
|
* Note when adding devices to a specific CPU there good idea to also assign
|
||||||
* /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
|
* /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
* New xmit() return, do_div and misc clean up by Stephen Hemminger
|
* New xmit() return, do_div and misc clean up by Stephen Hemminger
|
||||||
* <shemminger@osdl.org> 040923
|
* <shemminger@osdl.org> 040923
|
||||||
*
|
*
|
||||||
* Rany Dunlap fixed u64 printk compiler waring
|
* Randy Dunlap fixed u64 printk compiler waring
|
||||||
*
|
*
|
||||||
* Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
|
* Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
|
||||||
* New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
|
* New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
|
||||||
|
@ -137,6 +137,7 @@
|
||||||
#include <linux/ipv6.h>
|
#include <linux/ipv6.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
|
@ -151,7 +152,7 @@
|
||||||
#include <asm/timex.h>
|
#include <asm/timex.h>
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n"
|
#define VERSION "pktgen v2.63: Packet Generator for packet performance testing.\n"
|
||||||
|
|
||||||
/* #define PG_DEBUG(a) a */
|
/* #define PG_DEBUG(a) a */
|
||||||
#define PG_DEBUG(a)
|
#define PG_DEBUG(a)
|
||||||
|
@ -177,8 +178,8 @@
|
||||||
#define T_REMDEV (1<<3) /* Remove all devs */
|
#define T_REMDEV (1<<3) /* Remove all devs */
|
||||||
|
|
||||||
/* Locks */
|
/* Locks */
|
||||||
#define thread_lock() spin_lock(&_thread_lock)
|
#define thread_lock() down(&pktgen_sem)
|
||||||
#define thread_unlock() spin_unlock(&_thread_lock)
|
#define thread_unlock() up(&pktgen_sem)
|
||||||
|
|
||||||
/* If lock -- can be removed after some work */
|
/* If lock -- can be removed after some work */
|
||||||
#define if_lock(t) spin_lock(&(t->if_lock));
|
#define if_lock(t) spin_lock(&(t->if_lock));
|
||||||
|
@ -186,7 +187,9 @@
|
||||||
|
|
||||||
/* Used to help with determining the pkts on receive */
|
/* Used to help with determining the pkts on receive */
|
||||||
#define PKTGEN_MAGIC 0xbe9be955
|
#define PKTGEN_MAGIC 0xbe9be955
|
||||||
#define PG_PROC_DIR "net/pktgen"
|
#define PG_PROC_DIR "pktgen"
|
||||||
|
#define PGCTRL "pgctrl"
|
||||||
|
static struct proc_dir_entry *pg_proc_dir = NULL;
|
||||||
|
|
||||||
#define MAX_CFLOWS 65536
|
#define MAX_CFLOWS 65536
|
||||||
|
|
||||||
|
@ -202,11 +205,8 @@ struct pktgen_dev {
|
||||||
* Try to keep frequent/infrequent used vars. separated.
|
* Try to keep frequent/infrequent used vars. separated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char ifname[32];
|
char ifname[IFNAMSIZ];
|
||||||
struct proc_dir_entry *proc_ent;
|
|
||||||
char result[512];
|
char result[512];
|
||||||
/* proc file names */
|
|
||||||
char fname[80];
|
|
||||||
|
|
||||||
struct pktgen_thread* pg_thread; /* the owner */
|
struct pktgen_thread* pg_thread; /* the owner */
|
||||||
struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
|
struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
|
||||||
|
@ -244,7 +244,7 @@ struct pktgen_dev {
|
||||||
__u32 seq_num;
|
__u32 seq_num;
|
||||||
|
|
||||||
int clone_skb; /* Use multiple SKBs during packet gen. If this number
|
int clone_skb; /* Use multiple SKBs during packet gen. If this number
|
||||||
* is greater than 1, then that many coppies of the same
|
* is greater than 1, then that many copies of the same
|
||||||
* packet will be sent before a new packet is allocated.
|
* packet will be sent before a new packet is allocated.
|
||||||
* For instance, if you want to send 1024 identical packets
|
* For instance, if you want to send 1024 identical packets
|
||||||
* before creating a new packet, set clone_skb to 1024.
|
* before creating a new packet, set clone_skb to 1024.
|
||||||
|
@ -330,8 +330,6 @@ struct pktgen_thread {
|
||||||
struct pktgen_dev *if_list; /* All device here */
|
struct pktgen_dev *if_list; /* All device here */
|
||||||
struct pktgen_thread* next;
|
struct pktgen_thread* next;
|
||||||
char name[32];
|
char name[32];
|
||||||
char fname[128]; /* name of proc file */
|
|
||||||
struct proc_dir_entry *proc_ent;
|
|
||||||
char result[512];
|
char result[512];
|
||||||
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
|
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
|
||||||
|
|
||||||
|
@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y, int type)
|
||||||
|
|
||||||
/* End of hacks to deal with 64-bit math on x86 */
|
/* End of hacks to deal with 64-bit math on x86 */
|
||||||
|
|
||||||
/** Convert to miliseconds */
|
/** Convert to milliseconds */
|
||||||
static inline __u64 tv_to_ms(const struct timeval* tv)
|
static inline __u64 tv_to_ms(const struct timeval* tv)
|
||||||
{
|
{
|
||||||
__u64 ms = tv->tv_usec / 1000;
|
__u64 ms = tv->tv_usec / 1000;
|
||||||
|
@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __u64 base)
|
||||||
{
|
{
|
||||||
__u64 tmp = n;
|
__u64 tmp = n;
|
||||||
/*
|
/*
|
||||||
* How do we know if the architectrure we are running on
|
* How do we know if the architecture we are running on
|
||||||
* supports division with 64 bit base?
|
* supports division with 64 bit base?
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b)
|
||||||
|
|
||||||
static char version[] __initdata = VERSION;
|
static char version[] __initdata = VERSION;
|
||||||
|
|
||||||
static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
|
|
||||||
static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
|
|
||||||
static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
|
|
||||||
|
|
||||||
static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
|
|
||||||
static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
|
|
||||||
static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
|
|
||||||
static int create_proc_dir(void);
|
|
||||||
static int remove_proc_dir(void);
|
|
||||||
|
|
||||||
static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
|
static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
|
||||||
static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
|
static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
|
||||||
static struct pktgen_thread* pktgen_find_thread(const char* name);
|
static struct pktgen_thread* pktgen_find_thread(const char* name);
|
||||||
|
@ -503,83 +491,41 @@ static int pg_delay_d = 0;
|
||||||
static int pg_clone_skb_d = 0;
|
static int pg_clone_skb_d = 0;
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(_thread_lock);
|
static DECLARE_MUTEX(pktgen_sem);
|
||||||
static struct pktgen_thread *pktgen_threads = NULL;
|
static struct pktgen_thread *pktgen_threads = NULL;
|
||||||
|
|
||||||
static char module_fname[128];
|
|
||||||
static struct proc_dir_entry *module_proc_ent = NULL;
|
|
||||||
|
|
||||||
static struct notifier_block pktgen_notifier_block = {
|
static struct notifier_block pktgen_notifier_block = {
|
||||||
.notifier_call = pktgen_device_event,
|
.notifier_call = pktgen_device_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct file_operations pktgen_fops = {
|
|
||||||
.read = proc_pgctrl_read,
|
|
||||||
.write = proc_pgctrl_write,
|
|
||||||
/* .ioctl = pktgen_ioctl, later maybe */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* /proc handling functions
|
* /proc handling functions
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct proc_dir_entry *pg_proc_dir = NULL;
|
static int pgctrl_show(struct seq_file *seq, void *v)
|
||||||
static int proc_pgctrl_read_eof=0;
|
|
||||||
|
|
||||||
static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
char data[200];
|
seq_puts(seq, VERSION);
|
||||||
int len = 0;
|
return 0;
|
||||||
|
|
||||||
if(proc_pgctrl_read_eof) {
|
|
||||||
proc_pgctrl_read_eof=0;
|
|
||||||
len = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(data, "%s", VERSION);
|
|
||||||
|
|
||||||
len = strlen(data);
|
|
||||||
|
|
||||||
if(len > count) {
|
|
||||||
len =-EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (copy_to_user(buf, data, len)) {
|
|
||||||
len =-EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppos += len;
|
|
||||||
proc_pgctrl_read_eof=1; /* EOF next call */
|
|
||||||
|
|
||||||
out:
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
|
static ssize_t pgctrl_write(struct file* file,const char __user * buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
char *data = NULL;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
char data[128];
|
||||||
|
|
||||||
if (!capable(CAP_NET_ADMIN)){
|
if (!capable(CAP_NET_ADMIN)){
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (void*)vmalloc ((unsigned int)count);
|
if (count > sizeof(data))
|
||||||
|
count = sizeof(data);
|
||||||
|
|
||||||
if(!data) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (copy_from_user(data, buf, count)) {
|
if (copy_from_user(data, buf, count)) {
|
||||||
err =-EFAULT;
|
err = -EFAULT;
|
||||||
goto out_free;
|
goto out;
|
||||||
}
|
}
|
||||||
data[count-1] = 0; /* Make string */
|
data[count-1] = 0; /* Make string */
|
||||||
|
|
||||||
|
@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
|
||||||
|
|
||||||
err = count;
|
err = count;
|
||||||
|
|
||||||
out_free:
|
|
||||||
vfree (data);
|
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_if_read(char *buf , char **start, off_t offset,
|
static int pgctrl_open(struct inode *inode, struct file *file)
|
||||||
int len, int *eof, void *data)
|
{
|
||||||
|
return single_open(file, pgctrl_show, PDE(inode)->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct file_operations pktgen_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = pgctrl_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.write = pgctrl_write,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pktgen_if_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
char *p;
|
|
||||||
int i;
|
int i;
|
||||||
struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
|
struct pktgen_dev *pkt_dev = seq->private;
|
||||||
__u64 sa;
|
__u64 sa;
|
||||||
__u64 stopped;
|
__u64 stopped;
|
||||||
__u64 now = getCurUs();
|
__u64 now = getCurUs();
|
||||||
|
|
||||||
p = buf;
|
seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
|
||||||
p += sprintf(p, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
|
(unsigned long long) pkt_dev->count,
|
||||||
(unsigned long long) pkt_dev->count,
|
pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
|
||||||
pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
|
|
||||||
|
|
||||||
p += sprintf(p, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
|
seq_printf(seq, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
|
||||||
pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
|
pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
|
||||||
|
|
||||||
p += sprintf(p, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
|
seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
|
||||||
|
|
||||||
|
|
||||||
if(pkt_dev->flags & F_IPV6) {
|
if(pkt_dev->flags & F_IPV6) {
|
||||||
|
@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char **start, off_t offset,
|
||||||
fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
|
fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
|
||||||
fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
|
fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
|
||||||
fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
|
fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
|
||||||
p += sprintf(p, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
|
seq_printf(seq, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
|
||||||
|
|
||||||
fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
|
fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
|
||||||
fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
|
fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
|
||||||
fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
|
fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
|
||||||
p += sprintf(p, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
|
seq_printf(seq, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
p += sprintf(p, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
|
seq_printf(seq," dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
|
||||||
pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
|
pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
|
||||||
|
|
||||||
p += sprintf(p, " src_mac: ");
|
seq_puts(seq, " src_mac: ");
|
||||||
|
|
||||||
if ((pkt_dev->src_mac[0] == 0) &&
|
if ((pkt_dev->src_mac[0] == 0) &&
|
||||||
(pkt_dev->src_mac[1] == 0) &&
|
(pkt_dev->src_mac[1] == 0) &&
|
||||||
|
@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char **start, off_t offset,
|
||||||
(pkt_dev->src_mac[5] == 0))
|
(pkt_dev->src_mac[5] == 0))
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
|
seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
|
||||||
|
|
||||||
else
|
else
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
|
seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
|
||||||
|
|
||||||
p += sprintf(p, "dst_mac: ");
|
seq_printf(seq, "dst_mac: ");
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
|
seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
|
||||||
|
|
||||||
p += sprintf(p, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
|
seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
|
||||||
pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
|
pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
|
||||||
pkt_dev->udp_dst_max);
|
pkt_dev->udp_dst_max);
|
||||||
|
|
||||||
p += sprintf(p, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
|
seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
|
||||||
pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
|
pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
|
||||||
|
|
||||||
|
|
||||||
if (pkt_dev->flags & F_IPV6)
|
if (pkt_dev->flags & F_IPV6)
|
||||||
p += sprintf(p, "IPV6 ");
|
seq_printf(seq, "IPV6 ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_IPSRC_RND)
|
if (pkt_dev->flags & F_IPSRC_RND)
|
||||||
p += sprintf(p, "IPSRC_RND ");
|
seq_printf(seq, "IPSRC_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_IPDST_RND)
|
if (pkt_dev->flags & F_IPDST_RND)
|
||||||
p += sprintf(p, "IPDST_RND ");
|
seq_printf(seq, "IPDST_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_TXSIZE_RND)
|
if (pkt_dev->flags & F_TXSIZE_RND)
|
||||||
p += sprintf(p, "TXSIZE_RND ");
|
seq_printf(seq, "TXSIZE_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_UDPSRC_RND)
|
if (pkt_dev->flags & F_UDPSRC_RND)
|
||||||
p += sprintf(p, "UDPSRC_RND ");
|
seq_printf(seq, "UDPSRC_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_UDPDST_RND)
|
if (pkt_dev->flags & F_UDPDST_RND)
|
||||||
p += sprintf(p, "UDPDST_RND ");
|
seq_printf(seq, "UDPDST_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_MACSRC_RND)
|
if (pkt_dev->flags & F_MACSRC_RND)
|
||||||
p += sprintf(p, "MACSRC_RND ");
|
seq_printf(seq, "MACSRC_RND ");
|
||||||
|
|
||||||
if (pkt_dev->flags & F_MACDST_RND)
|
if (pkt_dev->flags & F_MACDST_RND)
|
||||||
p += sprintf(p, "MACDST_RND ");
|
seq_printf(seq, "MACDST_RND ");
|
||||||
|
|
||||||
|
|
||||||
p += sprintf(p, "\n");
|
seq_puts(seq, "\n");
|
||||||
|
|
||||||
sa = pkt_dev->started_at;
|
sa = pkt_dev->started_at;
|
||||||
stopped = pkt_dev->stopped_at;
|
stopped = pkt_dev->stopped_at;
|
||||||
if (pkt_dev->running)
|
if (pkt_dev->running)
|
||||||
stopped = now; /* not really stopped, more like last-running-at */
|
stopped = now; /* not really stopped, more like last-running-at */
|
||||||
|
|
||||||
p += sprintf(p, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
|
seq_printf(seq, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
|
||||||
(unsigned long long) pkt_dev->sofar,
|
(unsigned long long) pkt_dev->sofar,
|
||||||
(unsigned long long) pkt_dev->errors,
|
(unsigned long long) pkt_dev->errors,
|
||||||
(unsigned long long) sa,
|
(unsigned long long) sa,
|
||||||
(unsigned long long) stopped,
|
(unsigned long long) stopped,
|
||||||
(unsigned long long) pkt_dev->idle_acc);
|
(unsigned long long) pkt_dev->idle_acc);
|
||||||
|
|
||||||
p += sprintf(p, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
|
seq_printf(seq, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
|
||||||
pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
|
pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
|
||||||
|
pkt_dev->cur_src_mac_offset);
|
||||||
|
|
||||||
if(pkt_dev->flags & F_IPV6) {
|
if(pkt_dev->flags & F_IPV6) {
|
||||||
char b1[128], b2[128];
|
char b1[128], b2[128];
|
||||||
fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
|
fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
|
||||||
fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
|
fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
|
||||||
p += sprintf(p, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
|
seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
p += sprintf(p, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
|
seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
|
||||||
pkt_dev->cur_saddr, pkt_dev->cur_daddr);
|
pkt_dev->cur_saddr, pkt_dev->cur_daddr);
|
||||||
|
|
||||||
|
|
||||||
p += sprintf(p, " cur_udp_dst: %d cur_udp_src: %d\n",
|
seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
|
||||||
pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
|
pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
|
||||||
|
|
||||||
p += sprintf(p, " flows: %u\n", pkt_dev->nflows);
|
seq_printf(seq, " flows: %u\n", pkt_dev->nflows);
|
||||||
|
|
||||||
if (pkt_dev->result[0])
|
if (pkt_dev->result[0])
|
||||||
p += sprintf(p, "Result: %s\n", pkt_dev->result);
|
seq_printf(seq, "Result: %s\n", pkt_dev->result);
|
||||||
else
|
else
|
||||||
p += sprintf(p, "Result: Idle\n");
|
seq_printf(seq, "Result: Idle\n");
|
||||||
*eof = 1;
|
|
||||||
|
|
||||||
return p - buf;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -802,13 +757,14 @@ done_str:
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_if_write(struct file *file, const char __user *user_buffer,
|
static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer,
|
||||||
unsigned long count, void *data)
|
size_t count, loff_t *offset)
|
||||||
{
|
{
|
||||||
|
struct seq_file *seq = (struct seq_file *) file->private_data;
|
||||||
|
struct pktgen_dev *pkt_dev = seq->private;
|
||||||
int i = 0, max, len;
|
int i = 0, max, len;
|
||||||
char name[16], valstr[32];
|
char name[16], valstr[32];
|
||||||
unsigned long value = 0;
|
unsigned long value = 0;
|
||||||
struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
|
|
||||||
char* pg_result = NULL;
|
char* pg_result = NULL;
|
||||||
int tmp = 0;
|
int tmp = 0;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
@ -849,7 +805,8 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
|
||||||
if (copy_from_user(tb, user_buffer, count))
|
if (copy_from_user(tb, user_buffer, count))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
tb[count] = 0;
|
tb[count] = 0;
|
||||||
printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb);
|
printk("pktgen: %s,%lu buffer -:%s:-\n", name,
|
||||||
|
(unsigned long) count, tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(name, "min_pkt_size")) {
|
if (!strcmp(name, "min_pkt_size")) {
|
||||||
|
@ -1335,54 +1292,61 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_thread_read(char *buf , char **start, off_t offset,
|
static int pktgen_if_open(struct inode *inode, struct file *file)
|
||||||
int len, int *eof, void *data)
|
|
||||||
{
|
{
|
||||||
char *p;
|
return single_open(file, pktgen_if_show, PDE(inode)->data);
|
||||||
struct pktgen_thread *t = (struct pktgen_thread*)(data);
|
}
|
||||||
|
|
||||||
|
static struct file_operations pktgen_if_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = pktgen_if_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.write = pktgen_if_write,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pktgen_thread_show(struct seq_file *seq, void *v)
|
||||||
|
{
|
||||||
|
struct pktgen_thread *t = seq->private;
|
||||||
struct pktgen_dev *pkt_dev = NULL;
|
struct pktgen_dev *pkt_dev = NULL;
|
||||||
|
|
||||||
|
BUG_ON(!t);
|
||||||
|
|
||||||
if (!t) {
|
seq_printf(seq, "Name: %s max_before_softirq: %d\n",
|
||||||
printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = buf;
|
|
||||||
p += sprintf(p, "Name: %s max_before_softirq: %d\n",
|
|
||||||
t->name, t->max_before_softirq);
|
t->name, t->max_before_softirq);
|
||||||
|
|
||||||
p += sprintf(p, "Running: ");
|
seq_printf(seq, "Running: ");
|
||||||
|
|
||||||
if_lock(t);
|
if_lock(t);
|
||||||
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
|
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
|
||||||
if(pkt_dev->running)
|
if(pkt_dev->running)
|
||||||
p += sprintf(p, "%s ", pkt_dev->ifname);
|
seq_printf(seq, "%s ", pkt_dev->ifname);
|
||||||
|
|
||||||
p += sprintf(p, "\nStopped: ");
|
seq_printf(seq, "\nStopped: ");
|
||||||
|
|
||||||
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
|
for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
|
||||||
if(!pkt_dev->running)
|
if(!pkt_dev->running)
|
||||||
p += sprintf(p, "%s ", pkt_dev->ifname);
|
seq_printf(seq, "%s ", pkt_dev->ifname);
|
||||||
|
|
||||||
if (t->result[0])
|
if (t->result[0])
|
||||||
p += sprintf(p, "\nResult: %s\n", t->result);
|
seq_printf(seq, "\nResult: %s\n", t->result);
|
||||||
else
|
else
|
||||||
p += sprintf(p, "\nResult: NA\n");
|
seq_printf(seq, "\nResult: NA\n");
|
||||||
|
|
||||||
*eof = 1;
|
|
||||||
|
|
||||||
if_unlock(t);
|
if_unlock(t);
|
||||||
|
|
||||||
return p - buf;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_thread_write(struct file *file, const char __user *user_buffer,
|
static ssize_t pktgen_thread_write(struct file *file,
|
||||||
unsigned long count, void *data)
|
const char __user *user_buffer,
|
||||||
|
size_t count, loff_t *offset)
|
||||||
{
|
{
|
||||||
|
struct seq_file *seq = (struct seq_file *) file->private_data;
|
||||||
|
struct pktgen_thread *t = seq->private;
|
||||||
int i = 0, max, len, ret;
|
int i = 0, max, len, ret;
|
||||||
char name[40];
|
char name[40];
|
||||||
struct pktgen_thread *t;
|
|
||||||
char *pg_result;
|
char *pg_result;
|
||||||
unsigned long value = 0;
|
unsigned long value = 0;
|
||||||
|
|
||||||
|
@ -1417,10 +1381,9 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
|
||||||
i += len;
|
i += len;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
printk("pktgen: t=%s, count=%lu\n", name, count);
|
printk("pktgen: t=%s, count=%lu\n", name,
|
||||||
|
(unsigned long) count);
|
||||||
|
|
||||||
|
|
||||||
t = (struct pktgen_thread*)(data);
|
|
||||||
if(!t) {
|
if(!t) {
|
||||||
printk("pktgen: ERROR: No thread\n");
|
printk("pktgen: ERROR: No thread\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -1474,21 +1437,19 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_proc_dir(void)
|
static int pktgen_thread_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL);
|
return single_open(file, pktgen_thread_show, PDE(inode)->data);
|
||||||
|
|
||||||
if (!pg_proc_dir)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int remove_proc_dir(void)
|
static struct file_operations pktgen_thread_fops = {
|
||||||
{
|
.owner = THIS_MODULE,
|
||||||
remove_proc_entry(PG_PROC_DIR, NULL);
|
.open = pktgen_thread_open,
|
||||||
return 0;
|
.read = seq_read,
|
||||||
}
|
.llseek = seq_lseek,
|
||||||
|
.write = pktgen_thread_write,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
/* Think find or remove for NN */
|
/* Think find or remove for NN */
|
||||||
static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove)
|
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)
|
||||||
start = now = getCurUs();
|
start = now = getCurUs();
|
||||||
printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
|
printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
|
||||||
while (now < spin_until_us) {
|
while (now < spin_until_us) {
|
||||||
/* TODO: optimise sleeping behavior */
|
/* TODO: optimize sleeping behavior */
|
||||||
if (spin_until_us - now > jiffies_to_usecs(1)+1)
|
if (spin_until_us - now > jiffies_to_usecs(1)+1)
|
||||||
schedule_timeout_interruptible(1);
|
schedule_timeout_interruptible(1);
|
||||||
else if (spin_until_us - now > 100) {
|
else if (spin_until_us - now > 100) {
|
||||||
|
@ -2361,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(void)
|
||||||
pktgen_stop(t);
|
pktgen_stop(t);
|
||||||
t = t->next;
|
t = t->next;
|
||||||
}
|
}
|
||||||
thread_unlock();
|
thread_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int thread_is_running(struct pktgen_thread *t )
|
static int thread_is_running(struct pktgen_thread *t )
|
||||||
|
@ -2552,10 +2513,9 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
|
||||||
|
|
||||||
struct pktgen_thread *tmp = pktgen_threads;
|
struct pktgen_thread *tmp = pktgen_threads;
|
||||||
|
|
||||||
if (strlen(t->fname))
|
remove_proc_entry(t->name, pg_proc_dir);
|
||||||
remove_proc_entry(t->fname, NULL);
|
|
||||||
|
|
||||||
thread_lock();
|
thread_lock();
|
||||||
|
|
||||||
if (tmp == t)
|
if (tmp == t)
|
||||||
pktgen_threads = tmp->next;
|
pktgen_threads = tmp->next;
|
||||||
|
@ -2825,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* i
|
||||||
if_lock(t);
|
if_lock(t);
|
||||||
|
|
||||||
for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
|
for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
|
||||||
if (strcmp(pkt_dev->ifname, ifname) == 0) {
|
if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2864,74 +2824,70 @@ static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev
|
||||||
static int pktgen_add_device(struct pktgen_thread *t, const char* ifname)
|
static int pktgen_add_device(struct pktgen_thread *t, const char* ifname)
|
||||||
{
|
{
|
||||||
struct pktgen_dev *pkt_dev;
|
struct pktgen_dev *pkt_dev;
|
||||||
|
struct proc_dir_entry *pe;
|
||||||
|
|
||||||
/* We don't allow a device to be on several threads */
|
/* We don't allow a device to be on several threads */
|
||||||
|
|
||||||
if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
|
pkt_dev = __pktgen_NN_threads(ifname, FIND);
|
||||||
|
if (pkt_dev) {
|
||||||
pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
|
|
||||||
if (!pkt_dev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memset(pkt_dev, 0, sizeof(struct pktgen_dev));
|
|
||||||
|
|
||||||
pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
|
|
||||||
if (pkt_dev->flows == NULL) {
|
|
||||||
kfree(pkt_dev);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
|
|
||||||
|
|
||||||
pkt_dev->min_pkt_size = ETH_ZLEN;
|
|
||||||
pkt_dev->max_pkt_size = ETH_ZLEN;
|
|
||||||
pkt_dev->nfrags = 0;
|
|
||||||
pkt_dev->clone_skb = pg_clone_skb_d;
|
|
||||||
pkt_dev->delay_us = pg_delay_d / 1000;
|
|
||||||
pkt_dev->delay_ns = pg_delay_d % 1000;
|
|
||||||
pkt_dev->count = pg_count_d;
|
|
||||||
pkt_dev->sofar = 0;
|
|
||||||
pkt_dev->udp_src_min = 9; /* sink port */
|
|
||||||
pkt_dev->udp_src_max = 9;
|
|
||||||
pkt_dev->udp_dst_min = 9;
|
|
||||||
pkt_dev->udp_dst_max = 9;
|
|
||||||
|
|
||||||
strncpy(pkt_dev->ifname, ifname, 31);
|
|
||||||
sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname);
|
|
||||||
|
|
||||||
if (! pktgen_setup_dev(pkt_dev)) {
|
|
||||||
printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
|
|
||||||
if (pkt_dev->flows)
|
|
||||||
vfree(pkt_dev->flows);
|
|
||||||
kfree(pkt_dev);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL);
|
|
||||||
if (!pkt_dev->proc_ent) {
|
|
||||||
printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
|
|
||||||
if (pkt_dev->flows)
|
|
||||||
vfree(pkt_dev->flows);
|
|
||||||
kfree(pkt_dev);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
pkt_dev->proc_ent->read_proc = proc_if_read;
|
|
||||||
pkt_dev->proc_ent->write_proc = proc_if_write;
|
|
||||||
pkt_dev->proc_ent->data = (void*)(pkt_dev);
|
|
||||||
pkt_dev->proc_ent->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
return add_dev_to_thread(t, pkt_dev);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printk("pktgen: ERROR: interface already used.\n");
|
printk("pktgen: ERROR: interface already used.\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
|
||||||
|
if (!pkt_dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
|
||||||
|
if (pkt_dev->flows == NULL) {
|
||||||
|
kfree(pkt_dev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
|
||||||
|
|
||||||
|
pkt_dev->min_pkt_size = ETH_ZLEN;
|
||||||
|
pkt_dev->max_pkt_size = ETH_ZLEN;
|
||||||
|
pkt_dev->nfrags = 0;
|
||||||
|
pkt_dev->clone_skb = pg_clone_skb_d;
|
||||||
|
pkt_dev->delay_us = pg_delay_d / 1000;
|
||||||
|
pkt_dev->delay_ns = pg_delay_d % 1000;
|
||||||
|
pkt_dev->count = pg_count_d;
|
||||||
|
pkt_dev->sofar = 0;
|
||||||
|
pkt_dev->udp_src_min = 9; /* sink port */
|
||||||
|
pkt_dev->udp_src_max = 9;
|
||||||
|
pkt_dev->udp_dst_min = 9;
|
||||||
|
pkt_dev->udp_dst_max = 9;
|
||||||
|
|
||||||
|
strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
|
||||||
|
|
||||||
|
if (! pktgen_setup_dev(pkt_dev)) {
|
||||||
|
printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
|
||||||
|
if (pkt_dev->flows)
|
||||||
|
vfree(pkt_dev->flows);
|
||||||
|
kfree(pkt_dev);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
pe = create_proc_entry(ifname, 0600, pg_proc_dir);
|
||||||
|
if (!pe) {
|
||||||
|
printk("pktgen: cannot create %s/%s procfs entry.\n",
|
||||||
|
PG_PROC_DIR, ifname);
|
||||||
|
if (pkt_dev->flows)
|
||||||
|
vfree(pkt_dev->flows);
|
||||||
|
kfree(pkt_dev);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pe->proc_fops = &pktgen_if_fops;
|
||||||
|
pe->data = pkt_dev;
|
||||||
|
|
||||||
|
return add_dev_to_thread(t, pkt_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pktgen_thread *pktgen_find_thread(const char* name)
|
static struct pktgen_thread *pktgen_find_thread(const char* name)
|
||||||
{
|
{
|
||||||
struct pktgen_thread *t = NULL;
|
struct pktgen_thread *t = NULL;
|
||||||
|
|
||||||
thread_lock();
|
thread_lock();
|
||||||
|
|
||||||
t = pktgen_threads;
|
t = pktgen_threads;
|
||||||
while (t) {
|
while (t) {
|
||||||
|
@ -2947,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name)
|
||||||
static int pktgen_create_thread(const char* name, int cpu)
|
static int pktgen_create_thread(const char* name, int cpu)
|
||||||
{
|
{
|
||||||
struct pktgen_thread *t = NULL;
|
struct pktgen_thread *t = NULL;
|
||||||
|
struct proc_dir_entry *pe;
|
||||||
|
|
||||||
if (strlen(name) > 31) {
|
if (strlen(name) > 31) {
|
||||||
printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n");
|
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)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
|
t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
printk("pktgen: ERROR: out of memory, can't create new thread.\n");
|
printk("pktgen: ERROR: out of memory, can't create new thread.\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(t, 0, sizeof(struct pktgen_thread));
|
|
||||||
strcpy(t->name, name);
|
strcpy(t->name, name);
|
||||||
spin_lock_init(&t->if_lock);
|
spin_lock_init(&t->if_lock);
|
||||||
t->cpu = cpu;
|
t->cpu = cpu;
|
||||||
|
|
||||||
sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name);
|
pe = create_proc_entry(t->name, 0600, pg_proc_dir);
|
||||||
t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
|
if (!pe) {
|
||||||
if (!t->proc_ent) {
|
printk("pktgen: cannot create %s/%s procfs entry.\n",
|
||||||
printk("pktgen: cannot create %s procfs entry.\n", t->fname);
|
PG_PROC_DIR, t->name);
|
||||||
kfree(t);
|
kfree(t);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
t->proc_ent->read_proc = proc_thread_read;
|
|
||||||
t->proc_ent->write_proc = proc_thread_write;
|
pe->proc_fops = &pktgen_thread_fops;
|
||||||
t->proc_ent->data = (void*)(t);
|
pe->data = t;
|
||||||
t->proc_ent->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
t->next = pktgen_threads;
|
t->next = pktgen_threads;
|
||||||
pktgen_threads = t;
|
pktgen_threads = t;
|
||||||
|
@ -3034,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
|
||||||
|
|
||||||
/* Clean up proc file system */
|
/* Clean up proc file system */
|
||||||
|
|
||||||
if (strlen(pkt_dev->fname))
|
remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
|
||||||
remove_proc_entry(pkt_dev->fname, NULL);
|
|
||||||
|
|
||||||
if (pkt_dev->flows)
|
if (pkt_dev->flows)
|
||||||
vfree(pkt_dev->flows);
|
vfree(pkt_dev->flows);
|
||||||
|
@ -3046,31 +3000,31 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
|
||||||
static int __init pg_init(void)
|
static int __init pg_init(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
struct proc_dir_entry *pe;
|
||||||
|
|
||||||
printk(version);
|
printk(version);
|
||||||
|
|
||||||
module_fname[0] = 0;
|
pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
|
||||||
|
if (!pg_proc_dir)
|
||||||
|
return -ENODEV;
|
||||||
|
pg_proc_dir->owner = THIS_MODULE;
|
||||||
|
|
||||||
create_proc_dir();
|
pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
|
||||||
|
if (pe == NULL) {
|
||||||
sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR);
|
printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL);
|
||||||
module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
|
proc_net_remove(PG_PROC_DIR);
|
||||||
if (!module_proc_ent) {
|
|
||||||
printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_proc_ent->proc_fops = &pktgen_fops;
|
pe->proc_fops = &pktgen_fops;
|
||||||
module_proc_ent->data = NULL;
|
pe->data = NULL;
|
||||||
|
|
||||||
/* Register us to receive netdevice events */
|
/* Register us to receive netdevice events */
|
||||||
register_netdevice_notifier(&pktgen_notifier_block);
|
register_netdevice_notifier(&pktgen_notifier_block);
|
||||||
|
|
||||||
for (cpu = 0; cpu < NR_CPUS ; cpu++) {
|
for_each_online_cpu(cpu) {
|
||||||
char buf[30];
|
char buf[30];
|
||||||
|
|
||||||
if (!cpu_online(cpu))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sprintf(buf, "kpktgend_%i", cpu);
|
sprintf(buf, "kpktgend_%i", cpu);
|
||||||
pktgen_create_thread(buf, cpu);
|
pktgen_create_thread(buf, cpu);
|
||||||
}
|
}
|
||||||
|
@ -3095,10 +3049,8 @@ static void __exit pg_cleanup(void)
|
||||||
unregister_netdevice_notifier(&pktgen_notifier_block);
|
unregister_netdevice_notifier(&pktgen_notifier_block);
|
||||||
|
|
||||||
/* Clean up proc file system */
|
/* Clean up proc file system */
|
||||||
|
remove_proc_entry(PGCTRL, pg_proc_dir);
|
||||||
remove_proc_entry(module_fname, NULL);
|
proc_net_remove(PG_PROC_DIR);
|
||||||
|
|
||||||
remove_proc_dir();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
|
||||||
* __alloc_skb - allocate a network buffer
|
* __alloc_skb - allocate a network buffer
|
||||||
* @size: size to allocate
|
* @size: size to allocate
|
||||||
* @gfp_mask: allocation mask
|
* @gfp_mask: allocation mask
|
||||||
|
* @fclone: allocate from fclone cache instead of head cache
|
||||||
|
* and allocate a cloned (child) skb
|
||||||
*
|
*
|
||||||
* Allocate a new &sk_buff. The returned buffer has no headroom and a
|
* Allocate a new &sk_buff. The returned buffer has no headroom and a
|
||||||
* tail room of size bytes. The object has a reference count of one.
|
* tail room of size bytes. The object has a reference count of one.
|
||||||
|
|
|
@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||||
if (saddr->sdn_flags & ~SDF_WILD)
|
if (saddr->sdn_flags & ~SDF_WILD)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
|
if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
|
||||||
(saddr->sdn_flags & SDF_WILD)))
|
(saddr->sdn_flags & SDF_WILD)))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Maybe put the default actions in the default security ops for
|
|
||||||
* dn_prot_sock ? Would be nice if the capable call would go there
|
|
||||||
* too.
|
|
||||||
*/
|
|
||||||
if (security_dn_prot_sock(saddr) &&
|
|
||||||
!capable(CAP_NET_BIND_SERVICE) ||
|
|
||||||
saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD))
|
|
||||||
return -EACCES;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
if (!(saddr->sdn_flags & SDF_WILD)) {
|
if (!(saddr->sdn_flags & SDF_WILD)) {
|
||||||
if (dn_ntohs(saddr->sdn_nodeaddrl)) {
|
if (dn_ntohs(saddr->sdn_nodeaddrl)) {
|
||||||
|
|
|
@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
|
||||||
break;
|
break;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
|
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
|
||||||
|
u32 old_mask = ifa->ifa_mask;
|
||||||
inet_del_ifa(in_dev, ifap, 0);
|
inet_del_ifa(in_dev, ifap, 0);
|
||||||
ifa->ifa_mask = sin->sin_addr.s_addr;
|
ifa->ifa_mask = sin->sin_addr.s_addr;
|
||||||
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
|
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
|
||||||
|
@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
|
||||||
if ((dev->flags & IFF_BROADCAST) &&
|
if ((dev->flags & IFF_BROADCAST) &&
|
||||||
(ifa->ifa_prefixlen < 31) &&
|
(ifa->ifa_prefixlen < 31) &&
|
||||||
(ifa->ifa_broadcast ==
|
(ifa->ifa_broadcast ==
|
||||||
(ifa->ifa_local|~ifa->ifa_mask))) {
|
(ifa->ifa_local|~old_mask))) {
|
||||||
ifa->ifa_broadcast = (ifa->ifa_local |
|
ifa->ifa_broadcast = (ifa->ifa_local |
|
||||||
~sin->sin_addr.s_addr);
|
~sin->sin_addr.s_addr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2404,7 +2404,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
|
||||||
prefix = htonl(l->key);
|
prefix = htonl(l->key);
|
||||||
|
|
||||||
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
|
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
|
||||||
const struct fib_info *fi = rcu_dereference(fa->fa_info);
|
const struct fib_info *fi = fa->fa_info;
|
||||||
unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
|
unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
|
||||||
|
|
||||||
if (fa->fa_type == RTN_BROADCAST
|
if (fa->fa_type == RTN_BROADCAST
|
||||||
|
|
|
@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_family *ops)
|
||||||
struct inet_sock *inet;
|
struct inet_sock *inet;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
|
err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
|
||||||
&per_cpu(__icmp_socket, i));
|
&per_cpu(__icmp_socket, i));
|
||||||
|
|
||||||
|
|
|
@ -1023,10 +1023,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
|
||||||
int alloclen;
|
int alloclen;
|
||||||
|
|
||||||
skb_prev = skb;
|
skb_prev = skb;
|
||||||
if (skb_prev)
|
fraggap = skb_prev->len - maxfraglen;
|
||||||
fraggap = skb_prev->len - maxfraglen;
|
|
||||||
else
|
|
||||||
fraggap = 0;
|
|
||||||
|
|
||||||
alloclen = fragheaderlen + hh_len + fraggap + 15;
|
alloclen = fragheaderlen + hh_len + fraggap + 15;
|
||||||
skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
|
skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
||||||
#include <linux/netfilter_ipv4/listhelp.h>
|
#include <linux/netfilter_ipv4/listhelp.h>
|
||||||
|
|
||||||
#define IP_CONNTRACK_VERSION "2.3"
|
#define IP_CONNTRACK_VERSION "2.4"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define DEBUGP printk
|
#define DEBUGP printk
|
||||||
|
@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
|
||||||
static int ip_conntrack_hash_rnd_initted;
|
static int ip_conntrack_hash_rnd_initted;
|
||||||
static unsigned int ip_conntrack_hash_rnd;
|
static unsigned int ip_conntrack_hash_rnd;
|
||||||
|
|
||||||
static u_int32_t
|
static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
|
||||||
hash_conntrack(const struct ip_conntrack_tuple *tuple)
|
unsigned int size, unsigned int rnd)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
dump_tuple(tuple);
|
|
||||||
#endif
|
|
||||||
return (jhash_3words(tuple->src.ip,
|
return (jhash_3words(tuple->src.ip,
|
||||||
(tuple->dst.ip ^ tuple->dst.protonum),
|
(tuple->dst.ip ^ tuple->dst.protonum),
|
||||||
(tuple->src.u.all | (tuple->dst.u.all << 16)),
|
(tuple->src.u.all | (tuple->dst.u.all << 16)),
|
||||||
ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
|
rnd) % size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int32_t
|
||||||
|
hash_conntrack(const struct ip_conntrack_tuple *tuple)
|
||||||
|
{
|
||||||
|
return __hash_conntrack(tuple, ip_conntrack_htable_size,
|
||||||
|
ip_conntrack_hash_rnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1341,14 +1345,13 @@ static int kill_all(struct ip_conntrack *i, void *data)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_conntrack_hash(void)
|
static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
|
||||||
{
|
{
|
||||||
if (ip_conntrack_vmalloc)
|
if (vmalloced)
|
||||||
vfree(ip_conntrack_hash);
|
vfree(hash);
|
||||||
else
|
else
|
||||||
free_pages((unsigned long)ip_conntrack_hash,
|
free_pages((unsigned long)hash,
|
||||||
get_order(sizeof(struct list_head)
|
get_order(sizeof(struct list_head) * size));
|
||||||
* ip_conntrack_htable_size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip_conntrack_flush()
|
void ip_conntrack_flush()
|
||||||
|
@ -1378,12 +1381,83 @@ void ip_conntrack_cleanup(void)
|
||||||
ip_conntrack_flush();
|
ip_conntrack_flush();
|
||||||
kmem_cache_destroy(ip_conntrack_cachep);
|
kmem_cache_destroy(ip_conntrack_cachep);
|
||||||
kmem_cache_destroy(ip_conntrack_expect_cachep);
|
kmem_cache_destroy(ip_conntrack_expect_cachep);
|
||||||
free_conntrack_hash();
|
free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
|
||||||
|
ip_conntrack_htable_size);
|
||||||
nf_unregister_sockopt(&so_getorigdst);
|
nf_unregister_sockopt(&so_getorigdst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hashsize;
|
static struct list_head *alloc_hashtable(int size, int *vmalloced)
|
||||||
module_param(hashsize, int, 0400);
|
{
|
||||||
|
struct list_head *hash;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
*vmalloced = 0;
|
||||||
|
hash = (void*)__get_free_pages(GFP_KERNEL,
|
||||||
|
get_order(sizeof(struct list_head)
|
||||||
|
* size));
|
||||||
|
if (!hash) {
|
||||||
|
*vmalloced = 1;
|
||||||
|
printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n");
|
||||||
|
hash = vmalloc(sizeof(struct list_head) * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash)
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
INIT_LIST_HEAD(&hash[i]);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_hashsize(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
int i, bucket, hashsize, vmalloced;
|
||||||
|
int old_vmalloced, old_size;
|
||||||
|
int rnd;
|
||||||
|
struct list_head *hash, *old_hash;
|
||||||
|
struct ip_conntrack_tuple_hash *h;
|
||||||
|
|
||||||
|
/* On boot, we can set this without any fancy locking. */
|
||||||
|
if (!ip_conntrack_htable_size)
|
||||||
|
return param_set_int(val, kp);
|
||||||
|
|
||||||
|
hashsize = simple_strtol(val, NULL, 0);
|
||||||
|
if (!hashsize)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
hash = alloc_hashtable(hashsize, &vmalloced);
|
||||||
|
if (!hash)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* We have to rehash for the new table anyway, so we also can
|
||||||
|
* use a new random seed */
|
||||||
|
get_random_bytes(&rnd, 4);
|
||||||
|
|
||||||
|
write_lock_bh(&ip_conntrack_lock);
|
||||||
|
for (i = 0; i < ip_conntrack_htable_size; i++) {
|
||||||
|
while (!list_empty(&ip_conntrack_hash[i])) {
|
||||||
|
h = list_entry(ip_conntrack_hash[i].next,
|
||||||
|
struct ip_conntrack_tuple_hash, list);
|
||||||
|
list_del(&h->list);
|
||||||
|
bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
|
||||||
|
list_add_tail(&h->list, &hash[bucket]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
old_size = ip_conntrack_htable_size;
|
||||||
|
old_vmalloced = ip_conntrack_vmalloc;
|
||||||
|
old_hash = ip_conntrack_hash;
|
||||||
|
|
||||||
|
ip_conntrack_htable_size = hashsize;
|
||||||
|
ip_conntrack_vmalloc = vmalloced;
|
||||||
|
ip_conntrack_hash = hash;
|
||||||
|
ip_conntrack_hash_rnd = rnd;
|
||||||
|
write_unlock_bh(&ip_conntrack_lock);
|
||||||
|
|
||||||
|
free_conntrack_hash(old_hash, old_vmalloced, old_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_param_call(hashsize, set_hashsize, param_get_uint,
|
||||||
|
&ip_conntrack_htable_size, 0600);
|
||||||
|
|
||||||
int __init ip_conntrack_init(void)
|
int __init ip_conntrack_init(void)
|
||||||
{
|
{
|
||||||
|
@ -1392,9 +1466,7 @@ int __init ip_conntrack_init(void)
|
||||||
|
|
||||||
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
|
/* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
|
||||||
* machine has 256 buckets. >= 1GB machines have 8192 buckets. */
|
* machine has 256 buckets. >= 1GB machines have 8192 buckets. */
|
||||||
if (hashsize) {
|
if (!ip_conntrack_htable_size) {
|
||||||
ip_conntrack_htable_size = hashsize;
|
|
||||||
} else {
|
|
||||||
ip_conntrack_htable_size
|
ip_conntrack_htable_size
|
||||||
= (((num_physpages << PAGE_SHIFT) / 16384)
|
= (((num_physpages << PAGE_SHIFT) / 16384)
|
||||||
/ sizeof(struct list_head));
|
/ sizeof(struct list_head));
|
||||||
|
@ -1416,20 +1488,8 @@ int __init ip_conntrack_init(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AK: the hash table is twice as big than needed because it
|
ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size,
|
||||||
uses list_head. it would be much nicer to caches to use a
|
&ip_conntrack_vmalloc);
|
||||||
single pointer list head here. */
|
|
||||||
ip_conntrack_vmalloc = 0;
|
|
||||||
ip_conntrack_hash
|
|
||||||
=(void*)__get_free_pages(GFP_KERNEL,
|
|
||||||
get_order(sizeof(struct list_head)
|
|
||||||
*ip_conntrack_htable_size));
|
|
||||||
if (!ip_conntrack_hash) {
|
|
||||||
ip_conntrack_vmalloc = 1;
|
|
||||||
printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
|
|
||||||
ip_conntrack_hash = vmalloc(sizeof(struct list_head)
|
|
||||||
* ip_conntrack_htable_size);
|
|
||||||
}
|
|
||||||
if (!ip_conntrack_hash) {
|
if (!ip_conntrack_hash) {
|
||||||
printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
|
printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
|
||||||
goto err_unreg_sockopt;
|
goto err_unreg_sockopt;
|
||||||
|
@ -1461,9 +1521,6 @@ int __init ip_conntrack_init(void)
|
||||||
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
|
ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
|
||||||
write_unlock_bh(&ip_conntrack_lock);
|
write_unlock_bh(&ip_conntrack_lock);
|
||||||
|
|
||||||
for (i = 0; i < ip_conntrack_htable_size; i++)
|
|
||||||
INIT_LIST_HEAD(&ip_conntrack_hash[i]);
|
|
||||||
|
|
||||||
/* For use by ipt_REJECT */
|
/* For use by ipt_REJECT */
|
||||||
ip_ct_attach = ip_conntrack_attach;
|
ip_ct_attach = ip_conntrack_attach;
|
||||||
|
|
||||||
|
@ -1478,7 +1535,8 @@ int __init ip_conntrack_init(void)
|
||||||
err_free_conntrack_slab:
|
err_free_conntrack_slab:
|
||||||
kmem_cache_destroy(ip_conntrack_cachep);
|
kmem_cache_destroy(ip_conntrack_cachep);
|
||||||
err_free_hash:
|
err_free_hash:
|
||||||
free_conntrack_hash();
|
free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
|
||||||
|
ip_conntrack_htable_size);
|
||||||
err_unreg_sockopt:
|
err_unreg_sockopt:
|
||||||
nf_unregister_sockopt(&so_getorigdst);
|
nf_unregister_sockopt(&so_getorigdst);
|
||||||
|
|
||||||
|
|
|
@ -90,9 +90,7 @@ fold_field(void *mib[], int offt)
|
||||||
unsigned long res = 0;
|
unsigned long res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
|
res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
|
||||||
res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
|
res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -700,10 +700,7 @@ int __init icmpv6_init(struct net_proto_family *ops)
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
int err, i, j;
|
int err, i, j;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
|
err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
|
||||||
&per_cpu(__icmpv6_socket, i));
|
&per_cpu(__icmpv6_socket, i));
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -749,9 +746,7 @@ void icmpv6_cleanup(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
sock_release(per_cpu(__icmpv6_socket, i));
|
sock_release(per_cpu(__icmpv6_socket, i));
|
||||||
}
|
}
|
||||||
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
|
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
|
||||||
|
|
|
@ -140,9 +140,7 @@ fold_field(void *mib[], int offt)
|
||||||
unsigned long res = 0;
|
unsigned long res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
|
res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
|
||||||
res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
|
res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -740,11 +740,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
|
||||||
|
|
||||||
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
|
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
|
||||||
{
|
{
|
||||||
struct netlink_sock *nlk;
|
|
||||||
int len = skb->len;
|
int len = skb->len;
|
||||||
|
|
||||||
nlk = nlk_sk(sk);
|
|
||||||
|
|
||||||
skb_queue_tail(&sk->sk_receive_queue, skb);
|
skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||||
sk->sk_data_ready(sk, len);
|
sk->sk_data_ready(sk, len);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
|
@ -727,7 +727,7 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
|
||||||
}
|
}
|
||||||
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
|
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (rose_route.ndigis > 8) /* No more than 8 digipeats */
|
if (rose_route.ndigis > AX25_MAX_DIGIS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
err = rose_add_node(&rose_route, dev);
|
err = rose_add_node(&rose_route, dev);
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
|
|
@ -69,9 +69,7 @@ fold_field(void *mib[], int nr)
|
||||||
unsigned long res = 0;
|
unsigned long res = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for_each_cpu(i) {
|
||||||
if (!cpu_possible(i))
|
|
||||||
continue;
|
|
||||||
res +=
|
res +=
|
||||||
*((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
|
*((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
|
||||||
sizeof (unsigned long) * nr));
|
sizeof (unsigned long) * nr));
|
||||||
|
|
|
@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
|
||||||
|
|
||||||
EXPORT_SYMBOL(xfrm_bundle_ok);
|
EXPORT_SYMBOL(xfrm_bundle_ok);
|
||||||
|
|
||||||
/* Well... that's _TASK_. We need to scan through transformation
|
|
||||||
* list and figure out what mss tcp should generate in order to
|
|
||||||
* final datagram fit to mtu. Mama mia... :-)
|
|
||||||
*
|
|
||||||
* Apparently, some easy way exists, but we used to choose the most
|
|
||||||
* bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta.
|
|
||||||
*
|
|
||||||
* Consider this function as something like dark humour. :-)
|
|
||||||
*/
|
|
||||||
static int xfrm_get_mss(struct dst_entry *dst, u32 mtu)
|
|
||||||
{
|
|
||||||
int res = mtu - dst->header_len;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
struct dst_entry *d = dst;
|
|
||||||
int m = res;
|
|
||||||
|
|
||||||
do {
|
|
||||||
struct xfrm_state *x = d->xfrm;
|
|
||||||
if (x) {
|
|
||||||
spin_lock_bh(&x->lock);
|
|
||||||
if (x->km.state == XFRM_STATE_VALID &&
|
|
||||||
x->type && x->type->get_max_size)
|
|
||||||
m = x->type->get_max_size(d->xfrm, m);
|
|
||||||
else
|
|
||||||
m += x->props.header_len;
|
|
||||||
spin_unlock_bh(&x->lock);
|
|
||||||
}
|
|
||||||
} while ((d = d->child) != NULL);
|
|
||||||
|
|
||||||
if (m <= mtu)
|
|
||||||
break;
|
|
||||||
res -= (m - mtu);
|
|
||||||
if (res < 88)
|
|
||||||
return mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res + dst->header_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||||
dst_ops->negative_advice = xfrm_negative_advice;
|
dst_ops->negative_advice = xfrm_negative_advice;
|
||||||
if (likely(dst_ops->link_failure == NULL))
|
if (likely(dst_ops->link_failure == NULL))
|
||||||
dst_ops->link_failure = xfrm_link_failure;
|
dst_ops->link_failure = xfrm_link_failure;
|
||||||
if (likely(dst_ops->get_mss == NULL))
|
|
||||||
dst_ops->get_mss = xfrm_get_mss;
|
|
||||||
if (likely(afinfo->garbage_collect == NULL))
|
if (likely(afinfo->garbage_collect == NULL))
|
||||||
afinfo->garbage_collect = __xfrm_garbage_collect;
|
afinfo->garbage_collect = __xfrm_garbage_collect;
|
||||||
xfrm_policy_afinfo[afinfo->family] = afinfo;
|
xfrm_policy_afinfo[afinfo->family] = afinfo;
|
||||||
|
@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||||
dst_ops->check = NULL;
|
dst_ops->check = NULL;
|
||||||
dst_ops->negative_advice = NULL;
|
dst_ops->negative_advice = NULL;
|
||||||
dst_ops->link_failure = NULL;
|
dst_ops->link_failure = NULL;
|
||||||
dst_ops->get_mss = NULL;
|
|
||||||
afinfo->garbage_collect = NULL;
|
afinfo->garbage_collect = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1026,6 +1026,12 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(xfrm_state_delete_tunnel);
|
EXPORT_SYMBOL(xfrm_state_delete_tunnel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is NOT optimal. For example, with ESP it will give an
|
||||||
|
* MTU that's usually two bytes short of being optimal. However, it will
|
||||||
|
* usually give an answer that's a multiple of 4 provided the input is
|
||||||
|
* also a multiple of 4.
|
||||||
|
*/
|
||||||
int xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
int xfrm_state_mtu(struct xfrm_state *x, int mtu)
|
||||||
{
|
{
|
||||||
int res = mtu;
|
int res = mtu;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue