Skip to content

Commit 626d16f

Browse files
lxindavem330
authored andcommitted
sctp: export some apis or variables for sctp_diag and reuse some for proc
For some main variables in sctp.ko, we couldn't export it to other modules, so we have to define some api to access them. It will include sctp transport and endpoint's traversal. There are some transport traversal functions for sctp_diag, we can also use it for sctp_proc. cause they have the similar situation to traversal transport. v2->v3: - rhashtable_walk_init need the parameter gfp, because of recent upstrem update Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 52c52a6 commit 626d16f

File tree

3 files changed

+156
-63
lines changed

3 files changed

+156
-63
lines changed

include/net/sctp/sctp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,19 @@ extern struct percpu_counter sctp_sockets_allocated;
116116
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
117117
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
118118

119+
int sctp_transport_walk_start(struct rhashtable_iter *iter);
120+
void sctp_transport_walk_stop(struct rhashtable_iter *iter);
121+
struct sctp_transport *sctp_transport_get_next(struct net *net,
122+
struct rhashtable_iter *iter);
123+
struct sctp_transport *sctp_transport_get_idx(struct net *net,
124+
struct rhashtable_iter *iter, int pos);
125+
int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
126+
struct net *net,
127+
const union sctp_addr *laddr,
128+
const union sctp_addr *paddr, void *p);
129+
int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
130+
struct net *net, int pos, void *p);
131+
int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p);
119132
int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
120133
struct sctp_info *info);
121134

net/sctp/proc.c

Lines changed: 18 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -282,81 +282,31 @@ struct sctp_ht_iter {
282282
struct rhashtable_iter hti;
283283
};
284284

285-
static struct sctp_transport *sctp_transport_get_next(struct seq_file *seq)
286-
{
287-
struct sctp_ht_iter *iter = seq->private;
288-
struct sctp_transport *t;
289-
290-
t = rhashtable_walk_next(&iter->hti);
291-
for (; t; t = rhashtable_walk_next(&iter->hti)) {
292-
if (IS_ERR(t)) {
293-
if (PTR_ERR(t) == -EAGAIN)
294-
continue;
295-
break;
296-
}
297-
298-
if (net_eq(sock_net(t->asoc->base.sk), seq_file_net(seq)) &&
299-
t->asoc->peer.primary_path == t)
300-
break;
301-
}
302-
303-
return t;
304-
}
305-
306-
static struct sctp_transport *sctp_transport_get_idx(struct seq_file *seq,
307-
loff_t pos)
308-
{
309-
void *obj = SEQ_START_TOKEN;
310-
311-
while (pos && (obj = sctp_transport_get_next(seq)) && !IS_ERR(obj))
312-
pos--;
313-
314-
return obj;
315-
}
316-
317-
static int sctp_transport_walk_start(struct seq_file *seq)
318-
{
319-
struct sctp_ht_iter *iter = seq->private;
320-
int err;
321-
322-
err = rhashtable_walk_init(&sctp_transport_hashtable, &iter->hti,
323-
GFP_KERNEL);
324-
if (err)
325-
return err;
326-
327-
err = rhashtable_walk_start(&iter->hti);
328-
329-
return err == -EAGAIN ? 0 : err;
330-
}
331-
332-
static void sctp_transport_walk_stop(struct seq_file *seq)
333-
{
334-
struct sctp_ht_iter *iter = seq->private;
335-
336-
rhashtable_walk_stop(&iter->hti);
337-
rhashtable_walk_exit(&iter->hti);
338-
}
339-
340285
static void *sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
341286
{
342-
int err = sctp_transport_walk_start(seq);
287+
struct sctp_ht_iter *iter = seq->private;
288+
int err = sctp_transport_walk_start(&iter->hti);
343289

344290
if (err)
345291
return ERR_PTR(err);
346292

347-
return sctp_transport_get_idx(seq, *pos);
293+
return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);
348294
}
349295

350296
static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
351297
{
352-
sctp_transport_walk_stop(seq);
298+
struct sctp_ht_iter *iter = seq->private;
299+
300+
sctp_transport_walk_stop(&iter->hti);
353301
}
354302

355303
static void *sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
356304
{
305+
struct sctp_ht_iter *iter = seq->private;
306+
357307
++*pos;
358308

359-
return sctp_transport_get_next(seq);
309+
return sctp_transport_get_next(seq_file_net(seq), &iter->hti);
360310
}
361311

362312
/* Display sctp associations (/proc/net/sctp/assocs). */
@@ -458,24 +408,29 @@ void sctp_assocs_proc_exit(struct net *net)
458408

459409
static void *sctp_remaddr_seq_start(struct seq_file *seq, loff_t *pos)
460410
{
461-
int err = sctp_transport_walk_start(seq);
411+
struct sctp_ht_iter *iter = seq->private;
412+
int err = sctp_transport_walk_start(&iter->hti);
462413

463414
if (err)
464415
return ERR_PTR(err);
465416

466-
return sctp_transport_get_idx(seq, *pos);
417+
return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);
467418
}
468419

469420
static void *sctp_remaddr_seq_next(struct seq_file *seq, void *v, loff_t *pos)
470421
{
422+
struct sctp_ht_iter *iter = seq->private;
423+
471424
++*pos;
472425

473-
return sctp_transport_get_next(seq);
426+
return sctp_transport_get_next(seq_file_net(seq), &iter->hti);
474427
}
475428

476429
static void sctp_remaddr_seq_stop(struct seq_file *seq, void *v)
477430
{
478-
sctp_transport_walk_stop(seq);
431+
struct sctp_ht_iter *iter = seq->private;
432+
433+
sctp_transport_walk_stop(&iter->hti);
479434
}
480435

481436
static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)

net/sctp/socket.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4288,6 +4288,131 @@ int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc,
42884288
}
42894289
EXPORT_SYMBOL_GPL(sctp_get_sctp_info);
42904290

4291+
/* use callback to avoid exporting the core structure */
4292+
int sctp_transport_walk_start(struct rhashtable_iter *iter)
4293+
{
4294+
int err;
4295+
4296+
err = rhashtable_walk_init(&sctp_transport_hashtable, iter,
4297+
GFP_KERNEL);
4298+
if (err)
4299+
return err;
4300+
4301+
err = rhashtable_walk_start(iter);
4302+
4303+
return err == -EAGAIN ? 0 : err;
4304+
}
4305+
4306+
void sctp_transport_walk_stop(struct rhashtable_iter *iter)
4307+
{
4308+
rhashtable_walk_stop(iter);
4309+
rhashtable_walk_exit(iter);
4310+
}
4311+
4312+
struct sctp_transport *sctp_transport_get_next(struct net *net,
4313+
struct rhashtable_iter *iter)
4314+
{
4315+
struct sctp_transport *t;
4316+
4317+
t = rhashtable_walk_next(iter);
4318+
for (; t; t = rhashtable_walk_next(iter)) {
4319+
if (IS_ERR(t)) {
4320+
if (PTR_ERR(t) == -EAGAIN)
4321+
continue;
4322+
break;
4323+
}
4324+
4325+
if (net_eq(sock_net(t->asoc->base.sk), net) &&
4326+
t->asoc->peer.primary_path == t)
4327+
break;
4328+
}
4329+
4330+
return t;
4331+
}
4332+
4333+
struct sctp_transport *sctp_transport_get_idx(struct net *net,
4334+
struct rhashtable_iter *iter,
4335+
int pos)
4336+
{
4337+
void *obj = SEQ_START_TOKEN;
4338+
4339+
while (pos && (obj = sctp_transport_get_next(net, iter)) &&
4340+
!IS_ERR(obj))
4341+
pos--;
4342+
4343+
return obj;
4344+
}
4345+
4346+
int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
4347+
void *p) {
4348+
int err = 0;
4349+
int hash = 0;
4350+
struct sctp_ep_common *epb;
4351+
struct sctp_hashbucket *head;
4352+
4353+
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
4354+
hash++, head++) {
4355+
read_lock(&head->lock);
4356+
sctp_for_each_hentry(epb, &head->chain) {
4357+
err = cb(sctp_ep(epb), p);
4358+
if (err)
4359+
break;
4360+
}
4361+
read_unlock(&head->lock);
4362+
}
4363+
4364+
return err;
4365+
}
4366+
EXPORT_SYMBOL_GPL(sctp_for_each_endpoint);
4367+
4368+
int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *),
4369+
struct net *net,
4370+
const union sctp_addr *laddr,
4371+
const union sctp_addr *paddr, void *p)
4372+
{
4373+
struct sctp_transport *transport;
4374+
int err = 0;
4375+
4376+
rcu_read_lock();
4377+
transport = sctp_addrs_lookup_transport(net, laddr, paddr);
4378+
if (!transport || !sctp_transport_hold(transport))
4379+
goto out;
4380+
err = cb(transport, p);
4381+
sctp_transport_put(transport);
4382+
4383+
out:
4384+
rcu_read_unlock();
4385+
return err;
4386+
}
4387+
EXPORT_SYMBOL_GPL(sctp_transport_lookup_process);
4388+
4389+
int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *),
4390+
struct net *net, int pos, void *p) {
4391+
struct rhashtable_iter hti;
4392+
int err = 0;
4393+
void *obj;
4394+
4395+
if (sctp_transport_walk_start(&hti))
4396+
goto out;
4397+
4398+
sctp_transport_get_idx(net, &hti, pos);
4399+
obj = sctp_transport_get_next(net, &hti);
4400+
for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
4401+
struct sctp_transport *transport = obj;
4402+
4403+
if (!sctp_transport_hold(transport))
4404+
continue;
4405+
err = cb(transport, p);
4406+
sctp_transport_put(transport);
4407+
if (err)
4408+
break;
4409+
}
4410+
out:
4411+
sctp_transport_walk_stop(&hti);
4412+
return err;
4413+
}
4414+
EXPORT_SYMBOL_GPL(sctp_for_each_transport);
4415+
42914416
/* 7.2.1 Association Status (SCTP_STATUS)
42924417
42934418
* Applications can retrieve current status information about an

0 commit comments

Comments
 (0)