FAILED: patch "[PATCH] net: l2tp: do not propagate multicast notification errors" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x af20e269f7459d2ce69887fdf2fad7caf986c865
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090341-survival-shrill-fee9@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From af20e269f7459d2ce69887fdf2fad7caf986c865 Mon Sep 17 00:00:00 2001
From: Zihan Xi <[email protected]>
Date: Thu, 20 Aug 2026 18:40:28 +0000
Subject: [PATCH] net: l2tp: do not propagate multicast notification errors
The tunnel create, tunnel modify, session create, and session modify netlink handlers send multicast notifications through helpers that can fail while allocating or encoding a message, or while multicasting it.
For tunnel and session create/modify, a notification is sent after the live operation has completed. Returning a best-effort notification error as the command result can therefore report failure for an operation that already committed and can cause callers to retry and accumulate live objects.
Keep sending notifications for listener visibility, but do not propagate their best-effort status as the command result. This also keeps the tunnel modify command consistent with the other notification-only paths.
net/l2tp/l2tp_netlink.c +8 -8
@@ -251,8 +251,8 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *infokfree (tunnel); goto out; } - ret =l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel, -L2TP_CMD_TUNNEL_CREATE ); +l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel, +L2TP_CMD_TUNNEL_CREATE );l2tp_tunnel_put (tunnel); out:
@@ -308,8 +308,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info goto out; } - ret =l2tp_tunnel_notify (&l2tp_nl_family, info, - tunnel,L2TP_CMD_TUNNEL_MODIFY ); +l2tp_tunnel_notify (&l2tp_nl_family, info, + tunnel,L2TP_CMD_TUNNEL_MODIFY );l2tp_tunnel_put (tunnel);
@@ -648,8 +648,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf session =l2tp_session_get (net, tunnel->sock, tunnel->version, tunnel_id, session_id);if (session) { - ret =l2tp_session_notify (&l2tp_nl_family, info, session, -L2TP_CMD_SESSION_CREATE ); +l2tp_session_notify (&l2tp_nl_family, info, session, +L2TP_CMD_SESSION_CREATE );l2tp_session_put (session); } }
@@ -713,8 +713,8 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *infif (info->attrs[L2TP_ATTR_RECV_TIMEOUT ]) session->reorder_timeout =nla_get_msecs (info->attrs[L2TP_ATTR_RECV_TIMEOUT ]); - ret =l2tp_session_notify (&l2tp_nl_family, info, - session,L2TP_CMD_SESSION_MODIFY ); +l2tp_session_notify (&l2tp_nl_family, info, + session,L2TP_CMD_SESSION_MODIFY );l2tp_session_put (session);
Sasha Levin
maintainerPATCH 1/6 l2tp: don't set sk_user_data in tunnel socket
From: James Chapman <[email protected]>
[ Upstream commit 4a4cd70369f162f819b7855b0eabcb2db21f01f4 ]
l2tp no longer uses the tunnel socket's sk_user_data so drop the code which sets it.
In l2tp_validate_socket use l2tp_sk_to_tunnel to check whether a given socket is already attached to an l2tp tunnel since we can no longer use non-null sk_user_data to indicate this.
Stable-dep-of: af20e269f745 ("net: l2tp: do not propagate multicast notification errors")
--- net/l2tp/l2tp_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/l2tp/l2tp_core.c +6 -4
@@ -1166,7 +1166,6 @@ static void l2tp_tunnel_destruct(struct sock *sk)/* Remove hooks into tunnel socket */ write_lock_bh (&sk->sk_callback_lock); sk->sk_destruct = tunnel->old_sk_destruct; - sk->sk_user_data =NULL ;write_unlock_bh (&sk->sk_callback_lock);/* Call the original destructor */
@@ -1448,6 +1447,8 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);static int l2tp_validate_socket (const struct sock *sk,const struct net *net,enum l2tp_encap_type encap) { +struct l2tp_tunnel *tunnel; +if (!net_eq (sock_net (sk), net))return -EINVAL ;
@@ -1461,8 +1462,11 @@ static int l2tp_validate_socket(const struct sock *sk, const struct net *net, (encap == L2TP_ENCAPTYPE_IP && sk->sk_protocol != IPPROTO_L2TP)) return -EPROTONOSUPPORT; -if (sk->sk_user_data) + tunnel =l2tp_sk_to_tunnel (sk); +if (tunnel) { +l2tp_tunnel_dec_refcount (tunnel);return -EBUSY ; + }return 0 ; }
@@ -1501,12 +1505,10 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, ret =l2tp_validate_socket (sk, net, tunnel->encap);if (ret <0 ) goto err_inval_sock; -rcu_assign_sk_user_data (sk, tunnel);write_unlock_bh (&sk->sk_callback_lock);if (tunnel->encap ==L2TP_ENCAPTYPE_UDP ) {struct udp_tunnel_sock_cfg udp_cfg = { - .sk_user_data = tunnel, .encap_type =UDP_ENCAP_L2TPINUDP , .encap_rcv = l2tp_udp_encap_recv, .encap_destroy = l2tp_udp_encap_destroy,
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/6 l2tp: refactor ppp socket/session relationship
From: James Chapman <[email protected]>
[ Upstream commit c5cbaef992d6420d8bcebea1b1fcc23302a67c57 ]
Each l2tp ppp session has an associated pppox socket. l2tp_ppp uses the session's pppox socket refcount to manage session lifetimes; the pppox socket holds a ref on the session which is dropped by the socket destructor. This complicates session cleanup.
Given l2tp sessions are refcounted, it makes more sense to reverse this relationship such that the session keeps the socket alive, not the other way around. So refactor l2tp_ppp to have the session hold a ref on its socket while it references it. When the session is closed, it drops its socket ref when it detaches from its socket. If the socket is closed first, it initiates the closing of its session, if one is attached. The socket/session can then be freed asynchronously when their refcounts drop to 0.
Use the session's session_close callback to detach the pppox socket since this will be done on the work queue together with the rest of the session cleanup via l2tp_session_delete.
Also, since l2tp_ppp uses the pppox socket's sk_user_data, use the rcu sk_user_data access helpers when accessing it and set the socket's SOCK_RCU_FREE flag to have pppox sockets freed by rcu.
Stable-dep-of: af20e269f745 ("net: l2tp: do not propagate multicast notification errors")
--- net/l2tp/l2tp_ppp.c | 94 +++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 55 deletions(-)
net/l2tp/l2tp_ppp.c +39 -55
@@ -119,7 +119,6 @@ struct pppol2tp_session {struct mutex sk_lock;/* Protects .sk */ struct sock __rcu *sk;/* Pointer to the session PPPoX socket */ struct sock *__sk;/* Copy of .sk, for cleanup */ -struct rcu_head rcu;/* For asynchronous release */ };static int pppol2tp_xmit (struct ppp_channel *chan,struct sk_buff *skb);
@@ -147,20 +146,16 @@ static inline struct l2tp_session *pppol2tp_sock_to_session(struct sock *sk)if (!sk)return NULL ; -sock_hold (sk); - session = (struct l2tp_session *)(sk->sk_user_data); -if (!session) { -sock_put (sk); - goto out; - } -if (WARN_ON (session->magic !=L2TP_SESSION_MAGIC )) { - session =NULL ; -sock_put (sk); - goto out; +rcu_read_lock (); + session =rcu_dereference_sk_user_data (sk); +if (session &&refcount_inc_not_zero (&session->ref_count)) { +rcu_read_unlock (); +WARN_ON_ONCE (session->magic !=L2TP_SESSION_MAGIC ); +return session; } +rcu_read_unlock (); -out: -return session; +return NULL ; }/*****************************************************************************
@@ -307,12 +302,12 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,l2tp_xmit_skb (session, skb);local_bh_enable (); -sock_put (sk); +l2tp_session_dec_refcount (session);return total_len; error_put_sess: -sock_put (sk); +l2tp_session_dec_refcount (session); error:return error; }
@@ -366,12 +361,12 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)l2tp_xmit_skb (session, skb);local_bh_enable (); -sock_put (sk); +l2tp_session_dec_refcount (session);return 1 ; abort_put_sess: -sock_put (sk); +l2tp_session_dec_refcount (session); abort:/* Free the original skb */ kfree_skb (skb);
@@ -382,28 +377,31 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)* Session (and tunnel control) socket create/destroy. *****************************************************************************/ -static void pppol2tp_put_sk (struct rcu_head *head) -{ -struct pppol2tp_session *ps; - - ps =container_of (head,typeof (*ps), rcu); -sock_put (ps->__sk); -} -/* Really kill the session socket. (Called from sock_put() if * refcnt == 0.) */ static void pppol2tp_session_destruct (struct sock *sk) { -struct l2tp_session *session = sk->sk_user_data; -skb_queue_purge (&sk->sk_receive_queue);skb_queue_purge (&sk->sk_write_queue); +} -if (session) { - sk->sk_user_data =NULL ; -if (WARN_ON (session->magic !=L2TP_SESSION_MAGIC )) -return ; +static void pppol2tp_session_close (struct l2tp_session *session) +{ +struct pppol2tp_session *ps; + + ps =l2tp_session_priv (session); +mutex_lock (&ps->sk_lock); + ps->__sk =rcu_dereference_protected (ps->sk, +lockdep_is_held (&ps->sk_lock)); +RCU_INIT_POINTER (ps->sk,NULL ); +mutex_unlock (&ps->sk_lock); +if (ps->__sk) { +/* detach socket */ +rcu_assign_sk_user_data (ps->__sk,NULL ); +sock_put (ps->__sk); + +/* drop ref taken when we referenced socket via sk_user_data */ l2tp_session_dec_refcount (session); } }
@@ -433,30 +431,13 @@ static int pppol2tp_release(struct socket *sock) session =pppol2tp_sock_to_session (sk);if (session) { -struct pppol2tp_session *ps; -l2tp_session_delete (session); - - ps =l2tp_session_priv (session); -mutex_lock (&ps->sk_lock); - ps->__sk =rcu_dereference_protected (ps->sk, -lockdep_is_held (&ps->sk_lock)); -RCU_INIT_POINTER (ps->sk,NULL ); -mutex_unlock (&ps->sk_lock); -call_rcu (&ps->rcu, pppol2tp_put_sk); - -/* Rely on the sock_put() call at the end of the function for -* dropping the reference held by pppol2tp_sock_to_session(). -* The last reference will be dropped by pppol2tp_put_sk(). -*/ +/* drop ref taken by pppol2tp_sock_to_session */ +l2tp_session_dec_refcount (session); }release_sock (sk); -/* This will delete the session context via -* pppol2tp_session_destruct() if the socket's refcnt drops to -* zero. -*/ sock_put (sk);return 0 ;
@@ -495,6 +476,7 @@ static int pppol2tp_create(struct net *net, struct socket *sock, int kern) goto out;sock_init_data (sock, sk); +sock_set_flag (sk,SOCK_RCU_FREE ); sock->state =SS_UNCONNECTED ; sock->ops = &pppol2tp_ops;
@@ -532,6 +514,7 @@ static void pppol2tp_session_init(struct l2tp_session *session)struct pppol2tp_session *ps; session->recv_skb = pppol2tp_recv; + session->session_close = pppol2tp_session_close;if (IS_ENABLED (CONFIG_L2TP_DEBUGFS )) session->show = pppol2tp_show;
@@ -820,12 +803,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, out_no_ppp:/* This is how we get the session context from the socket. */ - sk->sk_user_data = session; +sock_hold (sk); +rcu_assign_sk_user_data (sk, session);rcu_assign_pointer (ps->sk, sk);mutex_unlock (&ps->sk_lock);/* Keep the reference we've grabbed on the session: sk doesn't expect -* the session to disappear. pppol2tp_session_destruct() is responsible +* the session to disappear. pppol2tp_session_close() is responsible * for dropping it. */ drop_refcnt = false;
@@ -992,7 +976,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, error = len; -sock_put (sk); +l2tp_session_dec_refcount (session); end:return error; }
@@ -1263,7 +1247,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, err =pppol2tp_session_setsockopt (sk, session, optname, val); } -sock_put (sk); +l2tp_session_dec_refcount (session); end:return err; }
@@ -1384,7 +1368,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, err =0 ; end_put_sess: -sock_put (sk); +l2tp_session_dec_refcount (session); end:return err; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/6 l2tp: prevent possible tunnel refcount underflow
In reply to Sasha LevinFrom: James Chapman <[email protected]>
[ Upstream commit 24256415d18695b46da06c93135f5b51c548b950 ]
When a session is created, it sets a backpointer to its tunnel. When the session refcount drops to 0, l2tp_session_free drops the tunnel refcount if session->tunnel is non-NULL. However, session->tunnel is set in l2tp_session_create, before the tunnel refcount is incremented by l2tp_session_register, which leaves a small window where session->tunnel is non-NULL when the tunnel refcount hasn't been bumped.
Moving the assignment to l2tp_session_register is trivial but l2tp_session_create calls l2tp_session_set_header_len which uses session->tunnel to get the tunnel's encap. Add an encap arg to l2tp_session_set_header_len to avoid using session->tunnel.
If l2tpv3 sessions have colliding IDs, it is possible for l2tp_v3_session_get to race with l2tp_session_register and fetch a session which doesn't yet have session->tunnel set. Add a check for this case.
Stable backport notes:
Keep this tree's per-tunnel and per-net session hash lists. Assign session->tunnel immediately after taking the tunnel reference in both registration branches, before publishing the session with hlist_add_head_rcu(). Registration failures therefore leave the tunnel pointer NULL and cannot release an unacquired tunnel reference. Retain the explicit encapsulation argument to l2tp_session_set_header_len() and all its callers. Omit the upstream collision-table lookup hunk because this tree has no such table and publishes only initialized sessions.
Rename the existing l2tp_tunnel_dec_refcount() and l2tp_session_dec_refcount() functions, declarations, exports and callers to l2tp_tunnel_put() and l2tp_session_put(). Their implementations are unchanged; no functions are added. This aligns the context adjacent to the notification calls so af20e269f745 applies cleanly with a three-way cherry-pick while retaining this tree's session lookup implementation.
Restore the stable tunnel socket sk_user_data assignment, validation and destructor clearing removed by the earlier 4a4cd70369f1 backport. The stable lookup, UDP receive and tunnel destruction paths still rely on that association. The newer validation also passed a const socket to the old non-const lookup and dropped a reference that this lookup does not acquire. Retaining the stable socket relationship avoids that compiler diagnostic and preserves the existing tunnel lifetime model.
Stable-dep-of: af20e269f745 ("net: l2tp: do not propagate multicast notification errors")
--- net/l2tp/l2tp_core.c | 48 +++++++++++++++++++++-------------------- net/l2tp/l2tp_core.h | 7 +++--- net/l2tp/l2tp_debugfs.c | 8 +++---- net/l2tp/l2tp_eth.c | 6 +++--- net/l2tp/l2tp_ip.c | 4 ++-- net/l2tp/l2tp_ip6.c | 4 ++-- net/l2tp/l2tp_netlink.c | 40 ++++++++++++++++++---------------- net/l2tp/l2tp_ppp.c | 41 ++++++++++++++++++----------------- 8 files changed, 82 insertions(+), 76 deletions(-)
net/l2tp/l2tp_core.c +25 -23
@@ -164,7 +164,7 @@ static void l2tp_session_free(struct l2tp_session *session) {trace_free_session (session);if (session->tunnel) -l2tp_tunnel_dec_refcount (session->tunnel); +l2tp_tunnel_put (session->tunnel);kfree (session); }
@@ -186,12 +186,12 @@ void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel) }EXPORT_SYMBOL_GPL (l2tp_tunnel_inc_refcount); -void l2tp_tunnel_dec_refcount (struct l2tp_tunnel *tunnel) +void l2tp_tunnel_put (struct l2tp_tunnel *tunnel) {if (refcount_dec_and_test (&tunnel->ref_count))l2tp_tunnel_free (tunnel); } -EXPORT_SYMBOL_GPL (l2tp_tunnel_dec_refcount); +EXPORT_SYMBOL_GPL (l2tp_tunnel_put);void l2tp_session_inc_refcount (struct l2tp_session *session) {
@@ -199,12 +199,12 @@ void l2tp_session_inc_refcount(struct l2tp_session *session) }EXPORT_SYMBOL_GPL (l2tp_session_inc_refcount); -void l2tp_session_dec_refcount (struct l2tp_session *session) +void l2tp_session_put (struct l2tp_session *session) {if (refcount_dec_and_test (&session->ref_count))l2tp_session_free (session); } -EXPORT_SYMBOL_GPL (l2tp_session_dec_refcount); +EXPORT_SYMBOL_GPL (l2tp_session_put);/* Lookup a tunnel. A new reference is held on the returned tunnel. */ struct l2tp_tunnel *l2tp_tunnel_get (const struct net *net,u32 tunnel_id)
@@ -380,11 +380,13 @@ int l2tp_session_register(struct l2tp_session *session, }l2tp_tunnel_inc_refcount (tunnel); + session->tunnel = tunnel;hlist_add_head_rcu (&session->global_hlist, g_head);spin_unlock_bh (&pn->l2tp_session_hlist_lock); }else {l2tp_tunnel_inc_refcount (tunnel); + session->tunnel = tunnel; }hlist_add_head_rcu (&session->hlist, head);
@@ -698,7 +700,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,if (!session->lns_mode && !session->send_seq) {trace_session_seqnum_lns_enable (session); session->send_seq =1 ; -l2tp_session_set_header_len (session, tunnel->version); +l2tp_session_set_header_len (session, tunnel->version, + tunnel->encap); } }else {/* No sequence numbers.
@@ -719,7 +722,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,if (!session->lns_mode && session->send_seq) {trace_session_seqnum_lns_disable (session); session->send_seq =0 ; -l2tp_session_set_header_len (session, tunnel->version); +l2tp_session_set_header_len (session, tunnel->version, + tunnel->encap); }else if (session->send_seq) {pr_debug_ratelimited ("%s: recv data has no seq numbers when required. Discarding.\n" , session->name);
@@ -863,7 +867,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb) session =l2tp_tunnel_get_session (tunnel, session_id);if (!session || !session->recv_skb) {if (session) -l2tp_session_dec_refcount (session); +l2tp_session_put (session);/* Not found? Pass to userspace to deal with */ pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n",
@@ -873,12 +877,12 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb)if (tunnel->version ==L2TP_HDR_VER_3 &&l2tp_v3_ensure_opt_in_linear (session, skb, &ptr, &optr)) { -l2tp_session_dec_refcount (session); +l2tp_session_put (session); goto invalid; }l2tp_recv_common (session, skb, ptr, optr, hdrflags, length); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);return 0 ;
@@ -1166,6 +1170,7 @@ static void l2tp_tunnel_destruct(struct sock *sk)/* Remove hooks into tunnel socket */ write_lock_bh (&sk->sk_callback_lock); sk->sk_destruct = tunnel->old_sk_destruct; + sk->sk_user_data =NULL ;write_unlock_bh (&sk->sk_callback_lock);/* Call the original destructor */
@@ -1271,10 +1276,10 @@ static void l2tp_tunnel_del_work(struct work_struct *work)l2tp_tunnel_remove (tunnel->l2tp_net, tunnel);/* drop initial ref */ -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel);/* drop workqueue ref */ -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); }/* Create a socket for the tunnel, if one isn't set up by
@@ -1447,8 +1452,6 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);static int l2tp_validate_socket (const struct sock *sk,const struct net *net,enum l2tp_encap_type encap) { -struct l2tp_tunnel *tunnel; -if (!net_eq (sock_net (sk), net))return -EINVAL ;
@@ -1462,11 +1465,8 @@ static int l2tp_validate_socket(const struct sock *sk, const struct net *net, (encap == L2TP_ENCAPTYPE_IP && sk->sk_protocol != IPPROTO_L2TP)) return -EPROTONOSUPPORT; - tunnel =l2tp_sk_to_tunnel (sk); -if (tunnel) { -l2tp_tunnel_dec_refcount (tunnel); +if (sk->sk_user_data)return -EBUSY ; - }return 0 ; }
@@ -1505,10 +1505,12 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, ret =l2tp_validate_socket (sk, net, tunnel->encap);if (ret <0 ) goto err_inval_sock; +rcu_assign_sk_user_data (sk, tunnel);write_unlock_bh (&sk->sk_callback_lock);if (tunnel->encap ==L2TP_ENCAPTYPE_UDP ) {struct udp_tunnel_sock_cfg udp_cfg = { + .sk_user_data = tunnel, .encap_type =UDP_ENCAP_L2TPINUDP , .encap_rcv = l2tp_udp_encap_recv, .encap_destroy = l2tp_udp_encap_destroy,
@@ -1574,14 +1576,15 @@ void l2tp_session_delete(struct l2tp_session *session)if (session->session_close) (*session->session_close)(session); -l2tp_session_dec_refcount (session); +l2tp_session_put (session); }EXPORT_SYMBOL_GPL (l2tp_session_delete);/* We come here whenever a session's send_seq, cookie_len or * l2specific_type parameters are set. */ -void l2tp_session_set_header_len (struct l2tp_session *session,int version) +void l2tp_session_set_header_len (struct l2tp_session *session,int version, +enum l2tp_encap_type encap) {if (version ==L2TP_HDR_VER_2 ) { session->hdr_len =6 ;
@@ -1590,7 +1593,7 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version) }else { session->hdr_len =4 + session->cookie_len; session->hdr_len +=l2tp_get_l2specific_len (session); -if (session->tunnel->encap ==L2TP_ENCAPTYPE_UDP ) +if (encap ==L2TP_ENCAPTYPE_UDP ) session->hdr_len +=4 ; } }
@@ -1604,7 +1607,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn session =kzalloc (sizeof (*session) + priv_size,GFP_KERNEL );if (session) { session->magic =L2TP_SESSION_MAGIC ; - session->tunnel = tunnel; session->session_id = session_id; session->peer_session_id = peer_session_id;
@@ -1640,7 +1642,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnmemcpy (&session->peer_cookie[0 ], &cfg->peer_cookie[0 ], cfg->peer_cookie_len); } -l2tp_session_set_header_len (session, tunnel->version); +l2tp_session_set_header_len (session, tunnel->version, tunnel->encap);refcount_set (&session->ref_count,1 );
net/l2tp/l2tp_core.h +4 -3
@@ -214,9 +214,9 @@ static inline void *l2tp_session_priv(struct l2tp_session *session)/* Tunnel and session refcounts */ void l2tp_tunnel_inc_refcount (struct l2tp_tunnel *tunnel); -void l2tp_tunnel_dec_refcount (struct l2tp_tunnel *tunnel); +void l2tp_tunnel_put (struct l2tp_tunnel *tunnel);void l2tp_session_inc_refcount (struct l2tp_session *session); -void l2tp_session_dec_refcount (struct l2tp_session *session); +void l2tp_session_put (struct l2tp_session *session);/* Tunnel and session lookup. * These functions take a reference on the instances they return, so
@@ -261,7 +261,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,int l2tp_udp_encap_recv (struct sock *sk,struct sk_buff *skb);/* Transmit path helpers for sending packets over the tunnel socket. */ -void l2tp_session_set_header_len (struct l2tp_session *session,int version); +void l2tp_session_set_header_len (struct l2tp_session *session,int version, +enum l2tp_encap_type encap);int l2tp_xmit_skb (struct l2tp_session *session,struct sk_buff *skb);/* Pseudowire management.
net/l2tp/l2tp_debugfs.c +4 -4
@@ -44,7 +44,7 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd) {/* Drop reference taken during previous invocation */ if (pd->tunnel) -l2tp_tunnel_dec_refcount (pd->tunnel); +l2tp_tunnel_put (pd->tunnel); pd->tunnel =l2tp_tunnel_get_nth (pd->net, pd->tunnel_idx); pd->tunnel_idx++;
@@ -54,7 +54,7 @@ static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd) {/* Drop reference taken during previous invocation */ if (pd->session) -l2tp_session_dec_refcount (pd->session); +l2tp_session_put (pd->session); pd->session =l2tp_session_get_nth (pd->tunnel, pd->session_idx); pd->session_idx++;
@@ -109,11 +109,11 @@ static void l2tp_dfs_seq_stop(struct seq_file *p, void *v)* or l2tp_dfs_next_tunnel(). */ if (pd->session) { -l2tp_session_dec_refcount (pd->session); +l2tp_session_put (pd->session); pd->session =NULL ; }if (pd->tunnel) { -l2tp_tunnel_dec_refcount (pd->tunnel); +l2tp_tunnel_put (pd->tunnel); pd->tunnel =NULL ; } }
net/l2tp/l2tp_eth.c +3 -3
@@ -311,7 +311,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,if (rc <0 ) {rtnl_unlock ();l2tp_session_delete (session); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);free_netdev (dev);return rc;
@@ -322,14 +322,14 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,rtnl_unlock (); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);__module_get (THIS_MODULE );return 0 ; err_sess_dev: -l2tp_session_dec_refcount (session); +l2tp_session_put (session);free_netdev (dev); err_sess:kfree (session);
net/l2tp/l2tp_ip.c +2 -2
@@ -152,7 +152,7 @@ static int l2tp_ip_recv(struct sk_buff *skb) goto discard_sess;l2tp_recv_common (session, skb, ptr, optr,0 , skb->len); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);return 0 ;
@@ -185,7 +185,7 @@ static int l2tp_ip_recv(struct sk_buff *skb)return sk_receive_skb (sk, skb,1 ); discard_sess: -l2tp_session_dec_refcount (session); +l2tp_session_put (session); goto discard; discard_put:
net/l2tp/l2tp_ip6.c +2 -2
@@ -162,7 +162,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb) goto discard_sess;l2tp_recv_common (session, skb, ptr, optr,0 , skb->len); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);return 0 ;
@@ -195,7 +195,7 @@ static int l2tp_ip6_recv(struct sk_buff *skb)return sk_receive_skb (sk, skb,1 ); discard_sess: -l2tp_session_dec_refcount (session); +l2tp_session_put (session); goto discard; discard_put:
net/l2tp/l2tp_netlink.c +21 -19
@@ -62,7 +62,7 @@ static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info) tunnel =l2tp_tunnel_get (net, tunnel_id);if (tunnel) { session =l2tp_tunnel_get_session (tunnel, session_id); -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); } }
@@ -249,7 +249,7 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info } ret =l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel,L2TP_CMD_TUNNEL_CREATE ); -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); out:return ret;
@@ -279,7 +279,7 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *infol2tp_tunnel_delete (tunnel); -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); out:return ret;
@@ -307,7 +307,7 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info ret =l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel,L2TP_CMD_TUNNEL_MODIFY ); -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); out:return ret;
@@ -478,12 +478,12 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)if (ret <0 ) goto err_nlmsg_tunnel; -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel);return genlmsg_unicast (net, msg, info->snd_portid); err_nlmsg_tunnel: -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); err_nlmsg:nlmsg_free (msg); err:
@@ -504,10 +504,10 @@ static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callbackif (l2tp_nl_tunnel_send (skb,NETLINK_CB (cb->skb).portid, cb->nlh->nlmsg_seq,NLM_F_MULTI , tunnel,L2TP_CMD_TUNNEL_GET ) <0 ) { -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); goto out; } -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); ti++; }
@@ -639,12 +639,12 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *infif (session) { ret =l2tp_session_notify (&l2tp_nl_family, info, session,L2TP_CMD_SESSION_CREATE ); -l2tp_session_dec_refcount (session); +l2tp_session_put (session); } } out_tunnel: -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); out:return ret; }
@@ -669,7 +669,7 @@ static int l2tp_nl_cmd_session_delete(struct sk_buff *skb, struct genl_info *infif (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete) l2tp_nl_cmd_ops[pw_type]->session_delete (session); -l2tp_session_dec_refcount (session); +l2tp_session_put (session); out:return ret;
@@ -690,8 +690,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf session->recv_seq =nla_get_u8 (info->attrs[L2TP_ATTR_RECV_SEQ ]);if (info->attrs[L2TP_ATTR_SEND_SEQ ]) { +struct l2tp_tunnel *tunnel = session->tunnel; + session->send_seq =nla_get_u8 (info->attrs[L2TP_ATTR_SEND_SEQ ]); -l2tp_session_set_header_len (session, session->tunnel->version); +l2tp_session_set_header_len (session, tunnel->version, tunnel->encap); }if (info->attrs[L2TP_ATTR_LNS_MODE ])
@@ -703,7 +705,7 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf ret =l2tp_session_notify (&l2tp_nl_family, info, session,L2TP_CMD_SESSION_MODIFY ); -l2tp_session_dec_refcount (session); +l2tp_session_put (session); out:return ret;
@@ -814,14 +816,14 @@ static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info) ret =genlmsg_unicast (genl_info_net (info), msg, info->snd_portid); -l2tp_session_dec_refcount (session); +l2tp_session_put (session);return ret; err_ref_msg:nlmsg_free (msg); err_ref: -l2tp_session_dec_refcount (session); +l2tp_session_put (session); err:return ret; }
@@ -844,7 +846,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback session =l2tp_session_get_nth (tunnel, si);if (!session) { ti++; -l2tp_tunnel_dec_refcount (tunnel); +l2tp_tunnel_put (tunnel); tunnel =NULL ; si =0 ;continue ;
@@ -853,11 +855,11 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callbackif (l2tp_nl_session_send (skb,NETLINK_CB (cb->skb).portid, cb->nlh->nlmsg_seq,NLM_F_MULTI , session,L2TP_CMD_SESSION_GET ) <0 ) { -l2tp_session_dec_refcount (session); -l2tp_tunnel_dec_refcount (tunnel); +l2tp_session_put (session); +l2tp_tunnel_put (tunnel);break ; } -l2tp_session_dec_refcount (session); +l2tp_session_put (session); si++; }
net/l2tp/l2tp_ppp.c +21 -20
146 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/6 l2tp: cleanup eth/ppp pseudowire setup code
In reply to Sasha LevinFrom: James Chapman <[email protected]>
[ Upstream commit d93b8a63f011f252dcfb101d5b90367bd8f42db3 ]
l2tp eth/ppp pseudowire setup/cleanup uses kfree() in some error paths. Drop the refcount instead such that the session object is always freed when the refcount reaches 0.
Stable-dep-of: af20e269f745 ("net: l2tp: do not propagate multicast notification errors")
--- net/l2tp/l2tp_eth.c | 2 +- net/l2tp/l2tp_ppp.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-)
net/l2tp/l2tp_eth.c +1 -1
@@ -332,7 +332,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,l2tp_session_put (session);free_netdev (dev); err_sess: -kfree (session); +l2tp_session_dec_refcount (session); err:return rc; }
net/l2tp/l2tp_ppp.c +5 -3
@@ -759,6 +759,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, goto end; } + drop_refcnt = true; +pppol2tp_session_init (session); ps =l2tp_session_priv (session);l2tp_session_inc_refcount (session);
@@ -767,10 +769,10 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, error =l2tp_session_register (session, tunnel);if (error <0 ) {mutex_unlock (&ps->sk_lock); -kfree (session); +l2tp_session_dec_refcount (session); goto end; } - drop_refcnt = true; + new_session = true; }
@@ -865,7 +867,7 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel,return 0 ; err_sess: -kfree (session); +l2tp_session_dec_refcount (session); err:return error; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 5/6 l2tp: improve tunnel/session refcount helpers
In reply to Sasha LevinFrom: James Chapman <[email protected]>
[ Upstream commit abe7a1a7d0b69e63b1bca5f9531023a52336784f ]
l2tp_tunnel_inc_refcount and l2tp_session_inc_refcount wrap refcount_inc. They add no value so just use the refcount APIs directly and drop l2tp's helpers. l2tp already uses refcount_inc_not_zero anyway.
Rename l2tp_tunnel_dec_refcount and l2tp_session_dec_refcount to l2tp_tunnel_put and l2tp_session_put to better match their use pairing various _get getters.
Stable backport notes:
Keep this tree's session hash lists, synchronous session deletion, and sk_user_data tunnel socket association. Its l2tp_sk_to_tunnel() does not acquire a reference, so omit upstream puts in the socket destruction and validation paths. Omit hunks for the absent session collision tables and session deletion worker; no functions are added.
The earlier 24256415d186 backport already renamed the release helpers and most callers to l2tp_tunnel_put() and l2tp_session_put(). Convert the three old session release calls introduced by the intervening d93b8a63f011 backport in Ethernet/PPP setup error paths to l2tp_session_put(), avoiding references to a helper that no longer exists.
Remove the two increment wrappers and their declarations/exports, using refcount_inc() at all callers, including the stable-only session lookup and registration paths. Reference acquisition and release ordering are unchanged. Retain the stable netlink lookup APIs; af20e269f745 applies cleanly with a three-way cherry-pick.
[ sashal: Reduced backport -- upstream abe7a1a7d0b69 touches 8 file(s), this
backport carries 5. Not backported here:
net/l2tp/l2tp_debugfs.c
net/l2tp/l2tp_ip6.c
net/l2tp/l2tp_ip.c
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: af20e269f745 ("net: l2tp: do not propagate multicast notification errors")
--- net/l2tp/l2tp_core.c | 26 +++++++------------------- net/l2tp/l2tp_core.h | 2 -- net/l2tp/l2tp_eth.c | 4 ++-- net/l2tp/l2tp_netlink.c | 2 +- net/l2tp/l2tp_ppp.c | 8 ++++---- 5 files changed, 14 insertions(+), 28 deletions(-)
net/l2tp/l2tp_core.c +7 -19
@@ -180,12 +180,6 @@ struct l2tp_tunnel *l2tp_sk_to_tunnel(struct sock *sk) }EXPORT_SYMBOL_GPL (l2tp_sk_to_tunnel); -void l2tp_tunnel_inc_refcount (struct l2tp_tunnel *tunnel) -{ -refcount_inc (&tunnel->ref_count); -} -EXPORT_SYMBOL_GPL (l2tp_tunnel_inc_refcount); -void l2tp_tunnel_put (struct l2tp_tunnel *tunnel) {if (refcount_dec_and_test (&tunnel->ref_count))
@@ -193,12 +187,6 @@ void l2tp_tunnel_put(struct l2tp_tunnel *tunnel) }EXPORT_SYMBOL_GPL (l2tp_tunnel_put); -void l2tp_session_inc_refcount (struct l2tp_session *session) -{ -refcount_inc (&session->ref_count); -} -EXPORT_SYMBOL_GPL (l2tp_session_inc_refcount); -void l2tp_session_put (struct l2tp_session *session) {if (refcount_dec_and_test (&session->ref_count))
@@ -256,7 +244,7 @@ struct l2tp_session *l2tp_tunnel_get_session(struct l2tp_tunnel *tunnel,rcu_read_lock_bh ();hlist_for_each_entry_rcu (session, session_list, hlist)if (session->session_id == session_id) { -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);rcu_read_unlock_bh ();return session;
@@ -277,7 +265,7 @@ struct l2tp_session *l2tp_session_get(const struct net *net, u32 session_id)rcu_read_lock_bh ();hlist_for_each_entry_rcu (session, session_list, global_hlist)if (session->session_id == session_id) { -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);rcu_read_unlock_bh ();return session;
@@ -298,7 +286,7 @@ struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth)for (hash =0 ; hash <L2TP_HASH_SIZE ; hash++) {hlist_for_each_entry_rcu (session, &tunnel->session_hlist[hash], hlist) {if (++count > nth) { -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);rcu_read_unlock_bh ();return session; }
@@ -325,7 +313,7 @@ struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,for (hash =0 ; hash <L2TP_HASH_SIZE_2 ; hash++) {hlist_for_each_entry_rcu (session, &pn->l2tp_session_hlist[hash], global_hlist) {if (!strcmp (session->ifname, ifname)) { -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);rcu_read_unlock_bh ();return session;
@@ -379,13 +367,13 @@ int l2tp_session_register(struct l2tp_session *session, goto err_tlock_pnlock; } -l2tp_tunnel_inc_refcount (tunnel); +refcount_inc (&tunnel->ref_count); session->tunnel = tunnel;hlist_add_head_rcu (&session->global_hlist, g_head);spin_unlock_bh (&pn->l2tp_session_hlist_lock); }else { -l2tp_tunnel_inc_refcount (tunnel); +refcount_inc (&tunnel->ref_count); session->tunnel = tunnel; }
@@ -1559,7 +1547,7 @@ void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) {if (!test_and_set_bit (0 , &tunnel->dead)) {trace_delete_tunnel (tunnel); -l2tp_tunnel_inc_refcount (tunnel); +refcount_inc (&tunnel->ref_count);queue_work (l2tp_wq, &tunnel->del_work); } }
net/l2tp/l2tp_core.h +0 -2
@@ -213,9 +213,7 @@ static inline void *l2tp_session_priv(struct l2tp_session *session) }/* Tunnel and session refcounts */ -void l2tp_tunnel_inc_refcount (struct l2tp_tunnel *tunnel);void l2tp_tunnel_put (struct l2tp_tunnel *tunnel); -void l2tp_session_inc_refcount (struct l2tp_session *session);void l2tp_session_put (struct l2tp_session *session);/* Tunnel and session lookup.
net/l2tp/l2tp_eth.c +2 -2
@@ -293,7 +293,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, spriv =l2tp_session_priv (session); -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);rtnl_lock ();
@@ -332,7 +332,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,l2tp_session_put (session);free_netdev (dev); err_sess: -l2tp_session_dec_refcount (session); +l2tp_session_put (session); err:return rc; }
net/l2tp/l2tp_netlink.c +1 -1
@@ -241,7 +241,7 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *infoif (ret <0 ) goto out; -l2tp_tunnel_inc_refcount (tunnel); +refcount_inc (&tunnel->ref_count); ret =l2tp_tunnel_register (tunnel, net, &cfg);if (ret <0 ) {kfree (tunnel);
net/l2tp/l2tp_ppp.c +4 -4
@@ -658,7 +658,7 @@ static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net,if (error <0 )return ERR_PTR (error); -l2tp_tunnel_inc_refcount (tunnel); +refcount_inc (&tunnel->ref_count); error =l2tp_tunnel_register (tunnel, net, &tcfg);if (error <0 ) {kfree (tunnel);
@@ -763,13 +763,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,pppol2tp_session_init (session); ps =l2tp_session_priv (session); -l2tp_session_inc_refcount (session); +refcount_inc (&session->ref_count);mutex_lock (&ps->sk_lock); error =l2tp_session_register (session, tunnel);if (error <0 ) {mutex_unlock (&ps->sk_lock); -l2tp_session_dec_refcount (session); +l2tp_session_put (session); goto end; }
@@ -867,7 +867,7 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel,return 0 ; err_sess: -l2tp_session_dec_refcount (session); +l2tp_session_put (session); err:return error; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 6/6 net: l2tp: do not propagate multicast notification errors
In reply to Sasha LevinFrom: Zihan Xi <[email protected]>
[ Upstream commit af20e269f7459d2ce69887fdf2fad7caf986c865 ]
The tunnel create, tunnel modify, session create, and session modify netlink handlers send multicast notifications through helpers that can fail while allocating or encoding a message, or while multicasting it.
For tunnel and session create/modify, a notification is sent after the live operation has completed. Returning a best-effort notification error as the command result can therefore report failure for an operation that already committed and can cause callers to retry and accumulate live objects.
Keep sending notifications for listener visibility, but do not propagate their best-effort status as the command result. This also keeps the tunnel modify command consistent with the other notification-only paths.
--- net/l2tp/l2tp_netlink.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
net/l2tp/l2tp_netlink.c +8 -8
@@ -247,8 +247,8 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *infokfree (tunnel); goto out; } - ret =l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel, -L2TP_CMD_TUNNEL_CREATE ); +l2tp_tunnel_notify (&l2tp_nl_family, info, tunnel, +L2TP_CMD_TUNNEL_CREATE );l2tp_tunnel_put (tunnel); out:
@@ -304,8 +304,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info goto out; } - ret =l2tp_tunnel_notify (&l2tp_nl_family, info, - tunnel,L2TP_CMD_TUNNEL_MODIFY ); +l2tp_tunnel_notify (&l2tp_nl_family, info, + tunnel,L2TP_CMD_TUNNEL_MODIFY );l2tp_tunnel_put (tunnel);
@@ -637,8 +637,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *infif (ret >=0 ) { session =l2tp_tunnel_get_session (tunnel, session_id);if (session) { - ret =l2tp_session_notify (&l2tp_nl_family, info, session, -L2TP_CMD_SESSION_CREATE ); +l2tp_session_notify (&l2tp_nl_family, info, session, +L2TP_CMD_SESSION_CREATE );l2tp_session_put (session); } }
@@ -702,8 +702,8 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *infif (info->attrs[L2TP_ATTR_RECV_TIMEOUT ]) session->reorder_timeout =nla_get_msecs (info->attrs[L2TP_ATTR_RECV_TIMEOUT ]); - ret =l2tp_session_notify (&l2tp_nl_family, info, - session,L2TP_CMD_SESSION_MODIFY ); +l2tp_session_notify (&l2tp_nl_family, info, + session,L2TP_CMD_SESSION_MODIFY );l2tp_session_put (session);
Signature · 1 line
2.53.0