aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/udp.h1
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/udp.c8
3 files changed, 16 insertions, 0 deletions
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 9d81de123c90..42278bbf7a88 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -68,6 +68,7 @@ struct udp_sock {
68 * For encapsulation sockets. 68 * For encapsulation sockets.
69 */ 69 */
70 int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); 70 int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
71 void (*encap_destroy)(struct sock *sk);
71}; 72};
72 73
73static inline struct udp_sock *udp_sk(const struct sock *sk) 74static inline struct udp_sock *udp_sk(const struct sock *sk)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 265c42cf963c..0a073a263720 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1762,9 +1762,16 @@ int udp_rcv(struct sk_buff *skb)
1762 1762
1763void udp_destroy_sock(struct sock *sk) 1763void udp_destroy_sock(struct sock *sk)
1764{ 1764{
1765 struct udp_sock *up = udp_sk(sk);
1765 bool slow = lock_sock_fast(sk); 1766 bool slow = lock_sock_fast(sk);
1766 udp_flush_pending_frames(sk); 1767 udp_flush_pending_frames(sk);
1767 unlock_sock_fast(sk, slow); 1768 unlock_sock_fast(sk, slow);
1769 if (static_key_false(&udp_encap_needed) && up->encap_type) {
1770 void (*encap_destroy)(struct sock *sk);
1771 encap_destroy = ACCESS_ONCE(up->encap_destroy);
1772 if (encap_destroy)
1773 encap_destroy(sk);
1774 }
1768} 1775}
1769 1776
1770/* 1777/*
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 599e1ba6d1ce..d8e5e852fc7a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1285,10 +1285,18 @@ do_confirm:
1285 1285
1286void udpv6_destroy_sock(struct sock *sk) 1286void udpv6_destroy_sock(struct sock *sk)
1287{ 1287{
1288 struct udp_sock *up = udp_sk(sk);
1288 lock_sock(sk); 1289 lock_sock(sk);
1289 udp_v6_flush_pending_frames(sk); 1290 udp_v6_flush_pending_frames(sk);
1290 release_sock(sk); 1291 release_sock(sk);
1291 1292
1293 if (static_key_false(&udpv6_encap_needed) && up->encap_type) {
1294 void (*encap_destroy)(struct sock *sk);
1295 encap_destroy = ACCESS_ONCE(up->encap_destroy);
1296 if (encap_destroy)
1297 encap_destroy(sk);
1298 }
1299
1292 inet6_destroy_sock(sk); 1300 inet6_destroy_sock(sk);
1293} 1301}
1294 1302