When a session refcount hits 0, the session is freed via l2tp_session_free. Some pseudowires (ppp, eth) may have additional resources to free when this happens. Add a session_free callback that can be used by pseudowires to override the default kfree. The callback is responsible for freeing the session. --- net/l2tp/l2tp_core.c | 7 +++++-- net/l2tp/l2tp_core.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 869dec89ff0f..d6306ba2d78e 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1662,12 +1662,15 @@ void l2tp_session_free(struct l2tp_session *session) BUG_ON(refcount_read(&session->ref_count) != 0); + if (session->session_free) + session->session_free(session); + else + kfree(session); + if (tunnel) { BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); l2tp_tunnel_dec_refcount(tunnel); } - - kfree(session); } EXPORT_SYMBOL_GPL(l2tp_session_free); diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index d28d91600ad5..094b2e0dbd75 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -126,6 +126,7 @@ struct l2tp_session { int (*build_header)(struct l2tp_session *session, void *buf); void (*recv_skb)(struct l2tp_session *session, struct sk_buff *skb, int data_len); void (*session_close)(struct l2tp_session *session); + void (*session_free)(struct l2tp_session *session); #if IS_ENABLED(CONFIG_L2TP_DEBUGFS) void (*show)(struct seq_file *m, void *priv); #endif -- 1.9.1