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

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -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),
+55 −33
Original line number Original line Diff line number Diff line
@@ -268,31 +268,26 @@ int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
}
}
EXPORT_SYMBOL(mr_fill_mroute);
EXPORT_SYMBOL(mr_fill_mroute);


int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
		     struct mr_table *(*iter)(struct net *net,
		  struct netlink_callback *cb,
					      struct mr_table *mrt),
		  int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
		     int (*fill)(struct mr_table *mrt,
				 struct sk_buff *skb,
			      u32 portid, u32 seq, struct mr_mfc *c,
			      u32 portid, u32 seq, struct mr_mfc *c,
			      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 e = 0, s_e = cb->args[1];
	struct net *net = sock_net(skb->sk);
	unsigned int flags = NLM_F_MULTI;
	struct mr_table *mrt;
	struct mr_mfc *mfc;
	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) {
	list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list) {
		if (e < s_e)
		if (e < s_e)
			goto next_entry;
			goto next_entry;
			if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,

				 cb->nlh->nlmsg_seq, mfc,
		err = fill(mrt, skb, NETLINK_CB(cb->skb).portid,
				 RTM_NEWROUTE, NLM_F_MULTI) < 0)
			   cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags);
				goto done;
		if (err < 0)
			goto out;
next_entry:
next_entry:
		e++;
		e++;
	}
	}
@@ -303,25 +298,52 @@ int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
	list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
	list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) {
		if (e < s_e)
		if (e < s_e)
			goto next_entry2;
			goto next_entry2;
			if (fill(mrt, skb, NETLINK_CB(cb->skb).portid,

				 cb->nlh->nlmsg_seq, mfc,
		err = fill(mrt, skb, NETLINK_CB(cb->skb).portid,
				 RTM_NEWROUTE, NLM_F_MULTI) < 0) {
			   cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags);
		if (err < 0) {
			spin_unlock_bh(lock);
			spin_unlock_bh(lock);
				goto done;
			goto out;
		}
		}
next_entry2:
next_entry2:
		e++;
		e++;
	}
	}
	spin_unlock_bh(lock);
	spin_unlock_bh(lock);
	err = 0;
	e = 0;
	e = 0;
		s_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),
		     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 t = 0, s_t = cb->args[0];
	struct net *net = sock_net(skb->sk);
	struct mr_table *mrt;
	int err;

	rcu_read_lock();
	for (mrt = iter(net, NULL); mrt; mrt = iter(net, mrt)) {
		if (t < s_t)
			goto next_table;

		err = mr_table_dump(mrt, skb, cb, fill, lock);
		if (err < 0)
			break;
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;