summaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_ppp.c
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2018-04-25 19:54:14 +0200
committerDavid S. Miller <davem@davemloft.net>2018-04-27 17:06:35 +0200
commit834944073301e85001c3ed9913027ca47c6f889b (patch)
treedeb655628c17910683936af73a8b510992404ff2 /net/l2tp/l2tp_ppp.c
parenttipc: introduce ioctl for fetching node identity (diff)
downloadlinux-834944073301e85001c3ed9913027ca47c6f889b.tar.xz
linux-834944073301e85001c3ed9913027ca47c6f889b.zip
l2tp: consistent reference counting in procfs and debufs
The 'pppol2tp' procfs and 'l2tp/tunnels' debugfs files handle reference counting of sessions differently than for tunnels. For consistency, use the same mechanism for handling both sessions and tunnels. That is, drop the reference on the previous session just before looking up the next one (rather than in .show()). If necessary (if dump stops before *_next_session() returns NULL), drop the last reference in .stop(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_ppp.c')
-rw-r--r--net/l2tp/l2tp_ppp.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 1fd9e145076a..f951c768dcf2 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1576,6 +1576,10 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
{
+ /* Drop reference taken during previous invocation */
+ if (pd->session)
+ l2tp_session_dec_refcount(pd->session);
+
pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx);
pd->session_idx++;
@@ -1624,11 +1628,16 @@ static void pppol2tp_seq_stop(struct seq_file *p, void *v)
if (!pd || pd == SEQ_START_TOKEN)
return;
- /* Drop reference taken by last invocation of pppol2tp_next_tunnel() */
+ /* Drop reference taken by last invocation of pppol2tp_next_session()
+ * or pppol2tp_next_tunnel().
+ */
+ if (pd->session) {
+ l2tp_session_dec_refcount(pd->session);
+ pd->session = NULL;
+ }
if (pd->tunnel) {
l2tp_tunnel_dec_refcount(pd->tunnel);
pd->tunnel = NULL;
- pd->session = NULL;
}
}
@@ -1723,14 +1732,10 @@ static int pppol2tp_seq_show(struct seq_file *m, void *v)
goto out;
}
- /* Show the tunnel or session context.
- */
- if (!pd->session) {
+ if (!pd->session)
pppol2tp_seq_tunnel_show(m, pd->tunnel);
- } else {
+ else
pppol2tp_seq_session_show(m, pd->session);
- l2tp_session_dec_refcount(pd->session);
- }
out:
return 0;