Loading Documentation/networking/pktgen.txt +19 −1 Original line number Diff line number Diff line Loading @@ -109,6 +109,22 @@ Examples: cycle through the port range. pgset "udp_dst_max 9" set UDP destination port max. pgset "mpls 0001000a,0002000a,0000000a" set MPLS labels (in this example outer label=16,middle label=32, inner label=0 (IPv4 NULL)) Note that there must be no spaces between the arguments. Leading zeros are required. Do not set the bottom of stack bit, thats done automatically. If you do set the bottom of stack bit, that indicates that you want to randomly generate that address and the flag MPLS_RND will be turned on. You can have any mix of random and fixed labels in the label stack. pgset "mpls 0" turn off mpls (or any invalid argument works too!) pgset stop aborts injection. Also, ^C aborts generator. Loading Loading @@ -167,6 +183,8 @@ pkt_size min_pkt_size max_pkt_size mpls udp_src_min udp_src_max Loading net/core/pktgen.c +147 −11 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ * * interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <nacc@us.ibm.com> * 050103 * * MPLS support by Steven Whitehouse <steve@chygwyn.com> * */ #include <linux/sys.h> #include <linux/types.h> Loading Loading @@ -154,7 +157,7 @@ #include <asm/div64.h> /* do_div */ #include <asm/timex.h> #define VERSION "pktgen v2.66: Packet Generator for packet performance testing.\n" #define VERSION "pktgen v2.67: Packet Generator for packet performance testing.\n" /* #define PG_DEBUG(a) a */ #define PG_DEBUG(a) Loading @@ -162,6 +165,8 @@ /* The buckets are exponential in 'width' */ #define LAT_BUCKETS_MAX 32 #define IP_NAME_SZ 32 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ #define MPLS_STACK_BOTTOM __constant_htonl(0x00000100) /* Device flag bits */ #define F_IPSRC_RND (1<<0) /* IP-Src Random */ Loading @@ -172,6 +177,7 @@ #define F_MACDST_RND (1<<5) /* MAC-Dst Random */ #define F_TXSIZE_RND (1<<6) /* Transmit size is random */ #define F_IPV6 (1<<7) /* Interface in IPV6 Mode */ #define F_MPLS_RND (1<<8) /* Random MPLS labels */ /* Thread control flag bits */ #define T_TERMINATE (1<<0) Loading Loading @@ -278,6 +284,10 @@ struct pktgen_dev { __u16 udp_dst_min; /* inclusive, dest UDP port */ __u16 udp_dst_max; /* exclusive, dest UDP port */ /* MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ __be32 labels[MAX_MPLS_LABELS]; __u32 src_mac_count; /* How many MACs to iterate through */ __u32 dst_mac_count; /* How many MACs to iterate through */ Loading Loading @@ -623,9 +633,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v) pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ", " src_mac_count: %d dst_mac_count: %d\n", pkt_dev->src_mac_count, pkt_dev->dst_mac_count); if (pkt_dev->nr_labels) { unsigned i; seq_printf(seq, " mpls: "); for(i = 0; i < pkt_dev->nr_labels; i++) seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]), i == pkt_dev->nr_labels-1 ? "\n" : ", "); } seq_printf(seq, " Flags: "); if (pkt_dev->flags & F_IPV6) seq_printf(seq, "IPV6 "); Loading @@ -644,6 +664,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v) if (pkt_dev->flags & F_UDPDST_RND) seq_printf(seq, "UDPDST_RND "); if (pkt_dev->flags & F_MPLS_RND) seq_printf(seq, "MPLS_RND "); if (pkt_dev->flags & F_MACSRC_RND) seq_printf(seq, "MACSRC_RND "); Loading Loading @@ -691,6 +714,29 @@ static int pktgen_if_show(struct seq_file *seq, void *v) return 0; } static int hex32_arg(const char __user *user_buffer, __u32 *num) { int i = 0; *num = 0; for(; i < 8; i++) { char c; *num <<= 4; if (get_user(c, &user_buffer[i])) return -EFAULT; if ((c >= '0') && (c <= '9')) *num |= c - '0'; else if ((c >= 'a') && (c <= 'f')) *num |= c - 'a' + 10; else if ((c >= 'A') && (c <= 'F')) *num |= c - 'A' + 10; else break; } return i; } static int count_trail_chars(const char __user * user_buffer, unsigned int maxlen) { Loading Loading @@ -759,6 +805,35 @@ static int strn_len(const char __user * user_buffer, unsigned int maxlen) return i; } static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev) { unsigned n = 0; char c; ssize_t i = 0; int len; pkt_dev->nr_labels = 0; do { __u32 tmp; len = hex32_arg(&buffer[i], &tmp); if (len <= 0) return len; pkt_dev->labels[n] = htonl(tmp); if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM) pkt_dev->flags |= F_MPLS_RND; i += len; if (get_user(c, &buffer[i])) return -EFAULT; i++; n++; if (n >= MAX_MPLS_LABELS) return -E2BIG; } while(c == ','); pkt_dev->nr_labels = n; return i; } static ssize_t pktgen_if_write(struct file *file, const char __user * user_buffer, size_t count, loff_t * offset) Loading Loading @@ -1059,6 +1134,12 @@ static ssize_t pktgen_if_write(struct file *file, else if (strcmp(f, "!MACDST_RND") == 0) pkt_dev->flags &= ~F_MACDST_RND; else if (strcmp(f, "MPLS_RND") == 0) pkt_dev->flags |= F_MPLS_RND; else if (strcmp(f, "!MPLS_RND") == 0) pkt_dev->flags &= ~F_MPLS_RND; else { sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", Loading Loading @@ -1354,6 +1435,19 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "mpls")) { unsigned n, offset; len = get_labels(&user_buffer[i], pkt_dev); if (len < 0) { return len; } i += len; offset = sprintf(pg_result, "OK: mpls="); for(n = 0; n < pkt_dev->nr_labels; n++) offset += sprintf(pg_result + offset, "%08x%s", ntohl(pkt_dev->labels[n]), n == pkt_dev->nr_labels-1 ? "" : ","); return count; } sprintf(pkt_dev->result, "No such parameter \"%s\"", name); return -EINVAL; } Loading Loading @@ -1846,6 +1940,15 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) pkt_dev->hh[1] = tmp; } if (pkt_dev->flags & F_MPLS_RND) { unsigned i; for(i = 0; i < pkt_dev->nr_labels; i++) if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) pkt_dev->labels[i] = MPLS_STACK_BOTTOM | (pktgen_random() & htonl(0x000fffff)); } if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { if (pkt_dev->flags & F_UDPSRC_RND) pkt_dev->cur_udp_src = Loading Loading @@ -1968,6 +2071,16 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) pkt_dev->flows[flow].count++; } static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) { unsigned i; for(i = 0; i < pkt_dev->nr_labels; i++) { *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; } mpls--; *mpls |= MPLS_STACK_BOTTOM; } static struct sk_buff *fill_packet_ipv4(struct net_device *odev, struct pktgen_dev *pkt_dev) { Loading @@ -1977,6 +2090,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, int datalen, iplen; struct iphdr *iph; struct pktgen_hdr *pgh = NULL; __be16 protocol = __constant_htons(ETH_P_IP); __be32 *mpls; if (pkt_dev->nr_labels) protocol = __constant_htons(ETH_P_MPLS_UC); /* Update any of the values, used when we're incrementing various * fields. Loading @@ -1984,7 +2102,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, mod_cur_headers(pkt_dev); datalen = (odev->hard_header_len + 16) & ~0xf; skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen + pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); if (!skb) { sprintf(pkt_dev->result, "No memory"); return NULL; Loading @@ -1994,13 +2113,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, /* Reserve for ethernet and IP header */ eth = (__u8 *) skb_push(skb, 14); mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); if (pkt_dev->nr_labels) mpls_push(mpls, pkt_dev); iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); memcpy(eth, pkt_dev->hh, 12); *(u16 *) & eth[12] = __constant_htons(ETH_P_IP); *(u16 *) & eth[12] = protocol; datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */ /* Eth + IPh + UDPh + mpls */ datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - pkt_dev->nr_labels*sizeof(u32); if (datalen < sizeof(struct pktgen_hdr)) datalen = sizeof(struct pktgen_hdr); Loading @@ -2021,8 +2145,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, iph->tot_len = htons(iplen); iph->check = 0; iph->check = ip_fast_csum((void *)iph, iph->ihl); skb->protocol = __constant_htons(ETH_P_IP); skb->mac.raw = ((u8 *) iph) - 14; skb->protocol = protocol; skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->dev = odev; skb->pkt_type = PACKET_HOST; Loading Loading @@ -2274,13 +2398,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, int datalen; struct ipv6hdr *iph; struct pktgen_hdr *pgh = NULL; __be16 protocol = __constant_htons(ETH_P_IPV6); __be32 *mpls; if (pkt_dev->nr_labels) protocol = __constant_htons(ETH_P_MPLS_UC); /* Update any of the values, used when we're incrementing various * fields. */ mod_cur_headers(pkt_dev); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 + pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); if (!skb) { sprintf(pkt_dev->result, "No memory"); return NULL; Loading @@ -2290,13 +2420,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, /* Reserve for ethernet and IP header */ eth = (__u8 *) skb_push(skb, 14); mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); if (pkt_dev->nr_labels) mpls_push(mpls, pkt_dev); iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); memcpy(eth, pkt_dev->hh, 12); *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6); datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr); /* Eth + IPh + UDPh */ /* Eth + IPh + UDPh + mpls */ datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr) - pkt_dev->nr_labels*sizeof(u32); if (datalen < sizeof(struct pktgen_hdr)) { datalen = sizeof(struct pktgen_hdr); Loading @@ -2320,8 +2456,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr); ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); skb->mac.raw = ((u8 *) iph) - 14; skb->protocol = __constant_htons(ETH_P_IPV6); skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->protocol = protocol; skb->dev = odev; skb->pkt_type = PACKET_HOST; Loading Loading
Documentation/networking/pktgen.txt +19 −1 Original line number Diff line number Diff line Loading @@ -109,6 +109,22 @@ Examples: cycle through the port range. pgset "udp_dst_max 9" set UDP destination port max. pgset "mpls 0001000a,0002000a,0000000a" set MPLS labels (in this example outer label=16,middle label=32, inner label=0 (IPv4 NULL)) Note that there must be no spaces between the arguments. Leading zeros are required. Do not set the bottom of stack bit, thats done automatically. If you do set the bottom of stack bit, that indicates that you want to randomly generate that address and the flag MPLS_RND will be turned on. You can have any mix of random and fixed labels in the label stack. pgset "mpls 0" turn off mpls (or any invalid argument works too!) pgset stop aborts injection. Also, ^C aborts generator. Loading Loading @@ -167,6 +183,8 @@ pkt_size min_pkt_size max_pkt_size mpls udp_src_min udp_src_max Loading
net/core/pktgen.c +147 −11 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ * * interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <nacc@us.ibm.com> * 050103 * * MPLS support by Steven Whitehouse <steve@chygwyn.com> * */ #include <linux/sys.h> #include <linux/types.h> Loading Loading @@ -154,7 +157,7 @@ #include <asm/div64.h> /* do_div */ #include <asm/timex.h> #define VERSION "pktgen v2.66: Packet Generator for packet performance testing.\n" #define VERSION "pktgen v2.67: Packet Generator for packet performance testing.\n" /* #define PG_DEBUG(a) a */ #define PG_DEBUG(a) Loading @@ -162,6 +165,8 @@ /* The buckets are exponential in 'width' */ #define LAT_BUCKETS_MAX 32 #define IP_NAME_SZ 32 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ #define MPLS_STACK_BOTTOM __constant_htonl(0x00000100) /* Device flag bits */ #define F_IPSRC_RND (1<<0) /* IP-Src Random */ Loading @@ -172,6 +177,7 @@ #define F_MACDST_RND (1<<5) /* MAC-Dst Random */ #define F_TXSIZE_RND (1<<6) /* Transmit size is random */ #define F_IPV6 (1<<7) /* Interface in IPV6 Mode */ #define F_MPLS_RND (1<<8) /* Random MPLS labels */ /* Thread control flag bits */ #define T_TERMINATE (1<<0) Loading Loading @@ -278,6 +284,10 @@ struct pktgen_dev { __u16 udp_dst_min; /* inclusive, dest UDP port */ __u16 udp_dst_max; /* exclusive, dest UDP port */ /* MPLS */ unsigned nr_labels; /* Depth of stack, 0 = no MPLS */ __be32 labels[MAX_MPLS_LABELS]; __u32 src_mac_count; /* How many MACs to iterate through */ __u32 dst_mac_count; /* How many MACs to iterate through */ Loading Loading @@ -623,9 +633,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v) pkt_dev->udp_dst_min, pkt_dev->udp_dst_max); seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ", " src_mac_count: %d dst_mac_count: %d\n", pkt_dev->src_mac_count, pkt_dev->dst_mac_count); if (pkt_dev->nr_labels) { unsigned i; seq_printf(seq, " mpls: "); for(i = 0; i < pkt_dev->nr_labels; i++) seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]), i == pkt_dev->nr_labels-1 ? "\n" : ", "); } seq_printf(seq, " Flags: "); if (pkt_dev->flags & F_IPV6) seq_printf(seq, "IPV6 "); Loading @@ -644,6 +664,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v) if (pkt_dev->flags & F_UDPDST_RND) seq_printf(seq, "UDPDST_RND "); if (pkt_dev->flags & F_MPLS_RND) seq_printf(seq, "MPLS_RND "); if (pkt_dev->flags & F_MACSRC_RND) seq_printf(seq, "MACSRC_RND "); Loading Loading @@ -691,6 +714,29 @@ static int pktgen_if_show(struct seq_file *seq, void *v) return 0; } static int hex32_arg(const char __user *user_buffer, __u32 *num) { int i = 0; *num = 0; for(; i < 8; i++) { char c; *num <<= 4; if (get_user(c, &user_buffer[i])) return -EFAULT; if ((c >= '0') && (c <= '9')) *num |= c - '0'; else if ((c >= 'a') && (c <= 'f')) *num |= c - 'a' + 10; else if ((c >= 'A') && (c <= 'F')) *num |= c - 'A' + 10; else break; } return i; } static int count_trail_chars(const char __user * user_buffer, unsigned int maxlen) { Loading Loading @@ -759,6 +805,35 @@ static int strn_len(const char __user * user_buffer, unsigned int maxlen) return i; } static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev) { unsigned n = 0; char c; ssize_t i = 0; int len; pkt_dev->nr_labels = 0; do { __u32 tmp; len = hex32_arg(&buffer[i], &tmp); if (len <= 0) return len; pkt_dev->labels[n] = htonl(tmp); if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM) pkt_dev->flags |= F_MPLS_RND; i += len; if (get_user(c, &buffer[i])) return -EFAULT; i++; n++; if (n >= MAX_MPLS_LABELS) return -E2BIG; } while(c == ','); pkt_dev->nr_labels = n; return i; } static ssize_t pktgen_if_write(struct file *file, const char __user * user_buffer, size_t count, loff_t * offset) Loading Loading @@ -1059,6 +1134,12 @@ static ssize_t pktgen_if_write(struct file *file, else if (strcmp(f, "!MACDST_RND") == 0) pkt_dev->flags &= ~F_MACDST_RND; else if (strcmp(f, "MPLS_RND") == 0) pkt_dev->flags |= F_MPLS_RND; else if (strcmp(f, "!MPLS_RND") == 0) pkt_dev->flags &= ~F_MPLS_RND; else { sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", Loading Loading @@ -1354,6 +1435,19 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "mpls")) { unsigned n, offset; len = get_labels(&user_buffer[i], pkt_dev); if (len < 0) { return len; } i += len; offset = sprintf(pg_result, "OK: mpls="); for(n = 0; n < pkt_dev->nr_labels; n++) offset += sprintf(pg_result + offset, "%08x%s", ntohl(pkt_dev->labels[n]), n == pkt_dev->nr_labels-1 ? "" : ","); return count; } sprintf(pkt_dev->result, "No such parameter \"%s\"", name); return -EINVAL; } Loading Loading @@ -1846,6 +1940,15 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) pkt_dev->hh[1] = tmp; } if (pkt_dev->flags & F_MPLS_RND) { unsigned i; for(i = 0; i < pkt_dev->nr_labels; i++) if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) pkt_dev->labels[i] = MPLS_STACK_BOTTOM | (pktgen_random() & htonl(0x000fffff)); } if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) { if (pkt_dev->flags & F_UDPSRC_RND) pkt_dev->cur_udp_src = Loading Loading @@ -1968,6 +2071,16 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) pkt_dev->flows[flow].count++; } static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) { unsigned i; for(i = 0; i < pkt_dev->nr_labels; i++) { *mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM; } mpls--; *mpls |= MPLS_STACK_BOTTOM; } static struct sk_buff *fill_packet_ipv4(struct net_device *odev, struct pktgen_dev *pkt_dev) { Loading @@ -1977,6 +2090,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, int datalen, iplen; struct iphdr *iph; struct pktgen_hdr *pgh = NULL; __be16 protocol = __constant_htons(ETH_P_IP); __be32 *mpls; if (pkt_dev->nr_labels) protocol = __constant_htons(ETH_P_MPLS_UC); /* Update any of the values, used when we're incrementing various * fields. Loading @@ -1984,7 +2102,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, mod_cur_headers(pkt_dev); datalen = (odev->hard_header_len + 16) & ~0xf; skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen + pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); if (!skb) { sprintf(pkt_dev->result, "No memory"); return NULL; Loading @@ -1994,13 +2113,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, /* Reserve for ethernet and IP header */ eth = (__u8 *) skb_push(skb, 14); mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); if (pkt_dev->nr_labels) mpls_push(mpls, pkt_dev); iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); memcpy(eth, pkt_dev->hh, 12); *(u16 *) & eth[12] = __constant_htons(ETH_P_IP); *(u16 *) & eth[12] = protocol; datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */ /* Eth + IPh + UDPh + mpls */ datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - pkt_dev->nr_labels*sizeof(u32); if (datalen < sizeof(struct pktgen_hdr)) datalen = sizeof(struct pktgen_hdr); Loading @@ -2021,8 +2145,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, iph->tot_len = htons(iplen); iph->check = 0; iph->check = ip_fast_csum((void *)iph, iph->ihl); skb->protocol = __constant_htons(ETH_P_IP); skb->mac.raw = ((u8 *) iph) - 14; skb->protocol = protocol; skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->dev = odev; skb->pkt_type = PACKET_HOST; Loading Loading @@ -2274,13 +2398,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, int datalen; struct ipv6hdr *iph; struct pktgen_hdr *pgh = NULL; __be16 protocol = __constant_htons(ETH_P_IPV6); __be32 *mpls; if (pkt_dev->nr_labels) protocol = __constant_htons(ETH_P_MPLS_UC); /* Update any of the values, used when we're incrementing various * fields. */ mod_cur_headers(pkt_dev); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 + pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC); if (!skb) { sprintf(pkt_dev->result, "No memory"); return NULL; Loading @@ -2290,13 +2420,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, /* Reserve for ethernet and IP header */ eth = (__u8 *) skb_push(skb, 14); mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32)); if (pkt_dev->nr_labels) mpls_push(mpls, pkt_dev); iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); memcpy(eth, pkt_dev->hh, 12); *(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6); datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr); /* Eth + IPh + UDPh */ /* Eth + IPh + UDPh + mpls */ datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr) - pkt_dev->nr_labels*sizeof(u32); if (datalen < sizeof(struct pktgen_hdr)) { datalen = sizeof(struct pktgen_hdr); Loading @@ -2320,8 +2456,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr); ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); skb->mac.raw = ((u8 *) iph) - 14; skb->protocol = __constant_htons(ETH_P_IPV6); skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->protocol = protocol; skb->dev = odev; skb->pkt_type = PACKET_HOST; Loading