diff options
author | Petr Machata | 2021-01-28 13:49:22 +0100 |
---|---|---|
committer | Jakub Kicinski | 2021-01-28 20:49:53 -0800 |
commit | cbee18071e72b68d63b055655ac96ae97126776e (patch) | |
tree | 20e6b33ba4117242c2d923e2d4b682d8c486b45a /net/ipv4 | |
parent | a6fbbaa64c3b0e744e7e421a13658a7441f5a9f3 (diff) |
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: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/nexthop.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 7ae197efa5a9..e5175f531ffb 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -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) { - if (likely(skb->len)) - goto out; - - goto out_err; - } + 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; + } + out: err = skb->len; out_err: - ctx->idx = idx; cb->seq = net->nexthop.seq; nl_dump_check_consistent(cb, nlmsg_hdr(skb)); - return err; } |