Loading net/core/pktgen.c +159 −139 Original line number Original line Diff line number Diff line Loading @@ -163,13 +163,14 @@ #include <asm/byteorder.h> #include <asm/byteorder.h> #include <linux/rcupdate.h> #include <linux/rcupdate.h> #include <linux/bitops.h> #include <linux/bitops.h> #include <asm/io.h> #include <linux/io.h> #include <linux/timex.h> #include <linux/uaccess.h> #include <asm/dma.h> #include <asm/dma.h> #include <asm/uaccess.h> #include <asm/div64.h> /* do_div */ #include <asm/div64.h> /* do_div */ #include <asm/timex.h> #define VERSION "pktgen v2.70: Packet Generator for packet performance testing.\n" #define VERSION \ "pktgen v2.70: Packet Generator for packet performance testing.\n" #define IP_NAME_SZ 32 #define IP_NAME_SZ 32 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ Loading Loading @@ -207,7 +208,7 @@ #define PKTGEN_MAGIC 0xbe9be955 #define PKTGEN_MAGIC 0xbe9be955 #define PG_PROC_DIR "pktgen" #define PG_PROC_DIR "pktgen" #define PGCTRL "pgctrl" #define PGCTRL "pgctrl" static struct proc_dir_entry *pg_proc_dir = NULL; static struct proc_dir_entry *pg_proc_dir; #define MAX_CFLOWS 65536 #define MAX_CFLOWS 65536 Loading @@ -232,9 +233,9 @@ struct pktgen_dev { */ */ struct proc_dir_entry *entry; /* proc file */ struct proc_dir_entry *entry; /* proc file */ struct pktgen_thread *pg_thread;/* the owner */ struct pktgen_thread *pg_thread;/* the owner */ struct list_head list; /* Used for chaining in the thread's run-queue */ struct list_head list; /* chaining in the thread's run-queue */ int running; /* if this changes to false, the test will stop */ int running; /* if false, the test will stop */ /* If min != max, then we will either do a linear iteration, or /* If min != max, then we will either do a linear iteration, or * we will do a random selection from within the range. * we will do a random selection from within the range. Loading @@ -252,15 +253,16 @@ struct pktgen_dev { __u64 count; /* Default No packets to send */ __u64 count; /* Default No packets to send */ __u64 sofar; /* How many pkts we've sent so far */ __u64 sofar; /* How many pkts we've sent so far */ __u64 tx_bytes; /* How many bytes we've transmitted */ __u64 tx_bytes; /* How many bytes we've transmitted */ __u64 errors; /* Errors when trying to transmit, pkts will be re-sent */ __u64 errors; /* Errors when trying to transmit, pkts will be re-sent */ /* runtime counters relating to clone_skb */ /* runtime counters relating to clone_skb */ __u64 allocated_skbs; __u64 allocated_skbs; __u32 clone_count; __u32 clone_count; int last_ok; /* Was last skb sent? int last_ok; /* Was last skb sent? * Or a failed transmit of some sort? This will keep * Or a failed transmit of some sort? * sequence numbers in order, for example. * This will keep sequence numbers in order */ */ ktime_t next_tx; ktime_t next_tx; ktime_t started_at; ktime_t started_at; Loading @@ -269,11 +271,14 @@ struct pktgen_dev { __u32 seq_num; __u32 seq_num; int clone_skb; /* Use multiple SKBs during packet gen. If this number int clone_skb; /* * is greater than 1, then that many copies of the same * Use multiple SKBs during packet gen. * packet will be sent before a new packet is allocated. * If this number is greater than 1, then * For instance, if you want to send 1024 identical packets * that many copies of the same packet will be * before creating a new packet, set clone_skb to 1024. * sent before a new packet is allocated. * If you want to send 1024 identical packets * before creating a new packet, * set clone_skb to 1024. */ */ char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */ char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */ Loading Loading @@ -305,8 +310,10 @@ struct pktgen_dev { __u16 udp_dst_max; /* exclusive, dest UDP port */ __u16 udp_dst_max; /* exclusive, dest UDP port */ /* DSCP + ECN */ /* DSCP + ECN */ __u8 tos; /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */ __u8 tos; /* six MSB of (former) IPv4 TOS __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */ are for dscp codepoint */ __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */ /* MPLS */ /* MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ Loading Loading @@ -347,13 +354,15 @@ struct pktgen_dev { */ */ __u16 pad; /* pad out the hh struct to an even 16 bytes */ __u16 pad; /* pad out the hh struct to an even 16 bytes */ struct sk_buff *skb; /* skb we are to transmit next, mainly used for when we struct sk_buff *skb; /* skb we are to transmit next, used for when we * are transmitting the same one multiple times * are transmitting the same one multiple times */ */ struct net_device *odev; /* The out-going device. Note that the device should struct net_device *odev; /* The out-going device. * have it's pg_info pointer pointing back to this * Note that the device should have it's * device. This will be set when the user specifies * pg_info pointer pointing back to this * the out-going device name (not when the inject is * device. * Set when the user specifies the out-going * device name (not when the inject is * started as it used to do.) * started as it used to do.) */ */ struct flow_state *flows; struct flow_state *flows; Loading @@ -380,13 +389,14 @@ struct pktgen_hdr { }; }; struct pktgen_thread { struct pktgen_thread { spinlock_t if_lock; spinlock_t if_lock; /* for list of devices */ struct list_head if_list; /* All device here */ struct list_head if_list; /* All device here */ struct list_head th_list; struct list_head th_list; struct task_struct *tsk; struct task_struct *tsk; char result[512]; char result[512]; /* Field for thread to receive "posted" events terminate, stop ifs etc. */ /* Field for thread to receive "posted" events terminate, stop ifs etc. */ u32 control; u32 control; int cpu; int cpu; Loading Loading @@ -545,11 +555,14 @@ static int pktgen_if_show(struct seq_file *seq, void *v) " daddr: %s min_daddr: %s max_daddr: %s\n", b1, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3); b2, b3); } else } else { seq_printf(seq, seq_printf(seq, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n", " dst_min: %s dst_max: %s\n", pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->dst_min, pkt_dev->dst_max); pkt_dev->src_max); seq_printf(seq, " src_min: %s src_max: %s\n", pkt_dev->src_min, pkt_dev->src_max); } seq_puts(seq, " src_mac: "); seq_puts(seq, " src_mac: "); Loading @@ -561,7 +574,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) seq_printf(seq, "%pM\n", pkt_dev->dst_mac); seq_printf(seq, "%pM\n", pkt_dev->dst_mac); seq_printf(seq, seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", " 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_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); Loading @@ -577,23 +591,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v) i == pkt_dev->nr_labels-1 ? "\n" : ", "); i == pkt_dev->nr_labels-1 ? "\n" : ", "); } } if (pkt_dev->vlan_id != 0xffff) { if (pkt_dev->vlan_id != 0xffff) seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n", seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n", pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi); pkt_dev->vlan_id, pkt_dev->vlan_p, } pkt_dev->vlan_cfi); if (pkt_dev->svlan_id != 0xffff) { if (pkt_dev->svlan_id != 0xffff) seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n", seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n", pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi); pkt_dev->svlan_id, pkt_dev->svlan_p, } pkt_dev->svlan_cfi); if (pkt_dev->tos) { if (pkt_dev->tos) seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos); seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos); } if (pkt_dev->traffic_class) { if (pkt_dev->traffic_class) seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class); seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class); } seq_printf(seq, " Flags: "); seq_printf(seq, " Flags: "); Loading Loading @@ -696,7 +708,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) } } static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num) static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num) { { int i = 0; int i = 0; *num = 0; *num = 0; Loading Loading @@ -846,9 +859,9 @@ static ssize_t pktgen_if_write(struct file *file, /* Read variable name */ /* Read variable name */ len = strn_len(&user_buffer[i], sizeof(name) - 1); len = strn_len(&user_buffer[i], sizeof(name) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name)); if (copy_from_user(name, &user_buffer[i], len)) if (copy_from_user(name, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading @@ -872,9 +885,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "min_pkt_size")) { if (!strcmp(name, "min_pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -889,9 +902,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "max_pkt_size")) { if (!strcmp(name, "max_pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -908,9 +921,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "pkt_size")) { if (!strcmp(name, "pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -925,9 +938,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "debug")) { if (!strcmp(name, "debug")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; debug = value; debug = value; sprintf(pg_result, "OK: debug=%u", debug); sprintf(pg_result, "OK: debug=%u", debug); Loading @@ -936,9 +949,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "frags")) { if (!strcmp(name, "frags")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->nfrags = value; pkt_dev->nfrags = value; sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags); sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags); Loading @@ -946,9 +959,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "delay")) { if (!strcmp(name, "delay")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value == 0x7FFFFFFF) if (value == 0x7FFFFFFF) pkt_dev->delay = ULLONG_MAX; pkt_dev->delay = ULLONG_MAX; Loading @@ -961,9 +974,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_src_min")) { if (!strcmp(name, "udp_src_min")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_src_min) { if (value != pkt_dev->udp_src_min) { pkt_dev->udp_src_min = value; pkt_dev->udp_src_min = value; Loading @@ -974,9 +987,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_dst_min")) { if (!strcmp(name, "udp_dst_min")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_dst_min) { if (value != pkt_dev->udp_dst_min) { pkt_dev->udp_dst_min = value; pkt_dev->udp_dst_min = value; Loading @@ -987,9 +1000,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_src_max")) { if (!strcmp(name, "udp_src_max")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_src_max) { if (value != pkt_dev->udp_src_max) { pkt_dev->udp_src_max = value; pkt_dev->udp_src_max = value; Loading @@ -1000,9 +1013,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_dst_max")) { if (!strcmp(name, "udp_dst_max")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_dst_max) { if (value != pkt_dev->udp_dst_max) { pkt_dev->udp_dst_max = value; pkt_dev->udp_dst_max = value; Loading @@ -1013,9 +1026,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "clone_skb")) { if (!strcmp(name, "clone_skb")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->clone_skb = value; pkt_dev->clone_skb = value; Loading @@ -1024,9 +1037,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "count")) { if (!strcmp(name, "count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->count = value; pkt_dev->count = value; sprintf(pg_result, "OK: count=%llu", sprintf(pg_result, "OK: count=%llu", Loading @@ -1035,9 +1048,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_mac_count")) { if (!strcmp(name, "src_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (pkt_dev->src_mac_count != value) { if (pkt_dev->src_mac_count != value) { pkt_dev->src_mac_count = value; pkt_dev->src_mac_count = value; Loading @@ -1049,9 +1062,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_mac_count")) { if (!strcmp(name, "dst_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (pkt_dev->dst_mac_count != value) { if (pkt_dev->dst_mac_count != value) { pkt_dev->dst_mac_count = value; pkt_dev->dst_mac_count = value; Loading @@ -1065,9 +1078,9 @@ static ssize_t pktgen_if_write(struct file *file, char f[32]; char f[32]; memset(f, 0, 32); memset(f, 0, 32); len = strn_len(&user_buffer[i], sizeof(f) - 1); len = strn_len(&user_buffer[i], sizeof(f) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(f, &user_buffer[i], len)) if (copy_from_user(f, &user_buffer[i], len)) return -EFAULT; return -EFAULT; i += len; i += len; Loading Loading @@ -1166,9 +1179,8 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading @@ -1188,9 +1200,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_max")) { if (!strcmp(name, "dst_max")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1301,9 +1313,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_min")) { if (!strcmp(name, "src_min")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; buf[len] = 0; buf[len] = 0; Loading @@ -1322,9 +1334,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_max")) { if (!strcmp(name, "src_max")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; buf[len] = 0; buf[len] = 0; Loading @@ -1348,9 +1360,9 @@ static ssize_t pktgen_if_write(struct file *file, memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN); memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(valstr, 0, sizeof(valstr)); memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1390,9 +1402,9 @@ static ssize_t pktgen_if_write(struct file *file, memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(valstr, 0, sizeof(valstr)); memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1433,9 +1445,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "flows")) { if (!strcmp(name, "flows")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value > MAX_CFLOWS) if (value > MAX_CFLOWS) value = MAX_CFLOWS; value = MAX_CFLOWS; Loading @@ -1447,9 +1459,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "flowlen")) { if (!strcmp(name, "flowlen")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->lflow = value; pkt_dev->lflow = value; sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow); sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow); Loading @@ -1458,9 +1470,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "queue_map_min")) { if (!strcmp(name, "queue_map_min")) { len = num_arg(&user_buffer[i], 5, &value); len = num_arg(&user_buffer[i], 5, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->queue_map_min = value; pkt_dev->queue_map_min = value; sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); Loading @@ -1469,9 +1481,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "queue_map_max")) { if (!strcmp(name, "queue_map_max")) { len = num_arg(&user_buffer[i], 5, &value); len = num_arg(&user_buffer[i], 5, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->queue_map_max = value; pkt_dev->queue_map_max = value; sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); Loading Loading @@ -1503,9 +1515,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_id")) { if (!strcmp(name, "vlan_id")) { len = num_arg(&user_buffer[i], 4, &value); len = num_arg(&user_buffer[i], 4, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value <= 4095) { if (value <= 4095) { pkt_dev->vlan_id = value; /* turn on VLAN */ pkt_dev->vlan_id = value; /* turn on VLAN */ Loading @@ -1530,9 +1542,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_p")) { if (!strcmp(name, "vlan_p")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) { if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) { pkt_dev->vlan_p = value; pkt_dev->vlan_p = value; Loading @@ -1545,9 +1557,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_cfi")) { if (!strcmp(name, "vlan_cfi")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) { if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) { pkt_dev->vlan_cfi = value; pkt_dev->vlan_cfi = value; Loading @@ -1560,9 +1572,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_id")) { if (!strcmp(name, "svlan_id")) { len = num_arg(&user_buffer[i], 4, &value); len = num_arg(&user_buffer[i], 4, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) { if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) { pkt_dev->svlan_id = value; /* turn on SVLAN */ pkt_dev->svlan_id = value; /* turn on SVLAN */ Loading @@ -1587,9 +1599,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_p")) { if (!strcmp(name, "svlan_p")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) { if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) { pkt_dev->svlan_p = value; pkt_dev->svlan_p = value; Loading @@ -1602,9 +1614,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_cfi")) { if (!strcmp(name, "svlan_cfi")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) { if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) { pkt_dev->svlan_cfi = value; pkt_dev->svlan_cfi = value; Loading @@ -1618,9 +1630,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "tos")) { if (!strcmp(name, "tos")) { __u32 tmp_value = 0; __u32 tmp_value = 0; len = hex32_arg(&user_buffer[i], 2, &tmp_value); len = hex32_arg(&user_buffer[i], 2, &tmp_value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (len == 2) { if (len == 2) { pkt_dev->tos = tmp_value; pkt_dev->tos = tmp_value; Loading @@ -1634,9 +1646,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "traffic_class")) { if (!strcmp(name, "traffic_class")) { __u32 tmp_value = 0; __u32 tmp_value = 0; len = hex32_arg(&user_buffer[i], 2, &tmp_value); len = hex32_arg(&user_buffer[i], 2, &tmp_value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (len == 2) { if (len == 2) { pkt_dev->traffic_class = tmp_value; pkt_dev->traffic_class = tmp_value; Loading Loading @@ -1906,7 +1918,8 @@ static int pktgen_device_event(struct notifier_block *unused, return NOTIFY_DONE; return NOTIFY_DONE; } } static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname) static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname) { { char b[IFNAMSIZ+5]; char b[IFNAMSIZ+5]; int i = 0; int i = 0; Loading Loading @@ -2028,7 +2041,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) */ */ rcu_read_lock(); rcu_read_lock(); if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { idev = __in6_dev_get(pkt_dev->odev); if (idev) { struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp; read_lock_bh(&idev->lock); read_lock_bh(&idev->lock); Loading Loading @@ -2320,18 +2334,18 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) if (!(pkt_dev->flags & F_IPV6)) { if (!(pkt_dev->flags & F_IPV6)) { if ((imn = ntohl(pkt_dev->saddr_min)) < (imx = imn = ntohl(pkt_dev->saddr_min); ntohl(pkt_dev-> imx = ntohl(pkt_dev->saddr_max); saddr_max))) { if (imn < imx) { __u32 t; __u32 t; if (pkt_dev->flags & F_IPSRC_RND) if (pkt_dev->flags & F_IPSRC_RND) t = random32() % (imx - imn) + imn; t = random32() % (imx - imn) + imn; else { else { t = ntohl(pkt_dev->cur_saddr); t = ntohl(pkt_dev->cur_saddr); t++; t++; if (t > imx) { if (t > imx) t = imn; t = imn; } } } pkt_dev->cur_saddr = htonl(t); pkt_dev->cur_saddr = htonl(t); } } Loading Loading @@ -2507,9 +2521,9 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) { { unsigned i; unsigned i; for (i = 0; i < pkt_dev->nr_labels; i++) { for (i = 0; i < pkt_dev->nr_labels; i++) *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; } mpls--; mpls--; *mpls |= MPLS_STACK_BOTTOM; *mpls |= MPLS_STACK_BOTTOM; } } Loading Loading @@ -2676,8 +2690,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, } } } } /* Stamp the time, and sequence number, convert them to network byte order */ /* Stamp the time, and sequence number, * convert them to network byte order */ if (pgh) { if (pgh) { struct timeval timestamp; struct timeval timestamp; Loading Loading @@ -3025,8 +3040,10 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, } } } } /* Stamp the time, and sequence number, convert them to network byte order */ /* Stamp the time, and sequence number, /* should we update cloned packets too ? */ * convert them to network byte order * should we update cloned packets too ? */ if (pgh) { if (pgh) { struct timeval timestamp; struct timeval timestamp; Loading Loading @@ -3174,7 +3191,8 @@ static void pktgen_run_all_threads(void) mutex_unlock(&pktgen_thread_lock); mutex_unlock(&pktgen_thread_lock); schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ /* Propagate thread->control */ schedule_timeout_interruptible(msecs_to_jiffies(125)); pktgen_wait_all_threads_run(); pktgen_wait_all_threads_run(); } } Loading @@ -3192,7 +3210,8 @@ static void pktgen_reset_all_threads(void) mutex_unlock(&pktgen_thread_lock); mutex_unlock(&pktgen_thread_lock); schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ /* Propagate thread->control */ schedule_timeout_interruptible(msecs_to_jiffies(125)); pktgen_wait_all_threads_run(); pktgen_wait_all_threads_run(); } } Loading Loading @@ -3485,7 +3504,8 @@ static int pktgen_thread_worker(void *arg) init_waitqueue_head(&t->queue); init_waitqueue_head(&t->queue); complete(&t->start_done); complete(&t->start_done); pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE); Loading Loading
net/core/pktgen.c +159 −139 Original line number Original line Diff line number Diff line Loading @@ -163,13 +163,14 @@ #include <asm/byteorder.h> #include <asm/byteorder.h> #include <linux/rcupdate.h> #include <linux/rcupdate.h> #include <linux/bitops.h> #include <linux/bitops.h> #include <asm/io.h> #include <linux/io.h> #include <linux/timex.h> #include <linux/uaccess.h> #include <asm/dma.h> #include <asm/dma.h> #include <asm/uaccess.h> #include <asm/div64.h> /* do_div */ #include <asm/div64.h> /* do_div */ #include <asm/timex.h> #define VERSION "pktgen v2.70: Packet Generator for packet performance testing.\n" #define VERSION \ "pktgen v2.70: Packet Generator for packet performance testing.\n" #define IP_NAME_SZ 32 #define IP_NAME_SZ 32 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ Loading Loading @@ -207,7 +208,7 @@ #define PKTGEN_MAGIC 0xbe9be955 #define PKTGEN_MAGIC 0xbe9be955 #define PG_PROC_DIR "pktgen" #define PG_PROC_DIR "pktgen" #define PGCTRL "pgctrl" #define PGCTRL "pgctrl" static struct proc_dir_entry *pg_proc_dir = NULL; static struct proc_dir_entry *pg_proc_dir; #define MAX_CFLOWS 65536 #define MAX_CFLOWS 65536 Loading @@ -232,9 +233,9 @@ struct pktgen_dev { */ */ struct proc_dir_entry *entry; /* proc file */ struct proc_dir_entry *entry; /* proc file */ struct pktgen_thread *pg_thread;/* the owner */ struct pktgen_thread *pg_thread;/* the owner */ struct list_head list; /* Used for chaining in the thread's run-queue */ struct list_head list; /* chaining in the thread's run-queue */ int running; /* if this changes to false, the test will stop */ int running; /* if false, the test will stop */ /* If min != max, then we will either do a linear iteration, or /* If min != max, then we will either do a linear iteration, or * we will do a random selection from within the range. * we will do a random selection from within the range. Loading @@ -252,15 +253,16 @@ struct pktgen_dev { __u64 count; /* Default No packets to send */ __u64 count; /* Default No packets to send */ __u64 sofar; /* How many pkts we've sent so far */ __u64 sofar; /* How many pkts we've sent so far */ __u64 tx_bytes; /* How many bytes we've transmitted */ __u64 tx_bytes; /* How many bytes we've transmitted */ __u64 errors; /* Errors when trying to transmit, pkts will be re-sent */ __u64 errors; /* Errors when trying to transmit, pkts will be re-sent */ /* runtime counters relating to clone_skb */ /* runtime counters relating to clone_skb */ __u64 allocated_skbs; __u64 allocated_skbs; __u32 clone_count; __u32 clone_count; int last_ok; /* Was last skb sent? int last_ok; /* Was last skb sent? * Or a failed transmit of some sort? This will keep * Or a failed transmit of some sort? * sequence numbers in order, for example. * This will keep sequence numbers in order */ */ ktime_t next_tx; ktime_t next_tx; ktime_t started_at; ktime_t started_at; Loading @@ -269,11 +271,14 @@ struct pktgen_dev { __u32 seq_num; __u32 seq_num; int clone_skb; /* Use multiple SKBs during packet gen. If this number int clone_skb; /* * is greater than 1, then that many copies of the same * Use multiple SKBs during packet gen. * packet will be sent before a new packet is allocated. * If this number is greater than 1, then * For instance, if you want to send 1024 identical packets * that many copies of the same packet will be * before creating a new packet, set clone_skb to 1024. * sent before a new packet is allocated. * If you want to send 1024 identical packets * before creating a new packet, * set clone_skb to 1024. */ */ char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */ char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */ Loading Loading @@ -305,8 +310,10 @@ struct pktgen_dev { __u16 udp_dst_max; /* exclusive, dest UDP port */ __u16 udp_dst_max; /* exclusive, dest UDP port */ /* DSCP + ECN */ /* DSCP + ECN */ __u8 tos; /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */ __u8 tos; /* six MSB of (former) IPv4 TOS __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */ are for dscp codepoint */ __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */ /* MPLS */ /* MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ Loading Loading @@ -347,13 +354,15 @@ struct pktgen_dev { */ */ __u16 pad; /* pad out the hh struct to an even 16 bytes */ __u16 pad; /* pad out the hh struct to an even 16 bytes */ struct sk_buff *skb; /* skb we are to transmit next, mainly used for when we struct sk_buff *skb; /* skb we are to transmit next, used for when we * are transmitting the same one multiple times * are transmitting the same one multiple times */ */ struct net_device *odev; /* The out-going device. Note that the device should struct net_device *odev; /* The out-going device. * have it's pg_info pointer pointing back to this * Note that the device should have it's * device. This will be set when the user specifies * pg_info pointer pointing back to this * the out-going device name (not when the inject is * device. * Set when the user specifies the out-going * device name (not when the inject is * started as it used to do.) * started as it used to do.) */ */ struct flow_state *flows; struct flow_state *flows; Loading @@ -380,13 +389,14 @@ struct pktgen_hdr { }; }; struct pktgen_thread { struct pktgen_thread { spinlock_t if_lock; spinlock_t if_lock; /* for list of devices */ struct list_head if_list; /* All device here */ struct list_head if_list; /* All device here */ struct list_head th_list; struct list_head th_list; struct task_struct *tsk; struct task_struct *tsk; char result[512]; char result[512]; /* Field for thread to receive "posted" events terminate, stop ifs etc. */ /* Field for thread to receive "posted" events terminate, stop ifs etc. */ u32 control; u32 control; int cpu; int cpu; Loading Loading @@ -545,11 +555,14 @@ static int pktgen_if_show(struct seq_file *seq, void *v) " daddr: %s min_daddr: %s max_daddr: %s\n", b1, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3); b2, b3); } else } else { seq_printf(seq, seq_printf(seq, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n", " dst_min: %s dst_max: %s\n", pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->dst_min, pkt_dev->dst_max); pkt_dev->src_max); seq_printf(seq, " src_min: %s src_max: %s\n", pkt_dev->src_min, pkt_dev->src_max); } seq_puts(seq, " src_mac: "); seq_puts(seq, " src_mac: "); Loading @@ -561,7 +574,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) seq_printf(seq, "%pM\n", pkt_dev->dst_mac); seq_printf(seq, "%pM\n", pkt_dev->dst_mac); seq_printf(seq, seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", " 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_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); Loading @@ -577,23 +591,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v) i == pkt_dev->nr_labels-1 ? "\n" : ", "); i == pkt_dev->nr_labels-1 ? "\n" : ", "); } } if (pkt_dev->vlan_id != 0xffff) { if (pkt_dev->vlan_id != 0xffff) seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n", seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n", pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi); pkt_dev->vlan_id, pkt_dev->vlan_p, } pkt_dev->vlan_cfi); if (pkt_dev->svlan_id != 0xffff) { if (pkt_dev->svlan_id != 0xffff) seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n", seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n", pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi); pkt_dev->svlan_id, pkt_dev->svlan_p, } pkt_dev->svlan_cfi); if (pkt_dev->tos) { if (pkt_dev->tos) seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos); seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos); } if (pkt_dev->traffic_class) { if (pkt_dev->traffic_class) seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class); seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class); } seq_printf(seq, " Flags: "); seq_printf(seq, " Flags: "); Loading Loading @@ -696,7 +708,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) } } static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num) static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num) { { int i = 0; int i = 0; *num = 0; *num = 0; Loading Loading @@ -846,9 +859,9 @@ static ssize_t pktgen_if_write(struct file *file, /* Read variable name */ /* Read variable name */ len = strn_len(&user_buffer[i], sizeof(name) - 1); len = strn_len(&user_buffer[i], sizeof(name) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name)); if (copy_from_user(name, &user_buffer[i], len)) if (copy_from_user(name, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading @@ -872,9 +885,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "min_pkt_size")) { if (!strcmp(name, "min_pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -889,9 +902,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "max_pkt_size")) { if (!strcmp(name, "max_pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -908,9 +921,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "pkt_size")) { if (!strcmp(name, "pkt_size")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value < 14 + 20 + 8) if (value < 14 + 20 + 8) value = 14 + 20 + 8; value = 14 + 20 + 8; Loading @@ -925,9 +938,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "debug")) { if (!strcmp(name, "debug")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; debug = value; debug = value; sprintf(pg_result, "OK: debug=%u", debug); sprintf(pg_result, "OK: debug=%u", debug); Loading @@ -936,9 +949,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "frags")) { if (!strcmp(name, "frags")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->nfrags = value; pkt_dev->nfrags = value; sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags); sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags); Loading @@ -946,9 +959,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "delay")) { if (!strcmp(name, "delay")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value == 0x7FFFFFFF) if (value == 0x7FFFFFFF) pkt_dev->delay = ULLONG_MAX; pkt_dev->delay = ULLONG_MAX; Loading @@ -961,9 +974,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_src_min")) { if (!strcmp(name, "udp_src_min")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_src_min) { if (value != pkt_dev->udp_src_min) { pkt_dev->udp_src_min = value; pkt_dev->udp_src_min = value; Loading @@ -974,9 +987,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_dst_min")) { if (!strcmp(name, "udp_dst_min")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_dst_min) { if (value != pkt_dev->udp_dst_min) { pkt_dev->udp_dst_min = value; pkt_dev->udp_dst_min = value; Loading @@ -987,9 +1000,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_src_max")) { if (!strcmp(name, "udp_src_max")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_src_max) { if (value != pkt_dev->udp_src_max) { pkt_dev->udp_src_max = value; pkt_dev->udp_src_max = value; Loading @@ -1000,9 +1013,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "udp_dst_max")) { if (!strcmp(name, "udp_dst_max")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value != pkt_dev->udp_dst_max) { if (value != pkt_dev->udp_dst_max) { pkt_dev->udp_dst_max = value; pkt_dev->udp_dst_max = value; Loading @@ -1013,9 +1026,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "clone_skb")) { if (!strcmp(name, "clone_skb")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->clone_skb = value; pkt_dev->clone_skb = value; Loading @@ -1024,9 +1037,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "count")) { if (!strcmp(name, "count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->count = value; pkt_dev->count = value; sprintf(pg_result, "OK: count=%llu", sprintf(pg_result, "OK: count=%llu", Loading @@ -1035,9 +1048,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_mac_count")) { if (!strcmp(name, "src_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (pkt_dev->src_mac_count != value) { if (pkt_dev->src_mac_count != value) { pkt_dev->src_mac_count = value; pkt_dev->src_mac_count = value; Loading @@ -1049,9 +1062,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_mac_count")) { if (!strcmp(name, "dst_mac_count")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (pkt_dev->dst_mac_count != value) { if (pkt_dev->dst_mac_count != value) { pkt_dev->dst_mac_count = value; pkt_dev->dst_mac_count = value; Loading @@ -1065,9 +1078,9 @@ static ssize_t pktgen_if_write(struct file *file, char f[32]; char f[32]; memset(f, 0, 32); memset(f, 0, 32); len = strn_len(&user_buffer[i], sizeof(f) - 1); len = strn_len(&user_buffer[i], sizeof(f) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(f, &user_buffer[i], len)) if (copy_from_user(f, &user_buffer[i], len)) return -EFAULT; return -EFAULT; i += len; i += len; Loading Loading @@ -1166,9 +1179,8 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading @@ -1188,9 +1200,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "dst_max")) { if (!strcmp(name, "dst_max")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1301,9 +1313,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_min")) { if (!strcmp(name, "src_min")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; buf[len] = 0; buf[len] = 0; Loading @@ -1322,9 +1334,9 @@ static ssize_t pktgen_if_write(struct file *file, } } if (!strcmp(name, "src_max")) { if (!strcmp(name, "src_max")) { len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); if (len < 0) { if (len < 0) return len; return len; } if (copy_from_user(buf, &user_buffer[i], len)) if (copy_from_user(buf, &user_buffer[i], len)) return -EFAULT; return -EFAULT; buf[len] = 0; buf[len] = 0; Loading @@ -1348,9 +1360,9 @@ static ssize_t pktgen_if_write(struct file *file, memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN); memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(valstr, 0, sizeof(valstr)); memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1390,9 +1402,9 @@ static ssize_t pktgen_if_write(struct file *file, memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) { if (len < 0) return len; return len; } memset(valstr, 0, sizeof(valstr)); memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; return -EFAULT; Loading Loading @@ -1433,9 +1445,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "flows")) { if (!strcmp(name, "flows")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value > MAX_CFLOWS) if (value > MAX_CFLOWS) value = MAX_CFLOWS; value = MAX_CFLOWS; Loading @@ -1447,9 +1459,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "flowlen")) { if (!strcmp(name, "flowlen")) { len = num_arg(&user_buffer[i], 10, &value); len = num_arg(&user_buffer[i], 10, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->lflow = value; pkt_dev->lflow = value; sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow); sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow); Loading @@ -1458,9 +1470,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "queue_map_min")) { if (!strcmp(name, "queue_map_min")) { len = num_arg(&user_buffer[i], 5, &value); len = num_arg(&user_buffer[i], 5, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->queue_map_min = value; pkt_dev->queue_map_min = value; sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); Loading @@ -1469,9 +1481,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "queue_map_max")) { if (!strcmp(name, "queue_map_max")) { len = num_arg(&user_buffer[i], 5, &value); len = num_arg(&user_buffer[i], 5, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; pkt_dev->queue_map_max = value; pkt_dev->queue_map_max = value; sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); Loading Loading @@ -1503,9 +1515,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_id")) { if (!strcmp(name, "vlan_id")) { len = num_arg(&user_buffer[i], 4, &value); len = num_arg(&user_buffer[i], 4, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (value <= 4095) { if (value <= 4095) { pkt_dev->vlan_id = value; /* turn on VLAN */ pkt_dev->vlan_id = value; /* turn on VLAN */ Loading @@ -1530,9 +1542,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_p")) { if (!strcmp(name, "vlan_p")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) { if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) { pkt_dev->vlan_p = value; pkt_dev->vlan_p = value; Loading @@ -1545,9 +1557,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "vlan_cfi")) { if (!strcmp(name, "vlan_cfi")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) { if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) { pkt_dev->vlan_cfi = value; pkt_dev->vlan_cfi = value; Loading @@ -1560,9 +1572,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_id")) { if (!strcmp(name, "svlan_id")) { len = num_arg(&user_buffer[i], 4, &value); len = num_arg(&user_buffer[i], 4, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) { if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) { pkt_dev->svlan_id = value; /* turn on SVLAN */ pkt_dev->svlan_id = value; /* turn on SVLAN */ Loading @@ -1587,9 +1599,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_p")) { if (!strcmp(name, "svlan_p")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) { if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) { pkt_dev->svlan_p = value; pkt_dev->svlan_p = value; Loading @@ -1602,9 +1614,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "svlan_cfi")) { if (!strcmp(name, "svlan_cfi")) { len = num_arg(&user_buffer[i], 1, &value); len = num_arg(&user_buffer[i], 1, &value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) { if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) { pkt_dev->svlan_cfi = value; pkt_dev->svlan_cfi = value; Loading @@ -1618,9 +1630,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "tos")) { if (!strcmp(name, "tos")) { __u32 tmp_value = 0; __u32 tmp_value = 0; len = hex32_arg(&user_buffer[i], 2, &tmp_value); len = hex32_arg(&user_buffer[i], 2, &tmp_value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (len == 2) { if (len == 2) { pkt_dev->tos = tmp_value; pkt_dev->tos = tmp_value; Loading @@ -1634,9 +1646,9 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "traffic_class")) { if (!strcmp(name, "traffic_class")) { __u32 tmp_value = 0; __u32 tmp_value = 0; len = hex32_arg(&user_buffer[i], 2, &tmp_value); len = hex32_arg(&user_buffer[i], 2, &tmp_value); if (len < 0) { if (len < 0) return len; return len; } i += len; i += len; if (len == 2) { if (len == 2) { pkt_dev->traffic_class = tmp_value; pkt_dev->traffic_class = tmp_value; Loading Loading @@ -1906,7 +1918,8 @@ static int pktgen_device_event(struct notifier_block *unused, return NOTIFY_DONE; return NOTIFY_DONE; } } static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname) static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname) { { char b[IFNAMSIZ+5]; char b[IFNAMSIZ+5]; int i = 0; int i = 0; Loading Loading @@ -2028,7 +2041,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) */ */ rcu_read_lock(); rcu_read_lock(); if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { idev = __in6_dev_get(pkt_dev->odev); if (idev) { struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp; read_lock_bh(&idev->lock); read_lock_bh(&idev->lock); Loading Loading @@ -2320,18 +2334,18 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) if (!(pkt_dev->flags & F_IPV6)) { if (!(pkt_dev->flags & F_IPV6)) { if ((imn = ntohl(pkt_dev->saddr_min)) < (imx = imn = ntohl(pkt_dev->saddr_min); ntohl(pkt_dev-> imx = ntohl(pkt_dev->saddr_max); saddr_max))) { if (imn < imx) { __u32 t; __u32 t; if (pkt_dev->flags & F_IPSRC_RND) if (pkt_dev->flags & F_IPSRC_RND) t = random32() % (imx - imn) + imn; t = random32() % (imx - imn) + imn; else { else { t = ntohl(pkt_dev->cur_saddr); t = ntohl(pkt_dev->cur_saddr); t++; t++; if (t > imx) { if (t > imx) t = imn; t = imn; } } } pkt_dev->cur_saddr = htonl(t); pkt_dev->cur_saddr = htonl(t); } } Loading Loading @@ -2507,9 +2521,9 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) { { unsigned i; unsigned i; for (i = 0; i < pkt_dev->nr_labels; i++) { for (i = 0; i < pkt_dev->nr_labels; i++) *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; } mpls--; mpls--; *mpls |= MPLS_STACK_BOTTOM; *mpls |= MPLS_STACK_BOTTOM; } } Loading Loading @@ -2676,8 +2690,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, } } } } /* Stamp the time, and sequence number, convert them to network byte order */ /* Stamp the time, and sequence number, * convert them to network byte order */ if (pgh) { if (pgh) { struct timeval timestamp; struct timeval timestamp; Loading Loading @@ -3025,8 +3040,10 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, } } } } /* Stamp the time, and sequence number, convert them to network byte order */ /* Stamp the time, and sequence number, /* should we update cloned packets too ? */ * convert them to network byte order * should we update cloned packets too ? */ if (pgh) { if (pgh) { struct timeval timestamp; struct timeval timestamp; Loading Loading @@ -3174,7 +3191,8 @@ static void pktgen_run_all_threads(void) mutex_unlock(&pktgen_thread_lock); mutex_unlock(&pktgen_thread_lock); schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ /* Propagate thread->control */ schedule_timeout_interruptible(msecs_to_jiffies(125)); pktgen_wait_all_threads_run(); pktgen_wait_all_threads_run(); } } Loading @@ -3192,7 +3210,8 @@ static void pktgen_reset_all_threads(void) mutex_unlock(&pktgen_thread_lock); mutex_unlock(&pktgen_thread_lock); schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ /* Propagate thread->control */ schedule_timeout_interruptible(msecs_to_jiffies(125)); pktgen_wait_all_threads_run(); pktgen_wait_all_threads_run(); } } Loading Loading @@ -3485,7 +3504,8 @@ static int pktgen_thread_worker(void *arg) init_waitqueue_head(&t->queue); init_waitqueue_head(&t->queue); complete(&t->start_done); complete(&t->start_done); pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE); Loading