Skip to content

Commit

Permalink
ipmr: Refactor mr_rtm_dumproute
Browse files Browse the repository at this point in the history
Move per-table loops from mr_rtm_dumproute to mr_table_dump and export
mr_table_dump for dumps by specific table id.

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David Ahern authored and David S. Miller committed Oct 16, 2018
1 parent bae9a78 commit e1cedae
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 33 deletions.
6 changes: 6 additions & 0 deletions include/linux/mroute_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);

int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
struct mr_mfc *c, struct rtmsg *rtm);
int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
struct netlink_callback *cb,
int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
u32 portid, u32 seq, struct mr_mfc *c,
int cmd, int flags),
spinlock_t *lock);
int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
struct mr_table *(*iter)(struct net *net,
struct mr_table *mrt),
Expand Down
88 changes: 55 additions & 33 deletions net/ipv4/ipmr_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,55 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
}
EXPORT_SYMBOL(mr_fill_mroute);

int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
struct netlink_callback *cb,
int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
u32 portid, u32 seq, struct mr_mfc *c,
int cmd, int flags),
spinlock_t *lock)
{
unsigned int e = 0, s_e = cb->args[1];
unsigned int flags = NLM_F_MULTI;
struct mr_mfc *mfc;
int err;

list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
if (e < s_e)
goto next_entry;

err = fill(mrt, skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags);
if (err < 0)
goto out;
next_entry:
e++;
}
e = 0;
s_e = 0;

spin_lock_bh(lock);
list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
if (e < s_e)
goto next_entry2;

err = fill(mrt, skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags);
if (err < 0) {
spin_unlock_bh(lock);
goto out;
}
next_entry2:
e++;
}
spin_unlock_bh(lock);
err = 0;
e = 0;

out:
cb->args[1] = e;
return err;
}

int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
struct mr_table *(*iter)(struct net *net,
struct mr_table *mrt),
Expand All @@ -277,51 +326,24 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
int cmd, int flags),
spinlock_t *lock)
{
unsigned int t = 0, e = 0, s_t = cb->args[0], s_e = cb->args[1];
unsigned int t = 0, s_t = cb->args[0];
struct net *net = sock_net(skb->sk);
struct mr_table *mrt;
struct mr_mfc *mfc;
int err;

rcu_read_lock();
for (mrt = iter(net, NULL); mrt; mrt = iter(net, mrt)) {
if (t < s_t)
goto next_table;
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
if (e < s_e)
goto next_entry;
if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, mfc,
RTM_NEWROUTE, NLM_F_MULTI) < 0)
goto done;
next_entry:
e++;
}
e = 0;
s_e = 0;

spin_lock_bh(lock);
list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
if (e < s_e)
goto next_entry2;
if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, mfc,
RTM_NEWROUTE, NLM_F_MULTI) < 0) {
spin_unlock_bh(lock);
goto done;
}
next_entry2:
e++;
}
spin_unlock_bh(lock);
e = 0;
s_e = 0;

err = mr_table_dump(mrt, skb, cb, fill, lock);
if (err < 0)
break;
next_table:
t++;
}
done:
rcu_read_unlock();

cb->args[1] = e;
cb->args[0] = t;

return skb->len;
Expand Down

0 comments on commit e1cedae

Please sign in to comment.