Skip to content

Commit

Permalink
Merge branch 'udp-pull'
Browse files Browse the repository at this point in the history
Willem de Bruijn says:

====================
net: fix udp pull header breakage

Commit e6afc8a ("udp: remove headers from UDP packets before
queueing") modified udp receive processing to pull headers before
enqueue and to not expect them on dequeue.

The patch missed protocols on top of udp with in-kernel
implementations that have their own skb_recv_datagram calls and
dequeue logic. Modify these datapaths to also no longer expect
a udp header at skb->data.

Sunrpc and rxrpc are the only two protocols that call this
function and contain references to udphr (some others, like tipc,
are based on encap_rcv, which acts before enqueue, before the
the header pull).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 11, 2016
2 parents a6db449 + 4d0fc73 commit c64a73d
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 9 deletions.
4 changes: 2 additions & 2 deletions net/rxrpc/ar-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,9 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
struct rxrpc_wire_header whdr;

/* dig out the RxRPC connection details */
if (skb_copy_bits(skb, sizeof(struct udphdr), &whdr, sizeof(whdr)) < 0)
if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0)
return -EBADMSG;
if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(whdr)))
if (!pskb_pull(skb, sizeof(whdr)))
BUG();

memset(sp, 0, sizeof(*sp));
Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/socklib.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
struct xdr_skb_reader desc;

desc.skb = skb;
desc.offset = sizeof(struct udphdr);
desc.offset = 0;
desc.count = skb->len - desc.offset;

if (skb_csum_unnecessary(skb))
Expand Down
5 changes: 2 additions & 3 deletions net/sunrpc/svcsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
svsk->sk_sk->sk_stamp = skb->tstamp;
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */

len = skb->len - sizeof(struct udphdr);
len = skb->len;
rqstp->rq_arg.len = len;

rqstp->rq_prot = IPPROTO_UDP;
Expand All @@ -641,8 +641,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
skb_free_datagram_locked(svsk->sk_sk, skb);
} else {
/* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data +
sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_base = skb->data;
rqstp->rq_arg.head[0].iov_len = len;
if (skb_checksum_complete(skb))
goto out_free;
Expand Down
5 changes: 2 additions & 3 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -995,15 +995,14 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt,
u32 _xid;
__be32 *xp;

repsize = skb->len - sizeof(struct udphdr);
repsize = skb->len;
if (repsize < 4) {
dprintk("RPC: impossible RPC reply size %d!\n", repsize);
return;
}

/* Copy the XID from the skb... */
xp = skb_header_pointer(skb, sizeof(struct udphdr),
sizeof(_xid), &_xid);
xp = skb_header_pointer(skb, 0, sizeof(_xid), &_xid);
if (xp == NULL)
return;

Expand Down

0 comments on commit c64a73d

Please sign in to comment.