Commit c64a73d5 authored by David S. Miller's avatar David S. Miller

Merge branch 'udp-pull'

Willem de Bruijn says:

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

Commit e6afc8ac ("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: default avatarDavid S. Miller <davem@davemloft.net>
parents a6db4494 4d0fc73e
...@@ -612,9 +612,9 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb) ...@@ -612,9 +612,9 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
struct rxrpc_wire_header whdr; struct rxrpc_wire_header whdr;
/* dig out the RxRPC connection details */ /* 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; return -EBADMSG;
if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(whdr))) if (!pskb_pull(skb, sizeof(whdr)))
BUG(); BUG();
memset(sp, 0, sizeof(*sp)); memset(sp, 0, sizeof(*sp));
......
...@@ -155,7 +155,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) ...@@ -155,7 +155,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
struct xdr_skb_reader desc; struct xdr_skb_reader desc;
desc.skb = skb; desc.skb = skb;
desc.offset = sizeof(struct udphdr); desc.offset = 0;
desc.count = skb->len - desc.offset; desc.count = skb->len - desc.offset;
if (skb_csum_unnecessary(skb)) if (skb_csum_unnecessary(skb))
......
...@@ -617,7 +617,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -617,7 +617,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
svsk->sk_sk->sk_stamp = skb->tstamp; svsk->sk_sk->sk_stamp = skb->tstamp;
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ 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_arg.len = len;
rqstp->rq_prot = IPPROTO_UDP; rqstp->rq_prot = IPPROTO_UDP;
...@@ -641,8 +641,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) ...@@ -641,8 +641,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
skb_free_datagram_locked(svsk->sk_sk, skb); skb_free_datagram_locked(svsk->sk_sk, skb);
} else { } else {
/* we can use it in-place */ /* we can use it in-place */
rqstp->rq_arg.head[0].iov_base = skb->data + rqstp->rq_arg.head[0].iov_base = skb->data;
sizeof(struct udphdr);
rqstp->rq_arg.head[0].iov_len = len; rqstp->rq_arg.head[0].iov_len = len;
if (skb_checksum_complete(skb)) if (skb_checksum_complete(skb))
goto out_free; goto out_free;
......
...@@ -995,15 +995,14 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt, ...@@ -995,15 +995,14 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt,
u32 _xid; u32 _xid;
__be32 *xp; __be32 *xp;
repsize = skb->len - sizeof(struct udphdr); repsize = skb->len;
if (repsize < 4) { if (repsize < 4) {
dprintk("RPC: impossible RPC reply size %d!\n", repsize); dprintk("RPC: impossible RPC reply size %d!\n", repsize);
return; return;
} }
/* Copy the XID from the skb... */ /* Copy the XID from the skb... */
xp = skb_header_pointer(skb, sizeof(struct udphdr), xp = skb_header_pointer(skb, 0, sizeof(_xid), &_xid);
sizeof(_xid), &_xid);
if (xp == NULL) if (xp == NULL)
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment