From: David Ahern <dsah...@gmail.com>

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 <dsah...@gmail.com>
---
 include/linux/mroute_base.h |  6 ++++
 net/ipv4/ipmr_base.c        | 88 ++++++++++++++++++++++++++++-----------------
 2 files changed, 61 insertions(+), 33 deletions(-)

diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h
index 6675b9f81979..db85373c8d15 100644
--- a/include/linux/mroute_base.h
+++ b/include/linux/mroute_base.h
@@ -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),
diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c
index 1ad9aa62a97b..132dd2613ca5 100644
--- a/net/ipv4/ipmr_base.c
+++ b/net/ipv4/ipmr_base.c
@@ -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),
@@ -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;
-- 
2.11.0

Reply via email to