Commit cbee1807 authored by Petr Machata's avatar Petr Machata Committed by Jakub Kicinski
Browse files

nexthop: Extract a helper for walking the next-hop tree



Extract from rtm_dump_nexthop() a helper to walk the next hop tree. A
separate function for this will be reusable from the bucket dumper.

Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a6fbbaa6
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -2079,22 +2079,17 @@ rtm_dump_nh_ctx(struct netlink_callback *cb)
	return ctx;
}

/* rtnl */
static int rtm_dump_nexthop(struct sk_buff *skb, struct netlink_callback *cb)
static int rtm_dump_walk_nexthops(struct sk_buff *skb,
				  struct netlink_callback *cb,
				  struct rb_root *root,
				  struct rtm_dump_nh_ctx *ctx,
				  struct nh_dump_filter *filter)
{
	struct rtm_dump_nh_ctx *ctx = rtm_dump_nh_ctx(cb);
	struct nhmsg *nhm = nlmsg_data(cb->nlh);
	struct net *net = sock_net(skb->sk);
	struct rb_root *root = &net->nexthop.rb_root;
	struct nh_dump_filter filter = {};
	struct rb_node *node;
	int idx = 0, s_idx;
	int err;

	err = nh_valid_dump_req(cb->nlh, &filter, cb);
	if (err < 0)
		return err;

	s_idx = ctx->idx;
	for (node = rb_first(root); node; node = rb_next(node)) {
		struct nexthop *nh;
@@ -2103,29 +2098,48 @@ static int rtm_dump_nexthop(struct sk_buff *skb, struct netlink_callback *cb)
			goto cont;

		nh = rb_entry(node, struct nexthop, rb_node);
		if (nh_dump_filtered(nh, &filter, nhm->nh_family))
		if (nh_dump_filtered(nh, filter, nhm->nh_family))
			goto cont;

		ctx->idx = idx;
		err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP,
				   NETLINK_CB(cb->skb).portid,
				   cb->nlh->nlmsg_seq, NLM_F_MULTI);
		if (err < 0)
			return err;
cont:
		idx++;
	}

	ctx->idx = idx;
	return 0;
}

/* rtnl */
static int rtm_dump_nexthop(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct rtm_dump_nh_ctx *ctx = rtm_dump_nh_ctx(cb);
	struct net *net = sock_net(skb->sk);
	struct rb_root *root = &net->nexthop.rb_root;
	struct nh_dump_filter filter = {};
	int err;

	err = nh_valid_dump_req(cb->nlh, &filter, cb);
	if (err < 0)
		return err;

	err = rtm_dump_walk_nexthops(skb, cb, root, ctx, &filter);
	if (err < 0) {
		if (likely(skb->len))
			goto out;

		goto out_err;
	}
cont:
		idx++;
	}

out:
	err = skb->len;
out_err:
	ctx->idx = idx;
	cb->seq = net->nexthop.seq;
	nl_dump_check_consistent(cb, nlmsg_hdr(skb));

	return err;
}