Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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 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,
		   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),
+55 −33
Original line number 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);

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,
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 t = 0, e = 0, s_t = cb->args[0], s_e = cb->args[1];
	struct net *net = sock_net(skb->sk);
	struct mr_table *mrt;
	unsigned int e = 0, s_e = cb->args[1];
	unsigned int flags = NLM_F_MULTI;
	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;

		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++;
	}
@@ -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) {
		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) {

		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 done;
			goto out;
		}
next_entry2:
		e++;
	}
	spin_unlock_bh(lock);
	err = 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:
		t++;
	}
done:
	rcu_read_unlock();

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

	return skb->len;