From b113d00bcc5d499d2acb4df824a10fcb5ccc3b6c Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 7 Sep 2012 12:35:18 +0200 Subject: L2TP: Close only session (not tunnel) after a PPP disconnection When a PPP connection is torn down, close the underlying session but not the tunnel (unless its last session has been closed). Signed-off-by: Guillaume Nault --- accel-pppd/ctrl/l2tp/l2tp.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index 3c38bfa..819da07 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -267,6 +267,19 @@ static int l2tp_session_disconnect(struct l2tp_conn_t *conn, return l2tp_tunnel_disconnect(conn, 1, 0); } +static void l2tp_ppp_session_disconnect(void *param) +{ + struct l2tp_sess_t *sess = param; + struct l2tp_conn_t *conn = sess->paren_conn; + + l2tp_send_CDN(conn, 2, 0); + l2tp_session_free(conn); + + /* Disconnect the tunnel when all sessions have been closed */ + l2tp_tunnel_disconnect(conn, 1, 0); + conn->state = STATE_FIN; +} + static void l2tp_ppp_started(struct ap_session *ses) { log_ppp_debug("l2tp: ppp started\n"); @@ -276,15 +289,10 @@ static void l2tp_ppp_finished(struct ap_session *ses) { struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses); struct l2tp_sess_t *sess = container_of(ppp, typeof(*sess), ppp); - struct l2tp_conn_t *conn = sess->paren_conn; log_ppp_debug("l2tp: ppp finished\n"); - - if (conn->sess.state1 == STATE_PPP) { - __sync_sub_and_fetch(&stat_active, 1); - if (l2tp_tunnel_disconnect(conn, 0, 0)) - triton_context_call(&conn->ctx, (triton_event_func)l2tp_tunnel_free, conn); - } + triton_context_call(&sess->paren_conn->ctx, + l2tp_ppp_session_disconnect, sess); } static int l2tp_session_alloc(struct l2tp_conn_t *conn) -- cgit v1.2.3