diff options
-rw-r--r-- | net/core/pktgen.c | 65 |
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 | ||
751 | static int hex32_arg(const char __user *user_buffer, __u32 *num) | 763 | static 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); |