aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFrancesco Fondelli <francesco.fondelli@gmail.com>2006-09-27 19:30:44 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-28 21:01:46 -0400
commit34954ddc4f3e790fb6d5ed331513f54b38713234 (patch)
treed0bdd9f7b3a5240cb65a5944ad1ba94e3317016c /net
parent658270a0a49612a0e3fdc01c2e8c0e1a6d47cbf4 (diff)
[PKTGEN]: vlan support
The attached patch allows pktgen to produce 802.1Q and Q-in-Q tagged frames. I have used it for stress test a bridge and seems ok to me. Unfortunately I have no access to net-2.6.x git tree so the diff is against 2.6.17.13. Signed-off-by: Francesco Fondelli <francesco.fondelli@gmail.com> Acked-by: Steven Whitehouse <steve@chygwyn.com> Signed-off-by: Robert Olsson <robert.olsson@its.uu.se> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/pktgen.c256
1 files changed, 247 insertions, 9 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 72145d4a2600..033802769e4f 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>
@@ -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;
@@ -288,6 +296,15 @@ struct pktgen_dev {
288 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ 296 unsigned nr_labels; /* Depth of stack, 0 = no MPLS */
289 __be32 labels[MAX_MPLS_LABELS]; 297 __be32 labels[MAX_MPLS_LABELS];
290 298
299 /* VLAN/SVLAN (802.1Q/Q-in-Q) */
300 __u8 vlan_p;
301 __u8 vlan_cfi;
302 __u16 vlan_id; /* 0xffff means no vlan tag */
303
304 __u8 svlan_p;
305 __u8 svlan_cfi;
306 __u16 svlan_id; /* 0xffff means no svlan tag */
307
291 __u32 src_mac_count; /* How many MACs to iterate through */ 308 __u32 src_mac_count; /* How many MACs to iterate through */
292 __u32 dst_mac_count; /* How many MACs to iterate through */ 309 __u32 dst_mac_count; /* How many MACs to iterate through */
293 310
@@ -644,6 +661,16 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
644 i == pkt_dev->nr_labels-1 ? "\n" : ", "); 661 i == pkt_dev->nr_labels-1 ? "\n" : ", ");
645 } 662 }
646 663
664 if (pkt_dev->vlan_id != 0xffff) {
665 seq_printf(seq, " vlan_id: %u vlan_p: %u vlan_cfi: %u\n",
666 pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
667 }
668
669 if (pkt_dev->svlan_id != 0xffff) {
670 seq_printf(seq, " svlan_id: %u vlan_p: %u vlan_cfi: %u\n",
671 pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
672 }
673
647 seq_printf(seq, " Flags: "); 674 seq_printf(seq, " Flags: ");
648 675
649 if (pkt_dev->flags & F_IPV6) 676 if (pkt_dev->flags & F_IPV6)
@@ -673,6 +700,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
673 if (pkt_dev->flags & F_MACDST_RND) 700 if (pkt_dev->flags & F_MACDST_RND)
674 seq_printf(seq, "MACDST_RND "); 701 seq_printf(seq, "MACDST_RND ");
675 702
703 if (pkt_dev->flags & F_VID_RND)
704 seq_printf(seq, "VID_RND ");
705
706 if (pkt_dev->flags & F_SVID_RND)
707 seq_printf(seq, "SVID_RND ");
708
676 seq_puts(seq, "\n"); 709 seq_puts(seq, "\n");
677 710
678 sa = pkt_dev->started_at; 711 sa = pkt_dev->started_at;
@@ -1140,6 +1173,18 @@ static ssize_t pktgen_if_write(struct file *file,
1140 else if (strcmp(f, "!MPLS_RND") == 0) 1173 else if (strcmp(f, "!MPLS_RND") == 0)
1141 pkt_dev->flags &= ~F_MPLS_RND; 1174 pkt_dev->flags &= ~F_MPLS_RND;
1142 1175
1176 else if (strcmp(f, "VID_RND") == 0)
1177 pkt_dev->flags |= F_VID_RND;
1178
1179 else if (strcmp(f, "!VID_RND") == 0)
1180 pkt_dev->flags &= ~F_VID_RND;
1181
1182 else if (strcmp(f, "SVID_RND") == 0)
1183 pkt_dev->flags |= F_SVID_RND;
1184
1185 else if (strcmp(f, "!SVID_RND") == 0)
1186 pkt_dev->flags &= ~F_SVID_RND;
1187
1143 else { 1188 else {
1144 sprintf(pg_result, 1189 sprintf(pg_result,
1145 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", 1190 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
@@ -1445,6 +1490,128 @@ static ssize_t pktgen_if_write(struct file *file,
1445 offset += sprintf(pg_result + offset, 1490 offset += sprintf(pg_result + offset,
1446 "%08x%s", ntohl(pkt_dev->labels[n]), 1491 "%08x%s", ntohl(pkt_dev->labels[n]),
1447 n == pkt_dev->nr_labels-1 ? "" : ","); 1492 n == pkt_dev->nr_labels-1 ? "" : ",");
1493
1494 if (pkt_dev->nr_labels && pkt_dev->vlan_id != 0xffff) {
1495 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1496 pkt_dev->svlan_id = 0xffff;
1497
1498 if (debug)
1499 printk("pktgen: VLAN/SVLAN auto turned off\n");
1500 }
1501 return count;
1502 }
1503
1504 if (!strcmp(name, "vlan_id")) {
1505 len = num_arg(&user_buffer[i], 4, &value);
1506 if (len < 0) {
1507 return len;
1508 }
1509 i += len;
1510 if (value <= 4095) {
1511 pkt_dev->vlan_id = value; /* turn on VLAN */
1512
1513 if (debug)
1514 printk("pktgen: VLAN turned on\n");
1515
1516 if (debug && pkt_dev->nr_labels)
1517 printk("pktgen: MPLS auto turned off\n");
1518
1519 pkt_dev->nr_labels = 0; /* turn off MPLS */
1520 sprintf(pg_result, "OK: vlan_id=%u", pkt_dev->vlan_id);
1521 } else {
1522 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1523 pkt_dev->svlan_id = 0xffff;
1524
1525 if (debug)
1526 printk("pktgen: VLAN/SVLAN turned off\n");
1527 }
1528 return count;
1529 }
1530
1531 if (!strcmp(name, "vlan_p")) {
1532 len = num_arg(&user_buffer[i], 1, &value);
1533 if (len < 0) {
1534 return len;
1535 }
1536 i += len;
1537 if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
1538 pkt_dev->vlan_p = value;
1539 sprintf(pg_result, "OK: vlan_p=%u", pkt_dev->vlan_p);
1540 } else {
1541 sprintf(pg_result, "ERROR: vlan_p must be 0-7");
1542 }
1543 return count;
1544 }
1545
1546 if (!strcmp(name, "vlan_cfi")) {
1547 len = num_arg(&user_buffer[i], 1, &value);
1548 if (len < 0) {
1549 return len;
1550 }
1551 i += len;
1552 if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
1553 pkt_dev->vlan_cfi = value;
1554 sprintf(pg_result, "OK: vlan_cfi=%u", pkt_dev->vlan_cfi);
1555 } else {
1556 sprintf(pg_result, "ERROR: vlan_cfi must be 0-1");
1557 }
1558 return count;
1559 }
1560
1561 if (!strcmp(name, "svlan_id")) {
1562 len = num_arg(&user_buffer[i], 4, &value);
1563 if (len < 0) {
1564 return len;
1565 }
1566 i += len;
1567 if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
1568 pkt_dev->svlan_id = value; /* turn on SVLAN */
1569
1570 if (debug)
1571 printk("pktgen: SVLAN turned on\n");
1572
1573 if (debug && pkt_dev->nr_labels)
1574 printk("pktgen: MPLS auto turned off\n");
1575
1576 pkt_dev->nr_labels = 0; /* turn off MPLS */
1577 sprintf(pg_result, "OK: svlan_id=%u", pkt_dev->svlan_id);
1578 } else {
1579 pkt_dev->vlan_id = 0xffff; /* turn off VLAN/SVLAN */
1580 pkt_dev->svlan_id = 0xffff;
1581
1582 if (debug)
1583 printk("pktgen: VLAN/SVLAN turned off\n");
1584 }
1585 return count;
1586 }
1587
1588 if (!strcmp(name, "svlan_p")) {
1589 len = num_arg(&user_buffer[i], 1, &value);
1590 if (len < 0) {
1591 return len;
1592 }
1593 i += len;
1594 if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
1595 pkt_dev->svlan_p = value;
1596 sprintf(pg_result, "OK: svlan_p=%u", pkt_dev->svlan_p);
1597 } else {
1598 sprintf(pg_result, "ERROR: svlan_p must be 0-7");
1599 }
1600 return count;
1601 }
1602
1603 if (!strcmp(name, "svlan_cfi")) {
1604 len = num_arg(&user_buffer[i], 1, &value);
1605 if (len < 0) {
1606 return len;
1607 }
1608 i += len;
1609 if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
1610 pkt_dev->svlan_cfi = value;
1611 sprintf(pg_result, "OK: svlan_cfi=%u", pkt_dev->svlan_cfi);
1612 } else {
1613 sprintf(pg_result, "ERROR: svlan_cfi must be 0-1");
1614 }
1448 return count; 1615 return count;
1449 } 1616 }
1450 1617
@@ -1949,6 +2116,14 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
1949 htonl(0x000fffff)); 2116 htonl(0x000fffff));
1950 } 2117 }
1951 2118
2119 if ((pkt_dev->flags & F_VID_RND) && (pkt_dev->vlan_id != 0xffff)) {
2120 pkt_dev->vlan_id = pktgen_random() % 4096;
2121 }
2122
2123 if ((pkt_dev->flags & F_SVID_RND) && (pkt_dev->svlan_id != 0xffff)) {
2124 pkt_dev->svlan_id = pktgen_random() % 4096;
2125 }
2126
1952 if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { 2127 if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
1953 if (pkt_dev->flags & F_UDPSRC_RND) 2128 if (pkt_dev->flags & F_UDPSRC_RND)
1954 pkt_dev->cur_udp_src = 2129 pkt_dev->cur_udp_src =
@@ -2092,10 +2267,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2092 struct pktgen_hdr *pgh = NULL; 2267 struct pktgen_hdr *pgh = NULL;
2093 __be16 protocol = __constant_htons(ETH_P_IP); 2268 __be16 protocol = __constant_htons(ETH_P_IP);
2094 __be32 *mpls; 2269 __be32 *mpls;
2270 __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
2271 __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
2272 __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
2273 __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
2274
2095 2275
2096 if (pkt_dev->nr_labels) 2276 if (pkt_dev->nr_labels)
2097 protocol = __constant_htons(ETH_P_MPLS_UC); 2277 protocol = __constant_htons(ETH_P_MPLS_UC);
2098 2278
2279 if (pkt_dev->vlan_id != 0xffff)
2280 protocol = __constant_htons(ETH_P_8021Q);
2281
2099 /* Update any of the values, used when we're incrementing various 2282 /* Update any of the values, used when we're incrementing various
2100 * fields. 2283 * fields.
2101 */ 2284 */
@@ -2103,7 +2286,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2103 2286
2104 datalen = (odev->hard_header_len + 16) & ~0xf; 2287 datalen = (odev->hard_header_len + 16) & ~0xf;
2105 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen + 2288 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
2106 pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); 2289 pkt_dev->nr_labels*sizeof(u32) +
2290 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2291 GFP_ATOMIC);
2107 if (!skb) { 2292 if (!skb) {
2108 sprintf(pkt_dev->result, "No memory"); 2293 sprintf(pkt_dev->result, "No memory");
2109 return NULL; 2294 return NULL;
@@ -2116,6 +2301,24 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2116 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); 2301 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
2117 if (pkt_dev->nr_labels) 2302 if (pkt_dev->nr_labels)
2118 mpls_push(mpls, pkt_dev); 2303 mpls_push(mpls, pkt_dev);
2304
2305 if (pkt_dev->vlan_id != 0xffff) {
2306 if(pkt_dev->svlan_id != 0xffff) {
2307 svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2308 *svlan_tci = htons(pkt_dev->svlan_id);
2309 *svlan_tci |= pkt_dev->svlan_p << 5;
2310 *svlan_tci |= pkt_dev->svlan_cfi << 4;
2311 svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2312 *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
2313 }
2314 vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2315 *vlan_tci = htons(pkt_dev->vlan_id);
2316 *vlan_tci |= pkt_dev->vlan_p << 5;
2317 *vlan_tci |= pkt_dev->vlan_cfi << 4;
2318 vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2319 *vlan_encapsulated_proto = __constant_htons(ETH_P_IP);
2320 }
2321
2119 iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); 2322 iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
2120 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2323 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2121 2324
@@ -2124,7 +2327,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2124 2327
2125 /* Eth + IPh + UDPh + mpls */ 2328 /* Eth + IPh + UDPh + mpls */
2126 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - 2329 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
2127 pkt_dev->nr_labels*sizeof(u32); 2330 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2128 if (datalen < sizeof(struct pktgen_hdr)) 2331 if (datalen < sizeof(struct pktgen_hdr))
2129 datalen = sizeof(struct pktgen_hdr); 2332 datalen = sizeof(struct pktgen_hdr);
2130 2333
@@ -2146,7 +2349,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2146 iph->check = 0; 2349 iph->check = 0;
2147 iph->check = ip_fast_csum((void *)iph, iph->ihl); 2350 iph->check = ip_fast_csum((void *)iph, iph->ihl);
2148 skb->protocol = protocol; 2351 skb->protocol = protocol;
2149 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); 2352 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
2353 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2150 skb->dev = odev; 2354 skb->dev = odev;
2151 skb->pkt_type = PACKET_HOST; 2355 skb->pkt_type = PACKET_HOST;
2152 skb->nh.iph = iph; 2356 skb->nh.iph = iph;
@@ -2218,7 +2422,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2218 pgh->tv_sec = htonl(timestamp.tv_sec); 2422 pgh->tv_sec = htonl(timestamp.tv_sec);
2219 pgh->tv_usec = htonl(timestamp.tv_usec); 2423 pgh->tv_usec = htonl(timestamp.tv_usec);
2220 } 2424 }
2221 pkt_dev->seq_num++;
2222 2425
2223 return skb; 2426 return skb;
2224} 2427}
@@ -2402,17 +2605,26 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2402 struct pktgen_hdr *pgh = NULL; 2605 struct pktgen_hdr *pgh = NULL;
2403 __be16 protocol = __constant_htons(ETH_P_IPV6); 2606 __be16 protocol = __constant_htons(ETH_P_IPV6);
2404 __be32 *mpls; 2607 __be32 *mpls;
2608 __be16 *vlan_tci = NULL; /* Encapsulates priority and VLAN ID */
2609 __be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
2610 __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
2611 __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
2405 2612
2406 if (pkt_dev->nr_labels) 2613 if (pkt_dev->nr_labels)
2407 protocol = __constant_htons(ETH_P_MPLS_UC); 2614 protocol = __constant_htons(ETH_P_MPLS_UC);
2408 2615
2616 if (pkt_dev->vlan_id != 0xffff)
2617 protocol = __constant_htons(ETH_P_8021Q);
2618
2409 /* Update any of the values, used when we're incrementing various 2619 /* Update any of the values, used when we're incrementing various
2410 * fields. 2620 * fields.
2411 */ 2621 */
2412 mod_cur_headers(pkt_dev); 2622 mod_cur_headers(pkt_dev);
2413 2623
2414 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 + 2624 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
2415 pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); 2625 pkt_dev->nr_labels*sizeof(u32) +
2626 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2627 GFP_ATOMIC);
2416 if (!skb) { 2628 if (!skb) {
2417 sprintf(pkt_dev->result, "No memory"); 2629 sprintf(pkt_dev->result, "No memory");
2418 return NULL; 2630 return NULL;
@@ -2425,16 +2637,34 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2425 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); 2637 mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
2426 if (pkt_dev->nr_labels) 2638 if (pkt_dev->nr_labels)
2427 mpls_push(mpls, pkt_dev); 2639 mpls_push(mpls, pkt_dev);
2640
2641 if (pkt_dev->vlan_id != 0xffff) {
2642 if(pkt_dev->svlan_id != 0xffff) {
2643 svlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2644 *svlan_tci = htons(pkt_dev->svlan_id);
2645 *svlan_tci |= pkt_dev->svlan_p << 5;
2646 *svlan_tci |= pkt_dev->svlan_cfi << 4;
2647 svlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2648 *svlan_encapsulated_proto = __constant_htons(ETH_P_8021Q);
2649 }
2650 vlan_tci = (__be16 *)skb_put(skb, sizeof(__be16));
2651 *vlan_tci = htons(pkt_dev->vlan_id);
2652 *vlan_tci |= pkt_dev->vlan_p << 5;
2653 *vlan_tci |= pkt_dev->vlan_cfi << 4;
2654 vlan_encapsulated_proto = (__be16 *)skb_put(skb, sizeof(__be16));
2655 *vlan_encapsulated_proto = __constant_htons(ETH_P_IPV6);
2656 }
2657
2428 iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); 2658 iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
2429 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2659 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2430 2660
2431 memcpy(eth, pkt_dev->hh, 12); 2661 memcpy(eth, pkt_dev->hh, 12);
2432 *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6); 2662 *(u16 *) & eth[12] = protocol;
2433 2663
2434 /* Eth + IPh + UDPh + mpls */ 2664 /* Eth + IPh + UDPh + mpls */
2435 datalen = pkt_dev->cur_pkt_size - 14 - 2665 datalen = pkt_dev->cur_pkt_size - 14 -
2436 sizeof(struct ipv6hdr) - sizeof(struct udphdr) - 2666 sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
2437 pkt_dev->nr_labels*sizeof(u32); 2667 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2438 2668
2439 if (datalen < sizeof(struct pktgen_hdr)) { 2669 if (datalen < sizeof(struct pktgen_hdr)) {
2440 datalen = sizeof(struct pktgen_hdr); 2670 datalen = sizeof(struct pktgen_hdr);
@@ -2458,7 +2688,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2458 ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr); 2688 ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
2459 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); 2689 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
2460 2690
2461 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); 2691 skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32) -
2692 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
2462 skb->protocol = protocol; 2693 skb->protocol = protocol;
2463 skb->dev = odev; 2694 skb->dev = odev;
2464 skb->pkt_type = PACKET_HOST; 2695 skb->pkt_type = PACKET_HOST;
@@ -2531,7 +2762,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2531 pgh->tv_sec = htonl(timestamp.tv_sec); 2762 pgh->tv_sec = htonl(timestamp.tv_sec);
2532 pgh->tv_usec = htonl(timestamp.tv_usec); 2763 pgh->tv_usec = htonl(timestamp.tv_usec);
2533 } 2764 }
2534 pkt_dev->seq_num++; 2765 /* pkt_dev->seq_num++; FF: you really mean this? */
2535 2766
2536 return skb; 2767 return skb;
2537} 2768}
@@ -3177,6 +3408,13 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3177 pkt_dev->udp_dst_min = 9; 3408 pkt_dev->udp_dst_min = 9;
3178 pkt_dev->udp_dst_max = 9; 3409 pkt_dev->udp_dst_max = 9;
3179 3410
3411 pkt_dev->vlan_p = 0;
3412 pkt_dev->vlan_cfi = 0;
3413 pkt_dev->vlan_id = 0xffff;
3414 pkt_dev->svlan_p = 0;
3415 pkt_dev->svlan_cfi = 0;
3416 pkt_dev->svlan_id = 0xffff;
3417
3180 strncpy(pkt_dev->ifname, ifname, IFNAMSIZ); 3418 strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
3181 3419
3182 if (!pktgen_setup_dev(pkt_dev)) { 3420 if (!pktgen_setup_dev(pkt_dev)) {