diff options
author | Robert Olsson <robert.olsson@its.uu.se> | 2007-08-28 18:45:55 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:48:35 -0400 |
commit | 45b270f880d32252ded95865390e69deb714e080 (patch) | |
tree | 23cc71f7ea17680fb6fa4952930f75ae04db6f2a /net/core/pktgen.c | |
parent | 32b21e034be9954eaae0278df20e0251eb958ded (diff) |
[PKTGEN]: Multiqueue support.
Below some pktgen support to send into different TX queues.
This can of course be feed into input queues on other machines
Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r-- | net/core/pktgen.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 803d0c8826af..1d6f1c6270b6 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -189,6 +189,7 @@ | |||
189 | #define F_SVID_RND (1<<10) /* Random SVLAN ID */ | 189 | #define F_SVID_RND (1<<10) /* Random SVLAN ID */ |
190 | #define F_FLOW_SEQ (1<<11) /* Sequential flows */ | 190 | #define F_FLOW_SEQ (1<<11) /* Sequential flows */ |
191 | #define F_IPSEC_ON (1<<12) /* ipsec on for flows */ | 191 | #define F_IPSEC_ON (1<<12) /* ipsec on for flows */ |
192 | #define F_QUEUE_MAP_RND (1<<13) /* queue map Random */ | ||
192 | 193 | ||
193 | /* Thread control flag bits */ | 194 | /* Thread control flag bits */ |
194 | #define T_TERMINATE (1<<0) | 195 | #define T_TERMINATE (1<<0) |
@@ -331,6 +332,7 @@ struct pktgen_dev { | |||
331 | __be32 cur_daddr; | 332 | __be32 cur_daddr; |
332 | __u16 cur_udp_dst; | 333 | __u16 cur_udp_dst; |
333 | __u16 cur_udp_src; | 334 | __u16 cur_udp_src; |
335 | __u16 cur_queue_map; | ||
334 | __u32 cur_pkt_size; | 336 | __u32 cur_pkt_size; |
335 | 337 | ||
336 | __u8 hh[14]; | 338 | __u8 hh[14]; |
@@ -358,6 +360,10 @@ struct pktgen_dev { | |||
358 | unsigned lflow; /* Flow length (config) */ | 360 | unsigned lflow; /* Flow length (config) */ |
359 | unsigned nflows; /* accumulated flows (stats) */ | 361 | unsigned nflows; /* accumulated flows (stats) */ |
360 | unsigned curfl; /* current sequenced flow (state)*/ | 362 | unsigned curfl; /* current sequenced flow (state)*/ |
363 | |||
364 | u16 queue_map_min; | ||
365 | u16 queue_map_max; | ||
366 | |||
361 | #ifdef CONFIG_XFRM | 367 | #ifdef CONFIG_XFRM |
362 | __u8 ipsmode; /* IPSEC mode (config) */ | 368 | __u8 ipsmode; /* IPSEC mode (config) */ |
363 | __u8 ipsproto; /* IPSEC type (config) */ | 369 | __u8 ipsproto; /* IPSEC type (config) */ |
@@ -613,6 +619,11 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
613 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, | 619 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, |
614 | pkt_dev->lflow); | 620 | pkt_dev->lflow); |
615 | 621 | ||
622 | seq_printf(seq, | ||
623 | " queue_map_min: %u queue_map_max: %u\n", | ||
624 | pkt_dev->queue_map_min, | ||
625 | pkt_dev->queue_map_max); | ||
626 | |||
616 | if (pkt_dev->flags & F_IPV6) { | 627 | if (pkt_dev->flags & F_IPV6) { |
617 | char b1[128], b2[128], b3[128]; | 628 | char b1[128], b2[128], b3[128]; |
618 | fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); | 629 | fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); |
@@ -709,6 +720,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
709 | if (pkt_dev->flags & F_MPLS_RND) | 720 | if (pkt_dev->flags & F_MPLS_RND) |
710 | seq_printf(seq, "MPLS_RND "); | 721 | seq_printf(seq, "MPLS_RND "); |
711 | 722 | ||
723 | if (pkt_dev->flags & F_QUEUE_MAP_RND) | ||
724 | seq_printf(seq, "QUEUE_MAP_RND "); | ||
725 | |||
712 | if (pkt_dev->cflows) { | 726 | if (pkt_dev->cflows) { |
713 | if (pkt_dev->flags & F_FLOW_SEQ) | 727 | if (pkt_dev->flags & F_FLOW_SEQ) |
714 | seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/ | 728 | seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/ |
@@ -764,6 +778,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
764 | seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", | 778 | seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n", |
765 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); | 779 | pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); |
766 | 780 | ||
781 | seq_printf(seq, " cur_queue_map: %u\n", pkt_dev->cur_queue_map); | ||
782 | |||
767 | seq_printf(seq, " flows: %u\n", pkt_dev->nflows); | 783 | seq_printf(seq, " flows: %u\n", pkt_dev->nflows); |
768 | 784 | ||
769 | if (pkt_dev->result[0]) | 785 | if (pkt_dev->result[0]) |
@@ -1215,6 +1231,11 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1215 | else if (strcmp(f, "FLOW_SEQ") == 0) | 1231 | else if (strcmp(f, "FLOW_SEQ") == 0) |
1216 | pkt_dev->flags |= F_FLOW_SEQ; | 1232 | pkt_dev->flags |= F_FLOW_SEQ; |
1217 | 1233 | ||
1234 | else if (strcmp(f, "QUEUE_MAP_RND") == 0) | ||
1235 | pkt_dev->flags |= F_QUEUE_MAP_RND; | ||
1236 | |||
1237 | else if (strcmp(f, "!QUEUE_MAP_RND") == 0) | ||
1238 | pkt_dev->flags &= ~F_QUEUE_MAP_RND; | ||
1218 | #ifdef CONFIG_XFRM | 1239 | #ifdef CONFIG_XFRM |
1219 | else if (strcmp(f, "IPSEC") == 0) | 1240 | else if (strcmp(f, "IPSEC") == 0) |
1220 | pkt_dev->flags |= F_IPSEC_ON; | 1241 | pkt_dev->flags |= F_IPSEC_ON; |
@@ -1526,6 +1547,28 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1526 | return count; | 1547 | return count; |
1527 | } | 1548 | } |
1528 | 1549 | ||
1550 | if (!strcmp(name, "queue_map_min")) { | ||
1551 | len = num_arg(&user_buffer[i], 5, &value); | ||
1552 | if (len < 0) { | ||
1553 | return len; | ||
1554 | } | ||
1555 | i += len; | ||
1556 | pkt_dev->queue_map_min = value; | ||
1557 | sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); | ||
1558 | return count; | ||
1559 | } | ||
1560 | |||
1561 | if (!strcmp(name, "queue_map_max")) { | ||
1562 | len = num_arg(&user_buffer[i], 5, &value); | ||
1563 | if (len < 0) { | ||
1564 | return len; | ||
1565 | } | ||
1566 | i += len; | ||
1567 | pkt_dev->queue_map_max = value; | ||
1568 | sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); | ||
1569 | return count; | ||
1570 | } | ||
1571 | |||
1529 | if (!strcmp(name, "mpls")) { | 1572 | if (!strcmp(name, "mpls")) { |
1530 | unsigned n, offset; | 1573 | unsigned n, offset; |
1531 | len = get_labels(&user_buffer[i], pkt_dev); | 1574 | len = get_labels(&user_buffer[i], pkt_dev); |
@@ -2387,6 +2430,20 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2387 | pkt_dev->cur_pkt_size = t; | 2430 | pkt_dev->cur_pkt_size = t; |
2388 | } | 2431 | } |
2389 | 2432 | ||
2433 | if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { | ||
2434 | __u16 t; | ||
2435 | if (pkt_dev->flags & F_QUEUE_MAP_RND) { | ||
2436 | t = random32() % | ||
2437 | (pkt_dev->queue_map_max - pkt_dev->queue_map_min + 1) | ||
2438 | + pkt_dev->queue_map_min; | ||
2439 | } else { | ||
2440 | t = pkt_dev->cur_queue_map + 1; | ||
2441 | if (t > pkt_dev->queue_map_max) | ||
2442 | t = pkt_dev->queue_map_min; | ||
2443 | } | ||
2444 | pkt_dev->cur_queue_map = t; | ||
2445 | } | ||
2446 | |||
2390 | pkt_dev->flows[flow].count++; | 2447 | pkt_dev->flows[flow].count++; |
2391 | } | 2448 | } |
2392 | 2449 | ||
@@ -2557,6 +2614,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2557 | skb->network_header = skb->tail; | 2614 | skb->network_header = skb->tail; |
2558 | skb->transport_header = skb->network_header + sizeof(struct iphdr); | 2615 | skb->transport_header = skb->network_header + sizeof(struct iphdr); |
2559 | skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr)); | 2616 | skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr)); |
2617 | skb->queue_mapping = pkt_dev->cur_queue_map; | ||
2560 | 2618 | ||
2561 | iph = ip_hdr(skb); | 2619 | iph = ip_hdr(skb); |
2562 | udph = udp_hdr(skb); | 2620 | udph = udp_hdr(skb); |
@@ -2898,6 +2956,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2898 | skb->network_header = skb->tail; | 2956 | skb->network_header = skb->tail; |
2899 | skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); | 2957 | skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); |
2900 | skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr)); | 2958 | skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr)); |
2959 | skb->queue_mapping = pkt_dev->cur_queue_map; | ||
2901 | 2960 | ||
2902 | iph = ipv6_hdr(skb); | 2961 | iph = ipv6_hdr(skb); |
2903 | udph = udp_hdr(skb); | 2962 | udph = udp_hdr(skb); |