aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/datagram.c1
-rw-r--r--net/ipv4/udp.c5
-rw-r--r--net/ipv6/udp.c8
-rw-r--r--net/sunrpc/svcsock.c12
4 files changed, 15 insertions, 11 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c
index ae6acf6a3dea..0337e2b76862 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -248,7 +248,6 @@ void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
248 unlock_sock_fast(sk, slow); 248 unlock_sock_fast(sk, slow);
249 249
250 /* skb is now orphaned, can be freed outside of locked section */ 250 /* skb is now orphaned, can be freed outside of locked section */
251 trace_kfree_skb(skb, skb_free_datagram_locked);
252 __kfree_skb(skb); 251 __kfree_skb(skb);
253} 252}
254EXPORT_SYMBOL(skb_free_datagram_locked); 253EXPORT_SYMBOL(skb_free_datagram_locked);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index db017efb76ea..ee37d47d472e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -108,6 +108,7 @@
108#include <net/xfrm.h> 108#include <net/xfrm.h>
109#include <trace/events/udp.h> 109#include <trace/events/udp.h>
110#include <linux/static_key.h> 110#include <linux/static_key.h>
111#include <trace/events/skb.h>
111#include "udp_impl.h" 112#include "udp_impl.h"
112 113
113struct udp_table udp_table __read_mostly; 114struct udp_table udp_table __read_mostly;
@@ -1220,8 +1221,10 @@ try_again:
1220 goto csum_copy_err; 1221 goto csum_copy_err;
1221 } 1222 }
1222 1223
1223 if (err) 1224 if (unlikely(err)) {
1225 trace_kfree_skb(skb, udp_recvmsg);
1224 goto out_free; 1226 goto out_free;
1227 }
1225 1228
1226 if (!peeked) 1229 if (!peeked)
1227 UDP_INC_STATS_USER(sock_net(sk), 1230 UDP_INC_STATS_USER(sock_net(sk),
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 051ad481973f..1ecd10249488 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -48,6 +48,7 @@
48 48
49#include <linux/proc_fs.h> 49#include <linux/proc_fs.h>
50#include <linux/seq_file.h> 50#include <linux/seq_file.h>
51#include <trace/events/skb.h>
51#include "udp_impl.h" 52#include "udp_impl.h"
52 53
53int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) 54int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
@@ -385,15 +386,16 @@ try_again:
385 386
386 if (skb_csum_unnecessary(skb)) 387 if (skb_csum_unnecessary(skb))
387 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), 388 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
388 msg->msg_iov, copied ); 389 msg->msg_iov, copied);
389 else { 390 else {
390 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 391 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
391 if (err == -EINVAL) 392 if (err == -EINVAL)
392 goto csum_copy_err; 393 goto csum_copy_err;
393 } 394 }
394 if (err) 395 if (unlikely(err)) {
396 trace_kfree_skb(skb, udpv6_recvmsg);
395 goto out_free; 397 goto out_free;
396 398 }
397 if (!peeked) { 399 if (!peeked) {
398 if (is_udp4) 400 if (is_udp4)
399 UDP_INC_STATS_USER(sock_net(sk), 401 UDP_INC_STATS_USER(sock_net(sk),
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index a6de09de5d21..18bc130255a7 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -43,6 +43,7 @@
43#include <net/tcp_states.h> 43#include <net/tcp_states.h>
44#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <asm/ioctls.h> 45#include <asm/ioctls.h>
46#include <trace/events/skb.h>
46 47
47#include <linux/sunrpc/types.h> 48#include <linux/sunrpc/types.h>
48#include <linux/sunrpc/clnt.h> 49#include <linux/sunrpc/clnt.h>
@@ -619,6 +620,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
619 if (!svc_udp_get_dest_address(rqstp, cmh)) { 620 if (!svc_udp_get_dest_address(rqstp, cmh)) {
620 net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n", 621 net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
621 cmh->cmsg_level, cmh->cmsg_type); 622 cmh->cmsg_level, cmh->cmsg_type);
623out_free:
624 trace_kfree_skb(skb, svc_udp_recvfrom);
622 skb_free_datagram_locked(svsk->sk_sk, skb); 625 skb_free_datagram_locked(svsk->sk_sk, skb);
623 return 0; 626 return 0;
624 } 627 }
@@ -630,8 +633,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
630 if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { 633 if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) {
631 local_bh_enable(); 634 local_bh_enable();
632 /* checksum error */ 635 /* checksum error */
633 skb_free_datagram_locked(svsk->sk_sk, skb); 636 goto out_free;
634 return 0;
635 } 637 }
636 local_bh_enable(); 638 local_bh_enable();
637 skb_free_datagram_locked(svsk->sk_sk, skb); 639 skb_free_datagram_locked(svsk->sk_sk, skb);
@@ -640,10 +642,8 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
640 rqstp->rq_arg.head[0].iov_base = skb->data + 642 rqstp->rq_arg.head[0].iov_base = skb->data +
641 sizeof(struct udphdr); 643 sizeof(struct udphdr);
642 rqstp->rq_arg.head[0].iov_len = len; 644 rqstp->rq_arg.head[0].iov_len = len;
643 if (skb_checksum_complete(skb)) { 645 if (skb_checksum_complete(skb))
644 skb_free_datagram_locked(svsk->sk_sk, skb); 646 goto out_free;
645 return 0;
646 }
647 rqstp->rq_xprt_ctxt = skb; 647 rqstp->rq_xprt_ctxt = skb;
648 } 648 }
649 649