diff options
author | David Woodhouse <dwmw2@infradead.org> | 2015-09-23 14:45:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-09-23 17:33:55 -0400 |
commit | d3869efe7a8a2298516d9af4f91487cf486ca945 (patch) | |
tree | 6559990f0366e38ca4355a05190e8ba9b1a39847 /net/packet | |
parent | 2d8bff12699abc3a9bf886bb0b79f44d94d81496 (diff) |
Fix AF_PACKET ABI breakage in 4.2
Commit 7d82410950aa ("virtio: add explicit big-endian support to memory
accessors") accidentally changed the virtio_net header used by
AF_PACKET with PACKET_VNET_HDR from host-endian to big-endian.
Since virtio_legacy_is_little_endian() is a very long identifier,
define a vio_le macro and use that throughout the code instead of the
hard-coded 'false' for little-endian.
This restores the ABI to match 4.1 and earlier kernels, and makes my
test program work again.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/af_packet.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 7b8e39a22387..aa4b15c35884 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -230,6 +230,8 @@ struct packet_skb_cb { | |||
230 | } sa; | 230 | } sa; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | #define vio_le() virtio_legacy_is_little_endian() | ||
234 | |||
233 | #define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) | 235 | #define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) |
234 | 236 | ||
235 | #define GET_PBDQC_FROM_RB(x) ((struct tpacket_kbdq_core *)(&(x)->prb_bdqc)) | 237 | #define GET_PBDQC_FROM_RB(x) ((struct tpacket_kbdq_core *)(&(x)->prb_bdqc)) |
@@ -2680,15 +2682,15 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2680 | goto out_unlock; | 2682 | goto out_unlock; |
2681 | 2683 | ||
2682 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | 2684 | if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && |
2683 | (__virtio16_to_cpu(false, vnet_hdr.csum_start) + | 2685 | (__virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) + |
2684 | __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 > | 2686 | __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2 > |
2685 | __virtio16_to_cpu(false, vnet_hdr.hdr_len))) | 2687 | __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len))) |
2686 | vnet_hdr.hdr_len = __cpu_to_virtio16(false, | 2688 | vnet_hdr.hdr_len = __cpu_to_virtio16(vio_le(), |
2687 | __virtio16_to_cpu(false, vnet_hdr.csum_start) + | 2689 | __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) + |
2688 | __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2); | 2690 | __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2); |
2689 | 2691 | ||
2690 | err = -EINVAL; | 2692 | err = -EINVAL; |
2691 | if (__virtio16_to_cpu(false, vnet_hdr.hdr_len) > len) | 2693 | if (__virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len) > len) |
2692 | goto out_unlock; | 2694 | goto out_unlock; |
2693 | 2695 | ||
2694 | if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 2696 | if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
@@ -2731,7 +2733,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2731 | hlen = LL_RESERVED_SPACE(dev); | 2733 | hlen = LL_RESERVED_SPACE(dev); |
2732 | tlen = dev->needed_tailroom; | 2734 | tlen = dev->needed_tailroom; |
2733 | skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, | 2735 | skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, |
2734 | __virtio16_to_cpu(false, vnet_hdr.hdr_len), | 2736 | __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len), |
2735 | msg->msg_flags & MSG_DONTWAIT, &err); | 2737 | msg->msg_flags & MSG_DONTWAIT, &err); |
2736 | if (skb == NULL) | 2738 | if (skb == NULL) |
2737 | goto out_unlock; | 2739 | goto out_unlock; |
@@ -2778,8 +2780,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2778 | 2780 | ||
2779 | if (po->has_vnet_hdr) { | 2781 | if (po->has_vnet_hdr) { |
2780 | if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { | 2782 | if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { |
2781 | u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start); | 2783 | u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start); |
2782 | u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset); | 2784 | u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset); |
2783 | if (!skb_partial_csum_set(skb, s, o)) { | 2785 | if (!skb_partial_csum_set(skb, s, o)) { |
2784 | err = -EINVAL; | 2786 | err = -EINVAL; |
2785 | goto out_free; | 2787 | goto out_free; |
@@ -2787,7 +2789,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2787 | } | 2789 | } |
2788 | 2790 | ||
2789 | skb_shinfo(skb)->gso_size = | 2791 | skb_shinfo(skb)->gso_size = |
2790 | __virtio16_to_cpu(false, vnet_hdr.gso_size); | 2792 | __virtio16_to_cpu(vio_le(), vnet_hdr.gso_size); |
2791 | skb_shinfo(skb)->gso_type = gso_type; | 2793 | skb_shinfo(skb)->gso_type = gso_type; |
2792 | 2794 | ||
2793 | /* Header must be checked, and gso_segs computed. */ | 2795 | /* Header must be checked, and gso_segs computed. */ |
@@ -3161,9 +3163,9 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
3161 | 3163 | ||
3162 | /* This is a hint as to how much should be linear. */ | 3164 | /* This is a hint as to how much should be linear. */ |
3163 | vnet_hdr.hdr_len = | 3165 | vnet_hdr.hdr_len = |
3164 | __cpu_to_virtio16(false, skb_headlen(skb)); | 3166 | __cpu_to_virtio16(vio_le(), skb_headlen(skb)); |
3165 | vnet_hdr.gso_size = | 3167 | vnet_hdr.gso_size = |
3166 | __cpu_to_virtio16(false, sinfo->gso_size); | 3168 | __cpu_to_virtio16(vio_le(), sinfo->gso_size); |
3167 | if (sinfo->gso_type & SKB_GSO_TCPV4) | 3169 | if (sinfo->gso_type & SKB_GSO_TCPV4) |
3168 | vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 3170 | vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
3169 | else if (sinfo->gso_type & SKB_GSO_TCPV6) | 3171 | else if (sinfo->gso_type & SKB_GSO_TCPV6) |
@@ -3181,9 +3183,9 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
3181 | 3183 | ||
3182 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 3184 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
3183 | vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; | 3185 | vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; |
3184 | vnet_hdr.csum_start = __cpu_to_virtio16(false, | 3186 | vnet_hdr.csum_start = __cpu_to_virtio16(vio_le(), |
3185 | skb_checksum_start_offset(skb)); | 3187 | skb_checksum_start_offset(skb)); |
3186 | vnet_hdr.csum_offset = __cpu_to_virtio16(false, | 3188 | vnet_hdr.csum_offset = __cpu_to_virtio16(vio_le(), |
3187 | skb->csum_offset); | 3189 | skb->csum_offset); |
3188 | } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { | 3190 | } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { |
3189 | vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; | 3191 | vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID; |