Skip to content

Commit 9084ab1

Browse files
j-c-hNipaLocal
authored andcommitted
l2tp: use get_next APIs for management requests and procfs/debugfs
l2tp netlink and procfs/debugfs iterate over tunnel and session lists to obtain data. They currently use very inefficient get_nth functions to do so. Replace these with get_next. For netlink, use nl cb->ctx[] for passing state instead of the obsolete cb->args[]. l2tp_tunnel_get_nth and l2tp_session_get_nth are no longer used so they can be removed. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: Tom Parkin <tparkin@katalix.com> Signed-off-by: NipaLocal <nipa@local>
1 parent 8d5187a commit 9084ab1

File tree

5 files changed

+39
-69
lines changed

5 files changed

+39
-69
lines changed

net/l2tp/l2tp_core.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -236,27 +236,6 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
236236
}
237237
EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
238238

239-
struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
240-
{
241-
struct l2tp_net *pn = l2tp_pernet(net);
242-
unsigned long tunnel_id, tmp;
243-
struct l2tp_tunnel *tunnel;
244-
int count = 0;
245-
246-
rcu_read_lock_bh();
247-
idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) {
248-
if (tunnel && ++count > nth &&
249-
refcount_inc_not_zero(&tunnel->ref_count)) {
250-
rcu_read_unlock_bh();
251-
return tunnel;
252-
}
253-
}
254-
rcu_read_unlock_bh();
255-
256-
return NULL;
257-
}
258-
EXPORT_SYMBOL_GPL(l2tp_tunnel_get_nth);
259-
260239
struct l2tp_tunnel *l2tp_tunnel_get_next(const struct net *net, unsigned long *key)
261240
{
262241
struct l2tp_net *pn = l2tp_pernet(net);
@@ -350,25 +329,6 @@ struct l2tp_session *l2tp_session_get(const struct net *net, struct sock *sk, in
350329
}
351330
EXPORT_SYMBOL_GPL(l2tp_session_get);
352331

353-
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth)
354-
{
355-
struct l2tp_session *session;
356-
int count = 0;
357-
358-
rcu_read_lock_bh();
359-
list_for_each_entry_rcu(session, &tunnel->session_list, list) {
360-
if (++count > nth) {
361-
l2tp_session_inc_refcount(session);
362-
rcu_read_unlock_bh();
363-
return session;
364-
}
365-
}
366-
rcu_read_unlock_bh();
367-
368-
return NULL;
369-
}
370-
EXPORT_SYMBOL_GPL(l2tp_session_get_nth);
371-
372332
static struct l2tp_session *l2tp_v2_session_get_next(const struct net *net, u16 tid, unsigned long *key)
373333
{
374334
struct l2tp_net *pn = l2tp_pernet(net);

net/l2tp/l2tp_core.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,12 @@ void l2tp_session_dec_refcount(struct l2tp_session *session);
219219
* the caller must ensure that the reference is dropped appropriately.
220220
*/
221221
struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
222-
struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth);
223222
struct l2tp_tunnel *l2tp_tunnel_get_next(const struct net *net, unsigned long *key);
224223

225224
struct l2tp_session *l2tp_v3_session_get(const struct net *net, struct sock *sk, u32 session_id);
226225
struct l2tp_session *l2tp_v2_session_get(const struct net *net, u16 tunnel_id, u16 session_id);
227226
struct l2tp_session *l2tp_session_get(const struct net *net, struct sock *sk, int pver,
228227
u32 tunnel_id, u32 session_id);
229-
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
230228
struct l2tp_session *l2tp_session_get_next(const struct net *net, struct sock *sk, int pver,
231229
u32 tunnel_id, unsigned long *key);
232230
struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,

net/l2tp/l2tp_debugfs.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ static struct dentry *rootdir;
3434
struct l2tp_dfs_seq_data {
3535
struct net *net;
3636
netns_tracker ns_tracker;
37-
int tunnel_idx; /* current tunnel */
38-
int session_idx; /* index of session within current tunnel */
37+
unsigned long tkey; /* lookup key of current tunnel */
38+
unsigned long skey; /* lookup key of current session */
3939
struct l2tp_tunnel *tunnel;
4040
struct l2tp_session *session; /* NULL means get next tunnel */
4141
};
@@ -46,8 +46,8 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd)
4646
if (pd->tunnel)
4747
l2tp_tunnel_dec_refcount(pd->tunnel);
4848

49-
pd->tunnel = l2tp_tunnel_get_nth(pd->net, pd->tunnel_idx);
50-
pd->tunnel_idx++;
49+
pd->tunnel = l2tp_tunnel_get_next(pd->net, &pd->tkey);
50+
pd->tkey++;
5151
}
5252

5353
static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
@@ -56,11 +56,13 @@ static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
5656
if (pd->session)
5757
l2tp_session_dec_refcount(pd->session);
5858

59-
pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx);
60-
pd->session_idx++;
59+
pd->session = l2tp_session_get_next(pd->net, pd->tunnel->sock,
60+
pd->tunnel->version,
61+
pd->tunnel->tunnel_id, &pd->skey);
62+
pd->skey++;
6163

6264
if (!pd->session) {
63-
pd->session_idx = 0;
65+
pd->skey = 0;
6466
l2tp_dfs_next_tunnel(pd);
6567
}
6668
}

net/l2tp/l2tp_netlink.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,20 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
491491
return ret;
492492
}
493493

494+
struct l2tp_nl_cb_data {
495+
unsigned long tkey;
496+
unsigned long skey;
497+
};
498+
494499
static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
495500
{
496-
int ti = cb->args[0];
501+
struct l2tp_nl_cb_data *cbd = (void *)&cb->ctx[0];
502+
unsigned long key = cbd->tkey;
497503
struct l2tp_tunnel *tunnel;
498504
struct net *net = sock_net(skb->sk);
499505

500506
for (;;) {
501-
tunnel = l2tp_tunnel_get_nth(net, ti);
507+
tunnel = l2tp_tunnel_get_next(net, &key);
502508
if (!tunnel)
503509
goto out;
504510

@@ -510,11 +516,11 @@ static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback
510516
}
511517
l2tp_tunnel_dec_refcount(tunnel);
512518

513-
ti++;
519+
key++;
514520
}
515521

516522
out:
517-
cb->args[0] = ti;
523+
cbd->tkey = key;
518524

519525
return skb->len;
520526
}
@@ -832,25 +838,27 @@ static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
832838

833839
static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback *cb)
834840
{
841+
struct l2tp_nl_cb_data *cbd = (void *)&cb->ctx[0];
835842
struct net *net = sock_net(skb->sk);
836843
struct l2tp_session *session;
837844
struct l2tp_tunnel *tunnel = NULL;
838-
int ti = cb->args[0];
839-
int si = cb->args[1];
845+
unsigned long tkey = cbd->tkey;
846+
unsigned long skey = cbd->skey;
840847

841848
for (;;) {
842849
if (!tunnel) {
843-
tunnel = l2tp_tunnel_get_nth(net, ti);
850+
tunnel = l2tp_tunnel_get_next(net, &tkey);
844851
if (!tunnel)
845852
goto out;
846853
}
847854

848-
session = l2tp_session_get_nth(tunnel, si);
855+
session = l2tp_session_get_next(net, tunnel->sock, tunnel->version,
856+
tunnel->tunnel_id, &skey);
849857
if (!session) {
850-
ti++;
858+
tkey++;
851859
l2tp_tunnel_dec_refcount(tunnel);
852860
tunnel = NULL;
853-
si = 0;
861+
skey = 0;
854862
continue;
855863
}
856864

@@ -863,12 +871,12 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
863871
}
864872
l2tp_session_dec_refcount(session);
865873

866-
si++;
874+
skey++;
867875
}
868876

869877
out:
870-
cb->args[0] = ti;
871-
cb->args[1] = si;
878+
cbd->tkey = tkey;
879+
cbd->skey = skey;
872880

873881
return skb->len;
874882
}

net/l2tp/l2tp_ppp.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,8 +1397,8 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
13971397

13981398
struct pppol2tp_seq_data {
13991399
struct seq_net_private p;
1400-
int tunnel_idx; /* current tunnel */
1401-
int session_idx; /* index of session within current tunnel */
1400+
unsigned long tkey; /* lookup key of current tunnel */
1401+
unsigned long skey; /* lookup key of current session */
14021402
struct l2tp_tunnel *tunnel;
14031403
struct l2tp_session *session; /* NULL means get next tunnel */
14041404
};
@@ -1410,8 +1410,8 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
14101410
l2tp_tunnel_dec_refcount(pd->tunnel);
14111411

14121412
for (;;) {
1413-
pd->tunnel = l2tp_tunnel_get_nth(net, pd->tunnel_idx);
1414-
pd->tunnel_idx++;
1413+
pd->tunnel = l2tp_tunnel_get_next(net, &pd->tkey);
1414+
pd->tkey++;
14151415

14161416
/* Only accept L2TPv2 tunnels */
14171417
if (!pd->tunnel || pd->tunnel->version == 2)
@@ -1427,11 +1427,13 @@ static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
14271427
if (pd->session)
14281428
l2tp_session_dec_refcount(pd->session);
14291429

1430-
pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx);
1431-
pd->session_idx++;
1430+
pd->session = l2tp_session_get_next(net, pd->tunnel->sock,
1431+
pd->tunnel->version,
1432+
pd->tunnel->tunnel_id, &pd->skey);
1433+
pd->skey++;
14321434

14331435
if (!pd->session) {
1434-
pd->session_idx = 0;
1436+
pd->skey = 0;
14351437
pppol2tp_next_tunnel(net, pd);
14361438
}
14371439
}

0 commit comments

Comments
 (0)