|
@@ -107,6 +107,7 @@
|
|
|
#include <net/checksum.h>
|
|
|
#include <net/xfrm.h>
|
|
|
#include <trace/events/udp.h>
|
|
|
+#include <linux/static_key.h>
|
|
|
#include "udp_impl.h"
|
|
|
|
|
|
struct udp_table udp_table __read_mostly;
|
|
@@ -1379,6 +1380,14 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
|
|
|
}
|
|
|
|
|
|
+static struct static_key udp_encap_needed __read_mostly;
|
|
|
+void udp_encap_enable(void)
|
|
|
+{
|
|
|
+ if (!static_key_enabled(&udp_encap_needed))
|
|
|
+ static_key_slow_inc(&udp_encap_needed);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(udp_encap_enable);
|
|
|
+
|
|
|
/* returns:
|
|
|
* -1: error
|
|
|
* 0: success
|
|
@@ -1400,7 +1409,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
goto drop;
|
|
|
nf_reset(skb);
|
|
|
|
|
|
- if (up->encap_type) {
|
|
|
+ if (static_key_false(&udp_encap_needed) && up->encap_type) {
|
|
|
int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
|
|
|
|
|
|
/*
|
|
@@ -1760,6 +1769,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
|
|
|
/* FALLTHROUGH */
|
|
|
case UDP_ENCAP_L2TPINUDP:
|
|
|
up->encap_type = val;
|
|
|
+ udp_encap_enable();
|
|
|
break;
|
|
|
default:
|
|
|
err = -ENOPROTOOPT;
|