aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/pktgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r--net/core/pktgen.c329
1 files changed, 312 insertions, 17 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 67ed14ddabd2..dd023fd28304 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -109,6 +109,8 @@
109 * 109 *
110 * MPLS support by Steven Whitehouse <steve@chygwyn.com> 110 * MPLS support by Steven Whitehouse <steve@chygwyn.com>
111 * 111 *
112 * 802.1Q/Q-in-Q support by Francesco Fondelli (FF) <francesco.fondelli@gmail.com>
113 *
112 */ 114 */
113#include <linux/sys.h> 115#include <linux/sys.h>
114#include <linux/types.h> 116#include <linux/types.h>
@@ -137,6 +139,7 @@
137#include <linux/inetdevice.h> 139#include <linux/inetdevice.h>
138#include <linux/rtnetlink.h> 140#include <linux/rtnetlink.h>
139#include <linux/if_arp.h> 141#include <linux/if_arp.h>
142#include <linux/if_vlan.h>
140#include <linux/in.h> 143#include <linux/in.h>
141#include <linux/ip.h> 144#include <linux/ip.h>
142#include <linux/ipv6.h> 145#include <linux/ipv6.h>
@@ -157,7 +160,7 @@
157#include <asm/div64.h> /* do_div */ 160#include <asm/div64.h> /* do_div */
158#include <asm/timex.h> 161#include <asm/timex.h>
159 162
160#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"
161 164
162/* #define PG_DEBUG(a) a */ 165/* #define PG_DEBUG(a) a */
163#define PG_DEBUG(a) 166#define PG_DEBUG(a)
@@ -178,6 +181,8 @@
178#define F_TXSIZE_RND (1<<6) /* Transmit size is random */ 181#define F_TXSIZE_RND (1<<6) /* Transmit size is random */
179#define F_IPV6 (1<<7) /* Interface in IPV6 Mode */ 182#define F_IPV6 (1<<7) /* Interface in IPV6 Mode */
180#define F_MPLS_RND (1<<8) /* Random MPLS labels */ 183#define F_MPLS_RND (1<<8) /* Random MPLS labels */
184#define F_VID_RND (1<<9) /* Random VLAN ID */
185#define F_SVID_RND (1<<10) /* Random SVLAN ID */
181 186
182/* Thread control flag bits */ 187/* Thread control flag bits */
183#define T_TERMINATE (1<<0) 188#define T_TERMINATE (1<<0)
@@ -198,6 +203,9 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
198 203
199#define MAX_CFLOWS 65536 204#define MAX_CFLOWS 65536
200 205
206#define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4)
207#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4)
208
201struct flow_state { 209struct flow_state {
202 __u32 cur_daddr; 210 __u32 cur_daddr;
203 int count; 211 int count;
@@ -284,10 +292,23 @@ struct pktgen_dev {
284 __u16 udp_dst_min; /* inclusive, dest UDP port */ 292 __u16 udp_dst_min; /* inclusive, dest UDP port */
285 __u16 udp_dst_max; /* exclusive, dest UDP port */ 293 __u16 udp_dst_max; /* exclusive, dest UDP port */
286 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
287 /* MPLS */ 299 /* MPLS */
288 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ 300 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */
289 __be32 labels[MAX_MPLS_LABELS]; 301 __be32 labels[MAX_MPLS_LABELS];
290 302
303 /* VLAN/SVLAN (802.1Q/Q-in-Q) */
304 __u8 vlan_p;
305 __u8 vlan_cfi;
306 __u16 vlan_id; /* 0xffff means no vlan tag */
307
308 __u8 svlan_p;
309 __u8 svlan_cfi;
310 __u16 svlan_id; /* 0xffff means no svlan tag */
311
291 __u32 src_mac_count; /* How many MACs to iterate through */ 312 __u32 src_mac_count; /* How many MACs to iterate through */
292 __u32 dst_mac_count; /* How many MACs to iterate through */ 313 __u32 dst_mac_count; /* How many MACs to iterate through */
293 314
@@ -644,6 +665,24 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
644 i == pkt_dev->nr_labels-1 ? "\n" : ", "); 665 i == pkt_dev->nr_labels-1 ? "\n" : ", ");
645 } 666 }
646 667
668 if (pkt_dev->vlan_id != 0xffff) {
669 seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n",
670 pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
671 }
672
673 if (pkt_dev->svlan_id != 0xffff) {
674 seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n",
675 pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
676 }
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
647 seq_printf(seq, " Flags: "); 686 seq_printf(seq, " Flags: ");
648 687
649 if (pkt_dev->flags & F_IPV6) 688 if (pkt_dev->flags & F_IPV6)
@@ -673,6 +712,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
673 if (pkt_dev->flags & F_MACDST_RND) 712 if (pkt_dev->flags & F_MACDST_RND)
674 seq_printf(seq, "MACDST_RND "); 713 seq_printf(seq, "MACDST_RND ");
675 714
715 if (pkt_dev->flags & F_VID_RND)
716 seq_printf(seq, "VID_RND ");
717
718 if (pkt_dev->flags & F_SVID_RND)
719 seq_printf(seq, "SVID_RND ");
720
676 seq_puts(seq, "\n"); 721 seq_puts(seq, "\n");
677 722
678 sa = pkt_dev->started_at; 723 sa = pkt_dev->started_at;
@@ -715,12 +760,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
715} 760}
716 761
717 762
718static int hex32_arg(const char __user *user_buffer, __u32 *num) 763static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
719{ 764{
720 int i = 0; 765 int i = 0;
721 *num = 0; 766 *num = 0;
722 767
723 for(; i < 8; i++) { 768 for(; i < maxlen; i++) {
724 char c; 769 char c;
725 *num <<= 4; 770 *num <<= 4;
726 if (get_user(c, &user_buffer[i])) 771 if (get_user(c, &user_buffer[i]))
@@ -815,7 +860,7 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
815 pkt_dev->nr_labels = 0; 860 pkt_dev->nr_labels = 0;
816 do { 861 do {
817 __u32 tmp; 862 __u32 tmp;
818 len = hex32_arg(&buffer[i], &tmp); 863 len = hex32_arg(&buffer[i], 8, &tmp);
819 if (len <= 0) 864 if (len <= 0)
820 return len; 865 return len;
821 pkt_dev->labels[n] = htonl(tmp); 866 pkt_dev->labels[n] = htonl(tmp);
@@ -1140,11 +1185,27 @@ static ssize_t pktgen_if_write(struct file *file,
1140 else if (strcmp(f, "!MPLS_RND") == 0) 1185 else if (strcmp(f, "!MPLS_RND") == 0)
1141 pkt_dev->flags &= ~F_MPLS_RND; 1186 pkt_dev->flags &= ~F_MPLS_RND;
1142 1187
1188 else if (strcmp(f, "VID_RND") == 0)
1189 pkt_dev->flags |= F_VID_RND;
1190
1191 else if (strcmp(f, "!VID_RND") == 0)
1192 pkt_dev->flags &= ~F_VID_RND;
1193
1194 else if (strcmp(f, "SVID_RND") == 0)
1195 pkt_dev->flags |= F_SVID_RND;
1196
1197 else if (strcmp(f, "!SVID_RND") == 0)
1198 pkt_dev->flags &= ~F_SVID_RND;
1199
1200 else if (strcmp(f, "!IPV6") == 0)
1201 pkt_dev->flags &= ~F_IPV6;
1202
1143 else { 1203 else {
1144 sprintf(pg_result, 1204 sprintf(pg_result,
1145 "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",
1146 f, 1206 f,
1147 "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");
1148 return count; 1209 return count;
1149 } 1210 }
1150 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags); 1211 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -1445,6 +1506,160 @@ static ssize_t pktgen_if_write(struct file *file,
1445 offset += sprintf(pg_result + offset, 1506 offset += sprintf(pg_result + offset,
1446 "%08x%s", ntohl(pkt_dev->labels[n]), 1507 "%08x%s", ntohl(pkt_dev->labels[n]),
1447 n == pkt_dev->nr_labels-1 ? "" : ","); 1508 n == pkt_dev->nr_labels-1 ? "" : ",");
1509
1510 if (pkt_dev->nr_labels && pkt_dev->vlan_id != 0xffff) {
1511 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1512 pkt_dev->svlan_id = 0xffff;
1513
1514 if (debug)
1515 printk("pktgen: VLAN/SVLAN auto turned off\n");
1516 }
1517 return count;
1518 }
1519
1520 if (!strcmp(name, "vlan_id")) {
1521 len = num_arg(&user_buffer[i], 4, &value);
1522 if (len < 0) {
1523 return len;
1524 }
1525 i += len;
1526 if (value <= 4095) {
1527 pkt_dev->vlan_id = value; /* turn on VLAN */
1528
1529 if (debug)
1530 printk("pktgen: VLAN turned on\n");
1531
1532 if (debug && pkt_dev->nr_labels)
1533 printk("pktgen: MPLS auto turned off\n");
1534
1535 pkt_dev->nr_labels = 0; /* turn off MPLS */
1536 sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id);
1537 } else {
1538 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1539 pkt_dev->svlan_id = 0xffff;
1540
1541 if (debug)
1542 printk("pktgen: VLAN/SVLAN turned off\n");
1543 }
1544 return count;
1545 }
1546
1547 if (!strcmp(name, "vlan_p")) {
1548 len = num_arg(&user_buffer[i], 1, &value);
1549 if (len < 0) {
1550 return len;
1551 }
1552 i += len;
1553 if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
1554 pkt_dev->vlan_p = value;
1555 sprintf(pg_result, "OK: vlan_p=%u", pkt_dev->vlan_p);
1556 } else {
1557 sprintf(pg_result, "ERROR: vlan_p must be 0-7");
1558 }
1559 return count;
1560 }
1561
1562 if (!strcmp(name, "vlan_cfi")) {
1563 len = num_arg(&user_buffer[i], 1, &value);
1564 if (len < 0) {
1565 return len;
1566 }
1567 i += len;
1568 if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
1569 pkt_dev->vlan_cfi = value;
1570 sprintf(pg_result, "OK: vlan_cfi=%u", pkt_dev->vlan_cfi);
1571 } else {
1572 sprintf(pg_result, "ERROR: vlan_cfi must be 0-1");
1573 }
1574 return count;
1575 }
1576
1577 if (!strcmp(name, "svlan_id")) {
1578 len = num_arg(&user_buffer[i], 4, &value);
1579 if (len < 0) {
1580 return len;
1581 }
1582 i += len;
1583 if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
1584 pkt_dev->svlan_id = value; /* turn on SVLAN */
1585
1586 if (debug)
1587 printk("pktgen: SVLAN turned on\n");
1588
1589 if (debug && pkt_dev->nr_labels)
1590 printk("pktgen: MPLS auto turned off\n");
1591
1592 pkt_dev->nr_labels = 0; /* turn off MPLS */
1593 sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id);
1594 } else {
1595 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1596 pkt_dev->svlan_id = 0xffff;
1597
1598 if (debug)
1599 printk("pktgen: VLAN/SVLAN turned off\n");
1600 }
1601 return count;
1602 }
1603
1604 if (!strcmp(name, "svlan_p")) {
1605 len = num_arg(&user_buffer[i], 1, &value);
1606 if (len < 0) {
1607 return len;
1608 }
1609 i += len;
1610 if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
1611 pkt_dev->svlan_p = value;
1612 sprintf(pg_result, "OK: svlan_p=%u", pkt_dev->svlan_p);
1613 } else {
1614 sprintf(pg_result, "ERROR: svlan_p must be 0-7");
1615 }
1616 return count;
1617 }
1618
1619 if (!strcmp(name, "svlan_cfi")) {
1620 len = num_arg(&user_buffer[i], 1, &value);
1621 if (len < 0) {
1622 return len;
1623 }
1624 i += len;
1625 if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
1626 pkt_dev->svlan_cfi = value;
1627 sprintf(pg_result, "OK: svlan_cfi=%u", pkt_dev->svlan_cfi);
1628 } else {
1629 sprintf(pg_result, "ERROR: svlan_cfi must be 0-1");
1630 }
1631 return count;
1632 }
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 }
1448 return count; 1663 return count;
1449 } 1664 }
1450 1665
@@ -1786,7 +2001,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1786 * use ipv6_get_lladdr if/when it's get exported 2001 * use ipv6_get_lladdr if/when it's get exported
1787 */ 2002 */
1788 2003
1789 read_lock(&addrconf_lock); 2004 rcu_read_lock();
1790 if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { 2005 if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
1791 struct inet6_ifaddr *ifp; 2006 struct inet6_ifaddr *ifp;
1792 2007
@@ -1805,7 +2020,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1805 } 2020 }
1806 read_unlock_bh(&idev->lock); 2021 read_unlock_bh(&idev->lock);
1807 } 2022 }
1808 read_unlock(&addrconf_lock); 2023 rcu_read_unlock();
1809 if (err) 2024 if (err)
1810 printk("pktgen: ERROR: IPv6 link address not availble.\n"); 2025 printk("pktgen: ERROR: IPv6 link address not availble.\n");
1811 } 2026 }
@@ -1949,6 +2164,14 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
1949 htonl(0x000fffff)); 2164 htonl(0x000fffff));
1950 } 2165 }
1951 2166
2167 if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) {
2168 pkt_dev->vlan_id = pktgen_random() % 4096;
2169 }
2170
2171 if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) {
2172 pkt_dev->svlan_id = pktgen_random() % 4096;
2173 }
2174
1952 if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { 2175 if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
1953 if (pkt_dev->flags & F_UDPSRC_RND) 2176 if (pkt_dev->flags & F_UDPSRC_RND)
1954 pkt_dev->cur_udp_src = 2177 pkt_dev->cur_udp_src =
@@ -2092,10 +2315,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2092 struct pktgen_hdr *pgh = NULL; 2315 struct pktgen_hdr *pgh = NULL;
2093 __be16 protocol = __constant_htons(ETH_P_IP); 2316 __be16 protocol = __constant_htons(ETH_P_IP);
2094 __be32 *mpls; 2317 __be32 *mpls;
2318 __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
2319 __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
2320 __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
2321 __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
2322
2095 2323
2096 if (pkt_dev->nr_labels) 2324 if (pkt_dev->nr_labels)
2097 protocol = __constant_htons(ETH_P_MPLS_UC); 2325 protocol = __constant_htons(ETH_P_MPLS_UC);
2098 2326
2327 if (pkt_dev->vlan_id != 0xffff)
2328 protocol = __constant_htons(ETH_P_8021Q);
2329
2099 /* Update any of the values, used when we're incrementing various 2330 /* Update any of the values, used when we're incrementing various
2100 * fields. 2331 * fields.
2101 */ 2332 */
@@ -2103,7 +2334,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2103 2334
2104 datalen = (odev->hard_header_len + 16) & ~0xf; 2335 datalen = (odev->hard_header_len + 16) & ~0xf;
2105 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen + 2336 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
2106 pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); 2337 pkt_dev->nr_labels*sizeof(u32) +
2338 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2339 GFP_ATOMIC);
2107 if (!skb) { 2340 if (!skb) {
2108 sprintf(pkt_dev->result, "No memory"); 2341 sprintf(pkt_dev->result, "No memory");
2109 return NULL; 2342 return NULL;
@@ -2116,6 +2349,24 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2116 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); 2349 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
2117 if (pkt_dev->nr_labels) 2350 if (pkt_dev->nr_labels)
2118 mpls_push(mpls, pkt_dev); 2351 mpls_push(mpls, pkt_dev);
2352
2353 if (pkt_dev->vlan_id != 0xffff) {
2354 if(pkt_dev->svlan_id != 0xffff) {
2355 svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2356 *svlan_tci = htons(pkt_dev->svlan_id);
2357 *svlan_tci |= pkt_dev->svlan_p << 5;
2358 *svlan_tci |= pkt_dev->svlan_cfi << 4;
2359 svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2360 *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
2361 }
2362 vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2363 *vlan_tci = htons(pkt_dev->vlan_id);
2364 *vlan_tci |= pkt_dev->vlan_p << 5;
2365 *vlan_tci |= pkt_dev->vlan_cfi << 4;
2366 vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2367 *vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
2368 }
2369
2119 iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); 2370 iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
2120 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2371 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2121 2372
@@ -2124,7 +2375,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2124 2375
2125 /* Eth + IPh + UDPh + mpls */ 2376 /* Eth + IPh + UDPh + mpls */
2126 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - 2377 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
2127 pkt_dev->nr_labels*sizeof(u32); 2378 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2128 if (datalen < sizeof(struct pktgen_hdr)) 2379 if (datalen < sizeof(struct pktgen_hdr))
2129 datalen = sizeof(struct pktgen_hdr); 2380 datalen = sizeof(struct pktgen_hdr);
2130 2381
@@ -2136,7 +2387,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2136 iph->ihl = 5; 2387 iph->ihl = 5;
2137 iph->version = 4; 2388 iph->version = 4;
2138 iph->ttl = 32; 2389 iph->ttl = 32;
2139 iph->tos = 0; 2390 iph->tos = pkt_dev->tos;
2140 iph->protocol = IPPROTO_UDP; /* UDP */ 2391 iph->protocol = IPPROTO_UDP; /* UDP */
2141 iph->saddr = pkt_dev->cur_saddr; 2392 iph->saddr = pkt_dev->cur_saddr;
2142 iph->daddr = pkt_dev->cur_daddr; 2393 iph->daddr = pkt_dev->cur_daddr;
@@ -2146,9 +2397,12 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2146 iph->check = 0; 2397 iph->check = 0;
2147 iph->check = ip_fast_csum((void *)iph, iph->ihl); 2398 iph->check = ip_fast_csum((void *)iph, iph->ihl);
2148 skb->protocol = protocol; 2399 skb->protocol = protocol;
2149 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); 2400 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
2401 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2150 skb->dev = odev; 2402 skb->dev = odev;
2151 skb->pkt_type = PACKET_HOST; 2403 skb->pkt_type = PACKET_HOST;
2404 skb->nh.iph = iph;
2405 skb->h.uh = udph;
2152 2406
2153 if (pkt_dev->nfrags <= 0) 2407 if (pkt_dev->nfrags <= 0)
2154 pgh = (struct pktgen_hdr *)skb_put(skb, datalen); 2408 pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
@@ -2216,7 +2470,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2216 pgh->tv_sec = htonl(timestamp.tv_sec); 2470 pgh->tv_sec = htonl(timestamp.tv_sec);
2217 pgh->tv_usec = htonl(timestamp.tv_usec); 2471 pgh->tv_usec = htonl(timestamp.tv_usec);
2218 } 2472 }
2219 pkt_dev->seq_num++;
2220 2473
2221 return skb; 2474 return skb;
2222} 2475}
@@ -2400,17 +2653,26 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2400 struct pktgen_hdr *pgh = NULL; 2653 struct pktgen_hdr *pgh = NULL;
2401 __be16 protocol = __constant_htons(ETH_P_IPV6); 2654 __be16 protocol = __constant_htons(ETH_P_IPV6);
2402 __be32 *mpls; 2655 __be32 *mpls;
2656 __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
2657 __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
2658 __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
2659 __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
2403 2660
2404 if (pkt_dev->nr_labels) 2661 if (pkt_dev->nr_labels)
2405 protocol = __constant_htons(ETH_P_MPLS_UC); 2662 protocol = __constant_htons(ETH_P_MPLS_UC);
2406 2663
2664 if (pkt_dev->vlan_id != 0xffff)
2665 protocol = __constant_htons(ETH_P_8021Q);
2666
2407 /* Update any of the values, used when we're incrementing various 2667 /* Update any of the values, used when we're incrementing various
2408 * fields. 2668 * fields.
2409 */ 2669 */
2410 mod_cur_headers(pkt_dev); 2670 mod_cur_headers(pkt_dev);
2411 2671
2412 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 + 2672 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
2413 pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); 2673 pkt_dev->nr_labels*sizeof(u32) +
2674 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2675 GFP_ATOMIC);
2414 if (!skb) { 2676 if (!skb) {
2415 sprintf(pkt_dev->result, "No memory"); 2677 sprintf(pkt_dev->result, "No memory");
2416 return NULL; 2678 return NULL;
@@ -2423,16 +2685,34 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2423 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); 2685 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
2424 if (pkt_dev->nr_labels) 2686 if (pkt_dev->nr_labels)
2425 mpls_push(mpls, pkt_dev); 2687 mpls_push(mpls, pkt_dev);
2688
2689 if (pkt_dev->vlan_id != 0xffff) {
2690 if(pkt_dev->svlan_id != 0xffff) {
2691 svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2692 *svlan_tci = htons(pkt_dev->svlan_id);
2693 *svlan_tci |= pkt_dev->svlan_p << 5;
2694 *svlan_tci |= pkt_dev->svlan_cfi << 4;
2695 svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2696 *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
2697 }
2698 vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2699 *vlan_tci = htons(pkt_dev->vlan_id);
2700 *vlan_tci |= pkt_dev->vlan_p << 5;
2701 *vlan_tci |= pkt_dev->vlan_cfi << 4;
2702 vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2703 *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
2704 }
2705
2426 iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); 2706 iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
2427 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2707 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2428 2708
2429 memcpy(eth, pkt_dev->hh, 12); 2709 memcpy(eth, pkt_dev->hh, 12);
2430 *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6); 2710 *(u16 *) & eth[12] = protocol;
2431 2711
2432 /* Eth + IPh + UDPh + mpls */ 2712 /* Eth + IPh + UDPh + mpls */
2433 datalen = pkt_dev->cur_pkt_size - 14 - 2713 datalen = pkt_dev->cur_pkt_size - 14 -
2434 sizeof(struct ipv6hdr) - sizeof(struct udphdr) - 2714 sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
2435 pkt_dev->nr_labels*sizeof(u32); 2715 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2436 2716
2437 if (datalen < sizeof(struct pktgen_hdr)) { 2717 if (datalen < sizeof(struct pktgen_hdr)) {
2438 datalen = sizeof(struct pktgen_hdr); 2718 datalen = sizeof(struct pktgen_hdr);
@@ -2448,6 +2728,11 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2448 2728
2449 *(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */ 2729 *(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */
2450 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
2451 iph->hop_limit = 32; 2736 iph->hop_limit = 32;
2452 2737
2453 iph->payload_len = htons(sizeof(struct udphdr) + datalen); 2738 iph->payload_len = htons(sizeof(struct udphdr) + datalen);
@@ -2456,10 +2741,13 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2456 ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr); 2741 ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
2457 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); 2742 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
2458 2743
2459 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); 2744 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
2745 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2460 skb->protocol = protocol; 2746 skb->protocol = protocol;
2461 skb->dev = odev; 2747 skb->dev = odev;
2462 skb->pkt_type = PACKET_HOST; 2748 skb->pkt_type = PACKET_HOST;
2749 skb->nh.ipv6h = iph;
2750 skb->h.uh = udph;
2463 2751
2464 if (pkt_dev->nfrags <= 0) 2752 if (pkt_dev->nfrags <= 0)
2465 pgh = (struct pktgen_hdr *)skb_put(skb, datalen); 2753 pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
@@ -2527,7 +2815,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2527 pgh->tv_sec = htonl(timestamp.tv_sec); 2815 pgh->tv_sec = htonl(timestamp.tv_sec);
2528 pgh->tv_usec = htonl(timestamp.tv_usec); 2816 pgh->tv_usec = htonl(timestamp.tv_usec);
2529 } 2817 }
2530 pkt_dev->seq_num++; 2818 /* pkt_dev->seq_num++; FF: you really mean this? */
2531 2819
2532 return skb; 2820 return skb;
2533} 2821}
@@ -3173,6 +3461,13 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3173 pkt_dev->udp_dst_min = 9; 3461 pkt_dev->udp_dst_min = 9;
3174 pkt_dev->udp_dst_max = 9; 3462 pkt_dev->udp_dst_max = 9;
3175 3463
3464 pkt_dev->vlan_p = 0;
3465 pkt_dev->vlan_cfi = 0;
3466 pkt_dev->vlan_id = 0xffff;
3467 pkt_dev->svlan_p = 0;
3468 pkt_dev->svlan_cfi = 0;
3469 pkt_dev->svlan_id = 0xffff;
3470
3176 strncpy(pkt_dev->ifname, ifname, IFNAMSIZ); 3471 strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
3177 3472
3178 if (!pktgen_setup_dev(pkt_dev)) { 3473 if (!pktgen_setup_dev(pkt_dev)) {