@@ -922,6 +922,37 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
return (struct rtable *)skb_dst(skb);
}
+void sock_dummyfree(struct sk_buff *skb);
+
+/* only early demux can set noref socks
+ * noref socks do not carry any refcount and must be
+ * cleared before exiting the current RCU section
+ */
+static inline void skb_set_noref_sk(struct sk_buff *skb, struct sock *sk)
+{
+ skb->sk = sk;
+ skb->destructor = sock_dummyfree;
+}
+
+static inline bool skb_has_noref_sk(struct sk_buff *skb)
+{
+ return skb->destructor == sock_dummyfree;
+}
+
+static inline struct sock *skb_clear_noref_sk(struct sk_buff *skb)
+{
+ struct sock *ret;
+
+ if (!skb_has_noref_sk(skb))
+ return NULL;
+
+ WARN_ON_ONCE(!rcu_read_lock_held());
+ ret = skb->sk;
+ skb->sk = NULL;
+ skb->destructor = NULL;
+ return ret;
+}
+
/* For mangling skb->pkt_type from user space side from applications
* such as nft, tc, etc, we only allow a conservative subset of
* possible pkt_types to be set.
@@ -1893,6 +1893,13 @@ void sock_efree(struct sk_buff *skb)
}
EXPORT_SYMBOL(sock_efree);
+/* dummy destructor used by noref sockets */
+void sock_dummyfree(struct sk_buff *skb)
+{
+ WARN_ON_ONCE(!rcu_read_lock_held());
+}
+EXPORT_SYMBOL(sock_dummyfree);
+
kuid_t sock_i_uid(struct sock *sk)
{
kuid_t uid;
Noref sk do not carry a socket refcount, are valid only inside the current RCU section and must be explicitly cleared before exiting such section. They will be used in a later patch to allow early demux without sock refcounting. Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- include/linux/skbuff.h | 31 +++++++++++++++++++++++++++++++ net/core/sock.c | 7 +++++++ 2 files changed, 38 insertions(+)