Skip to content

Commit d3869ef

Browse files
dwmw2davem330
authored andcommitted
Fix AF_PACKET ABI breakage in 4.2
Commit 7d82410 ("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>
1 parent 2d8bff1 commit d3869ef

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

net/packet/af_packet.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ struct packet_skb_cb {
230230
} sa;
231231
};
232232

233+
#define vio_le() virtio_legacy_is_little_endian()
234+
233235
#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
234236

235237
#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)
26802682
goto out_unlock;
26812683

26822684
if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
2683-
(__virtio16_to_cpu(false, vnet_hdr.csum_start) +
2684-
__virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2 >
2685-
__virtio16_to_cpu(false, vnet_hdr.hdr_len)))
2686-
vnet_hdr.hdr_len = __cpu_to_virtio16(false,
2687-
__virtio16_to_cpu(false, vnet_hdr.csum_start) +
2688-
__virtio16_to_cpu(false, vnet_hdr.csum_offset) + 2);
2685+
(__virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) +
2686+
__virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2 >
2687+
__virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len)))
2688+
vnet_hdr.hdr_len = __cpu_to_virtio16(vio_le(),
2689+
__virtio16_to_cpu(vio_le(), vnet_hdr.csum_start) +
2690+
__virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset) + 2);
26892691

26902692
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)
26922694
goto out_unlock;
26932695

26942696
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)
27312733
hlen = LL_RESERVED_SPACE(dev);
27322734
tlen = dev->needed_tailroom;
27332735
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),
27352737
msg->msg_flags & MSG_DONTWAIT, &err);
27362738
if (skb == NULL)
27372739
goto out_unlock;
@@ -2778,16 +2780,16 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
27782780

27792781
if (po->has_vnet_hdr) {
27802782
if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
2781-
u16 s = __virtio16_to_cpu(false, vnet_hdr.csum_start);
2782-
u16 o = __virtio16_to_cpu(false, vnet_hdr.csum_offset);
2783+
u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start);
2784+
u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset);
27832785
if (!skb_partial_csum_set(skb, s, o)) {
27842786
err = -EINVAL;
27852787
goto out_free;
27862788
}
27872789
}
27882790

27892791
skb_shinfo(skb)->gso_size =
2790-
__virtio16_to_cpu(false, vnet_hdr.gso_size);
2792+
__virtio16_to_cpu(vio_le(), vnet_hdr.gso_size);
27912793
skb_shinfo(skb)->gso_type = gso_type;
27922794

27932795
/* 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,
31613163

31623164
/* This is a hint as to how much should be linear. */
31633165
vnet_hdr.hdr_len =
3164-
__cpu_to_virtio16(false, skb_headlen(skb));
3166+
__cpu_to_virtio16(vio_le(), skb_headlen(skb));
31653167
vnet_hdr.gso_size =
3166-
__cpu_to_virtio16(false, sinfo->gso_size);
3168+
__cpu_to_virtio16(vio_le(), sinfo->gso_size);
31673169
if (sinfo->gso_type & SKB_GSO_TCPV4)
31683170
vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
31693171
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,
31813183

31823184
if (skb->ip_summed == CHECKSUM_PARTIAL) {
31833185
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(),
31853187
skb_checksum_start_offset(skb));
3186-
vnet_hdr.csum_offset = __cpu_to_virtio16(false,
3188+
vnet_hdr.csum_offset = __cpu_to_virtio16(vio_le(),
31873189
skb->csum_offset);
31883190
} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
31893191
vnet_hdr.flags = VIRTIO_NET_HDR_F_DATA_VALID;

0 commit comments

Comments
 (0)