aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/pktgen.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 033802769e4f..dd023fd28304 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -160,7 +160,7 @@
160#include <asm/div64.h> /* do_div */ 160#include <asm/div64.h> /* do_div */
161#include <asm/timex.h> 161#include <asm/timex.h>
162 162
163#define VERSION "pktgen v2.67: Packet Generator for packet performance testing.\n" 163#define VERSION "pktgen v2.68: Packet Generator for packet performance testing.\n"
164 164
165/* #define PG_DEBUG(a) a */ 165/* #define PG_DEBUG(a) a */
166#define PG_DEBUG(a) 166#define PG_DEBUG(a)
@@ -292,6 +292,10 @@ struct pktgen_dev {
292 __u16 udp_dst_min; /* inclusive, dest UDP port */ 292 __u16 udp_dst_min; /* inclusive, dest UDP port */
293 __u16 udp_dst_max; /* exclusive, dest UDP port */ 293 __u16 udp_dst_max; /* exclusive, dest UDP port */
294 294
295 /* DSCP + ECN */
296 __u8 tos; /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */
297 __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */
298
295 /* MPLS */ 299 /* MPLS */
296 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ 300 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */
297 __be32 labels[MAX_MPLS_LABELS]; 301 __be32 labels[MAX_MPLS_LABELS];
@@ -671,6 +675,14 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
671 pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi); 675 pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
672 } 676 }
673 677
678 if (pkt_dev->tos) {
679 seq_printf(seq, " tos: 0x%02x\n", pkt_dev->tos);
680 }
681
682 if (pkt_dev->traffic_class) {
683 seq_printf(seq, " traffic_class: 0x%02x\n", pkt_dev->traffic_class);
684 }
685
674 seq_printf(seq, " Flags: "); 686 seq_printf(seq, " Flags: ");
675 687
676 if (pkt_dev->flags & F_IPV6) 688 if (pkt_dev->flags & F_IPV6)
@@ -748,12 +760,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
748} 760}
749 761
750 762
751static int hex32_arg(const char __user *user_buffer, __u32 *num) 763static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
752{ 764{
753 int i = 0; 765 int i = 0;
754 *num = 0; 766 *num = 0;
755 767
756 for(; i < 8; i++) { 768 for(; i < maxlen; i++) {
757 char c; 769 char c;
758 *num <<= 4; 770 *num <<= 4;
759 if (get_user(c, &user_buffer[i])) 771 if (get_user(c, &user_buffer[i]))
@@ -848,7 +860,7 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
848 pkt_dev->nr_labels = 0; 860 pkt_dev->nr_labels = 0;
849 do { 861 do {
850 __u32 tmp; 862 __u32 tmp;
851 len = hex32_arg(&buffer[i], &tmp); 863 len = hex32_arg(&buffer[i], 8, &tmp);
852 if (len <= 0) 864 if (len <= 0)
853 return len; 865 return len;
854 pkt_dev->labels[n] = htonl(tmp); 866 pkt_dev->labels[n] = htonl(tmp);
@@ -1185,11 +1197,15 @@ static ssize_t pktgen_if_write(struct file *file,
1185 else if (strcmp(f, "!SVID_RND") == 0) 1197 else if (strcmp(f, "!SVID_RND") == 0)
1186 pkt_dev->flags &= ~F_SVID_RND; 1198 pkt_dev->flags &= ~F_SVID_RND;
1187 1199
1200 else if (strcmp(f, "!IPV6") == 0)
1201 pkt_dev->flags &= ~F_IPV6;
1202
1188 else { 1203 else {
1189 sprintf(pg_result, 1204 sprintf(pg_result,
1190 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", 1205 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
1191 f, 1206 f,
1192 "IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n"); 1207 "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
1208 "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n");
1193 return count; 1209 return count;
1194 } 1210 }
1195 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags); 1211 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -1615,6 +1631,38 @@ static ssize_t pktgen_if_write(struct file *file,
1615 return count; 1631 return count;
1616 } 1632 }
1617 1633
1634 if (!strcmp(name, "tos")) {
1635 __u32 tmp_value = 0;
1636 len = hex32_arg(&user_buffer[i], 2, &tmp_value);
1637 if (len < 0) {
1638 return len;
1639 }
1640 i += len;
1641 if (len == 2) {
1642 pkt_dev->tos = tmp_value;
1643 sprintf(pg_result, "OK: tos=0x%02x", pkt_dev->tos);
1644 } else {
1645 sprintf(pg_result, "ERROR: tos must be 00-ff");
1646 }
1647 return count;
1648 }
1649
1650 if (!strcmp(name, "traffic_class")) {
1651 __u32 tmp_value = 0;
1652 len = hex32_arg(&user_buffer[i], 2, &tmp_value);
1653 if (len < 0) {
1654 return len;
1655 }
1656 i += len;
1657 if (len == 2) {
1658 pkt_dev->traffic_class = tmp_value;
1659 sprintf(pg_result, "OK: traffic_class=0x%02x", pkt_dev->traffic_class);
1660 } else {
1661 sprintf(pg_result, "ERROR: traffic_class must be 00-ff");
1662 }
1663 return count;
1664 }
1665
1618 sprintf(pkt_dev->result, "No such parameter \"%s\"", name); 1666 sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
1619 return -EINVAL; 1667 return -EINVAL;
1620} 1668}
@@ -2339,7 +2387,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2339 iph->ihl = 5; 2387 iph->ihl = 5;
2340 iph->version = 4; 2388 iph->version = 4;
2341 iph->ttl = 32; 2389 iph->ttl = 32;
2342 iph->tos = 0; 2390 iph->tos = pkt_dev->tos;
2343 iph->protocol = IPPROTO_UDP; /* UDP */ 2391 iph->protocol = IPPROTO_UDP; /* UDP */
2344 iph->saddr = pkt_dev->cur_saddr; 2392 iph->saddr = pkt_dev->cur_saddr;
2345 iph->daddr = pkt_dev->cur_daddr; 2393 iph->daddr = pkt_dev->cur_daddr;
@@ -2680,6 +2728,11 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2680 2728
2681 *(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */ 2729 *(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */
2682 2730
2731 if (pkt_dev->traffic_class) {
2732 /* Version + traffic class + flow (0) */
2733 *(u32 *)iph |= htonl(0x60000000 | (pkt_dev->traffic_class << 20));
2734 }
2735
2683 iph->hop_limit = 32; 2736 iph->hop_limit = 32;
2684 2737
2685 iph->payload_len = htons(sizeof(struct udphdr) + datalen); 2738 iph->payload_len = htons(sizeof(struct udphdr) + datalen);