summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller2016-04-11 21:31:34 +0200
committerDavid S. Miller2016-04-11 21:31:34 +0200
commitc64a73d584cc344915baee1183c791c0d0c42d79 (patch)
treea36049a8905dbcbbd5e047e47d48682a1d9c7fef
parentnet: ipv4: Consider failed nexthops in multipath routes (diff)
parentrxrpc: do not pull udp headers on receive (diff)
downloadkernel-qcow2-linux-c64a73d584cc344915baee1183c791c0d0c42d79.tar.gz
kernel-qcow2-linux-c64a73d584cc344915baee1183c791c0d0c42d79.tar.xz
kernel-qcow2-linux-c64a73d584cc344915baee1183c791c0d0c42d79.zip
Merge branch 'udp-pull'
Willem de Bruijn says: ==================== net: fix udp pull header breakage Commit e6afc8ace6dd ("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>
-rw-r--r--net/rxrpc/ar-input.c4
-rw-r--r--net/sunrpc/socklib.c2
-rw-r--r--net/sunrpc/svcsock.c5
-rw-r--r--net/sunrpc/xprtsock.c5
4 files changed, 7 insertions, 9 deletions
diff --git a/net/rxrpc/ar-input.c b/net/rxrpc/ar-input.c
index 63ed75c40e29..4824a827d10d 100644
--- a/net/rxrpc/ar-input.c
+++ b/net/rxrpc/ar-input.c
@@ -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));
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index de70c78025d7..f217c348b341 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -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))
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 1413cdcc131c..71d6072664d2 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -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;
@@ -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;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 65e759569e48..c1fc7b20bbc1 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -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;