Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Woodhouse and committed by
David S. Miller
d3869efe 2d8bff12

+17 -15
+17 -15
net/packet/af_packet.c
··· 230 230 } sa; 231 231 }; 232 232 233 + #define vio_le() virtio_legacy_is_little_endian() 234 + 233 235 #define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) 234 236 235 237 #define GET_PBDQC_FROM_RB(x) ((struct tpacket_kbdq_core *)(&(x)->prb_bdqc)) ··· 2682 2680 goto out_unlock; 2683 2681 2684 2682 if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && 2685 - (__virtio16_to_cpu(false, vnet_hdr.csum_start) + 2686 - __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 > 2687 - __virtio16_to_cpu(false, vnet_hdr.hdr_len))) 2688 - vnet_hdr.hdr_len = __cpu_to_virtio16(false, 2689 - __virtio16_to_cpu(false, vnet_hdr.csum_start) + 2690 - __virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2); 2683 + (__virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) + 2684 + __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2 > 2685 + __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len))) 2686 + vnet_hdr.hdr_len = __cpu_to_virtio16(vio_le(), 2687 + __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) + 2688 + __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2); 2691 2689 2692 2690 err = -EINVAL; 2693 - if (__virtio16_to_cpu(false, vnet_hdr.hdr_len) > len) 2691 + if (__virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len) > len) 2694 2692 goto out_unlock; 2695 2693 2696 2694 if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) { ··· 2733 2731 hlen = LL_RESERVED_SPACE(dev); 2734 2732 tlen = dev->needed_tailroom; 2735 2733 skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, 2736 - __virtio16_to_cpu(false, vnet_hdr.hdr_len), 2734 + __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len), 2737 2735 msg->msg_flags & MSG_DONTWAIT, &err); 2738 2736 if (skb == NULL) 2739 2737 goto out_unlock; ··· 2780 2778 2781 2779 if (po->has_vnet_hdr) { 2782 2780 if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { 2783 - u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start); 2784 - u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset); 2781 + u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start); 2782 + u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset); 2785 2783 if (!skb_partial_csum_set(skb, s, o)) { 2786 2784 err = -EINVAL; 2787 2785 goto out_free; ··· 2789 2787 } 2790 2788 2791 2789 skb_shinfo(skb)->gso_size = 2792 - __virtio16_to_cpu(false, vnet_hdr.gso_size); 2790 + __virtio16_to_cpu(vio_le(), vnet_hdr.gso_size); 2793 2791 skb_shinfo(skb)->gso_type = gso_type; 2794 2792 2795 2793 /* Header must be checked, and gso_segs computed. */ ··· 3163 3161 3164 3162 /* This is a hint as to how much should be linear. */ 3165 3163 vnet_hdr.hdr_len = 3166 - __cpu_to_virtio16(false, skb_headlen(skb)); 3164 + __cpu_to_virtio16(vio_le(), skb_headlen(skb)); 3167 3165 vnet_hdr.gso_size = 3168 - __cpu_to_virtio16(false, sinfo->gso_size); 3166 + __cpu_to_virtio16(vio_le(), sinfo->gso_size); 3169 3167 if (sinfo->gso_type & SKB_GSO_TCPV4) 3170 3168 vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 3171 3169 else if (sinfo->gso_type & SKB_GSO_TCPV6) ··· 3183 3181 3184 3182 if (skb->ip_summed == CHECKSUM_PARTIAL) { 3185 3183 vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; 3186 - vnet_hdr.csum_start = __cpu_to_virtio16(false, 3184 + vnet_hdr.csum_start = __cpu_to_virtio16(vio_le(), 3187 3185 skb_checksum_start_offset(skb)); 3188 - vnet_hdr.csum_offset = __cpu_to_virtio16(false, 3186 + vnet_hdr.csum_offset = __cpu_to_virtio16(vio_le(), 3189 3187 skb->csum_offset); 3190 3188 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 3191 3189 vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;