diff options
author | Thomas Graf <tgraf@suug.ch> | 2013-06-03 07:49:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-04 20:35:45 -0400 |
commit | 525cebedb32a87fa48584bc44e14170beb2c10d1 (patch) | |
tree | 17a3e08c3768f02e8dd59ad0583c2bba17c4d4db /net/core | |
parent | 10e179e364beafc23d837e81cf98d99720f42551 (diff) |
pktgen: Fix position of ip and udp header
skb_set_network_header() expects an offset based on the data pointer
whereas skb_tail_offset() also includes the headroom. This resulted
in the ip header being written in a wrong location.
Use return values of skb_put() directly and rely on skb->len to
set mac, network, and transport header.
Cc: Simon Horman <horms@verge.net.au>
Cc: Daniel Borkmann <dborkmann@redhat.com>
Assisted-by: Daniel Borkmann <dborkmann@redhat.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Daniel Borkmann <dborkmann@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/pktgen.c | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index d2ede89662be..303412d8332b 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -2642,7 +2642,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2642 | __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */ | 2642 | __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */ |
2643 | __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */ | 2643 | __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */ |
2644 | u16 queue_map; | 2644 | u16 queue_map; |
2645 | unsigned long tail_offset; | ||
2646 | 2645 | ||
2647 | if (pkt_dev->nr_labels) | 2646 | if (pkt_dev->nr_labels) |
2648 | protocol = htons(ETH_P_MPLS_UC); | 2647 | protocol = htons(ETH_P_MPLS_UC); |
@@ -2709,20 +2708,15 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2709 | *vlan_encapsulated_proto = htons(ETH_P_IP); | 2708 | *vlan_encapsulated_proto = htons(ETH_P_IP); |
2710 | } | 2709 | } |
2711 | 2710 | ||
2712 | tail_offset = skb_tail_offset(skb); | 2711 | skb_set_mac_header(skb, 0); |
2713 | if (tail_offset > 0xffff) { | 2712 | skb_set_network_header(skb, skb->len); |
2714 | kfree_skb(skb); | 2713 | iph = (struct iphdr *) skb_put(skb, sizeof(struct iphdr)); |
2715 | return NULL; | 2714 | |
2716 | } | 2715 | skb_set_transport_header(skb, skb->len); |
2717 | skb_set_network_header(skb, tail_offset); | 2716 | udph = (struct udphdr *) skb_put(skb, sizeof(struct udphdr)); |
2718 | skb->transport_header = skb->network_header + sizeof(struct iphdr); | ||
2719 | skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr)); | ||
2720 | skb_set_queue_mapping(skb, queue_map); | 2717 | skb_set_queue_mapping(skb, queue_map); |
2721 | skb->priority = pkt_dev->skb_priority; | 2718 | skb->priority = pkt_dev->skb_priority; |
2722 | 2719 | ||
2723 | iph = ip_hdr(skb); | ||
2724 | udph = udp_hdr(skb); | ||
2725 | |||
2726 | memcpy(eth, pkt_dev->hh, 12); | 2720 | memcpy(eth, pkt_dev->hh, 12); |
2727 | *(__be16 *) & eth[12] = protocol; | 2721 | *(__be16 *) & eth[12] = protocol; |
2728 | 2722 | ||
@@ -2752,8 +2746,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2752 | iph->check = 0; | 2746 | iph->check = 0; |
2753 | iph->check = ip_fast_csum((void *)iph, iph->ihl); | 2747 | iph->check = ip_fast_csum((void *)iph, iph->ihl); |
2754 | skb->protocol = protocol; | 2748 | skb->protocol = protocol; |
2755 | skb->mac_header = (skb->network_header - ETH_HLEN - | ||
2756 | pkt_dev->pkt_overhead); | ||
2757 | skb->dev = odev; | 2749 | skb->dev = odev; |
2758 | skb->pkt_type = PACKET_HOST; | 2750 | skb->pkt_type = PACKET_HOST; |
2759 | pktgen_finalize_skb(pkt_dev, skb, datalen); | 2751 | pktgen_finalize_skb(pkt_dev, skb, datalen); |
@@ -2781,7 +2773,6 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2781 | __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */ | 2773 | __be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */ |
2782 | __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */ | 2774 | __be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */ |
2783 | u16 queue_map; | 2775 | u16 queue_map; |
2784 | unsigned long tail_offset; | ||
2785 | 2776 | ||
2786 | if (pkt_dev->nr_labels) | 2777 | if (pkt_dev->nr_labels) |
2787 | protocol = htons(ETH_P_MPLS_UC); | 2778 | protocol = htons(ETH_P_MPLS_UC); |
@@ -2829,18 +2820,14 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2829 | *vlan_encapsulated_proto = htons(ETH_P_IPV6); | 2820 | *vlan_encapsulated_proto = htons(ETH_P_IPV6); |
2830 | } | 2821 | } |
2831 | 2822 | ||
2832 | tail_offset = skb_tail_offset(skb); | 2823 | skb_set_mac_header(skb, 0); |
2833 | if (tail_offset > 0xffff) { | 2824 | skb_set_network_header(skb, skb->len); |
2834 | kfree_skb(skb); | 2825 | iph = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); |
2835 | return NULL; | 2826 | |
2836 | } | 2827 | skb_set_transport_header(skb, skb->len); |
2837 | skb_set_network_header(skb, tail_offset); | 2828 | udph = (struct udphdr *) skb_put(skb, sizeof(struct udphdr)); |
2838 | skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); | ||
2839 | skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr)); | ||
2840 | skb_set_queue_mapping(skb, queue_map); | 2829 | skb_set_queue_mapping(skb, queue_map); |
2841 | skb->priority = pkt_dev->skb_priority; | 2830 | skb->priority = pkt_dev->skb_priority; |
2842 | iph = ipv6_hdr(skb); | ||
2843 | udph = udp_hdr(skb); | ||
2844 | 2831 | ||
2845 | memcpy(eth, pkt_dev->hh, 12); | 2832 | memcpy(eth, pkt_dev->hh, 12); |
2846 | *(__be16 *) ð[12] = protocol; | 2833 | *(__be16 *) ð[12] = protocol; |
@@ -2875,8 +2862,6 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2875 | iph->daddr = pkt_dev->cur_in6_daddr; | 2862 | iph->daddr = pkt_dev->cur_in6_daddr; |
2876 | iph->saddr = pkt_dev->cur_in6_saddr; | 2863 | iph->saddr = pkt_dev->cur_in6_saddr; |
2877 | 2864 | ||
2878 | skb->mac_header = (skb->network_header - ETH_HLEN - | ||
2879 | pkt_dev->pkt_overhead); | ||
2880 | skb->protocol = protocol; | 2865 | skb->protocol = protocol; |
2881 | skb->dev = odev; | 2866 | skb->dev = odev; |
2882 | skb->pkt_type = PACKET_HOST; | 2867 | skb->pkt_type = PACKET_HOST; |