Commit e1cedae1 authored by David Ahern's avatar David Ahern Committed by David S. Miller

ipmr: Refactor mr_rtm_dumproute

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: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bae9a78b
...@@ -283,6 +283,12 @@ void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg); ...@@ -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, int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
struct mr_mfc *c, struct rtmsg *rtm); 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, int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
struct mr_table *(*iter)(struct net *net, struct mr_table *(*iter)(struct net *net,
struct mr_table *mrt), struct mr_table *mrt),
......
...@@ -268,6 +268,55 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, ...@@ -268,6 +268,55 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
} }
EXPORT_SYMBOL(mr_fill_mroute); 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, int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
struct mr_table *(*iter)(struct net *net, struct mr_table *(*iter)(struct net *net,
struct mr_table *mrt), struct mr_table *mrt),
...@@ -277,51 +326,24 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb, ...@@ -277,51 +326,24 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
int cmd, int flags), int cmd, int flags),
spinlock_t *lock) 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 net *net = sock_net(skb->sk);
struct mr_table *mrt; struct mr_table *mrt;
struct mr_mfc *mfc; int err;
rcu_read_lock(); rcu_read_lock();
for (mrt = iter(net, NULL); mrt; mrt = iter(net, mrt)) { for (mrt = iter(net, NULL); mrt; mrt = iter(net, mrt)) {
if (t < s_t) if (t < s_t)
goto next_table; goto next_table;
list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
if (e < s_e) err = mr_table_dump(mrt, skb, cb, fill, lock);
goto next_entry; if (err < 0)
if (fill(mrt, skb, NETLINK_CB(cb->skb).portid, break;
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;
next_table: next_table:
t++; t++;
} }
done:
rcu_read_unlock(); rcu_read_unlock();
cb->args[1] = e;
cb->args[0] = t; cb->args[0] = t;
return skb->len; return skb->len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment