Skip to content

Commit 22e36ea

Browse files
edumazetdavem330
authored andcommitted
inet: allow ip_valid_fib_dump_req() to be called with RTNL or RCU
Add a new field into struct fib_dump_filter, to let callers tell if they use RTNL locking or RCU. This is used in the following patch, when inet_dump_fib() no longer holds RTNL. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Donald Hunter <donald.hunter@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 69fdb7e commit 22e36ea

File tree

6 files changed

+26
-9
lines changed

6 files changed

+26
-9
lines changed

include/net/ip_fib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ struct fib_dump_filter {
264264
bool filter_set;
265265
bool dump_routes;
266266
bool dump_exceptions;
267+
bool rtnl_held;
267268
unsigned char protocol;
268269
unsigned char rt_type;
269270
unsigned int flags;

net/ipv4/fib_frontend.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,8 @@ int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
916916
struct rtmsg *rtm;
917917
int err, i;
918918

919-
ASSERT_RTNL();
919+
if (filter->rtnl_held)
920+
ASSERT_RTNL();
920921

921922
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*rtm))) {
922923
NL_SET_ERR_MSG(extack, "Invalid header for FIB dump request");
@@ -961,7 +962,10 @@ int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
961962
break;
962963
case RTA_OIF:
963964
ifindex = nla_get_u32(tb[i]);
964-
filter->dev = __dev_get_by_index(net, ifindex);
965+
if (filter->rtnl_held)
966+
filter->dev = __dev_get_by_index(net, ifindex);
967+
else
968+
filter->dev = dev_get_by_index_rcu(net, ifindex);
965969
if (!filter->dev)
966970
return -ENODEV;
967971
break;
@@ -983,8 +987,11 @@ EXPORT_SYMBOL_GPL(ip_valid_fib_dump_req);
983987

984988
static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
985989
{
986-
struct fib_dump_filter filter = { .dump_routes = true,
987-
.dump_exceptions = true };
990+
struct fib_dump_filter filter = {
991+
.dump_routes = true,
992+
.dump_exceptions = true,
993+
.rtnl_held = true,
994+
};
988995
const struct nlmsghdr *nlh = cb->nlh;
989996
struct net *net = sock_net(skb->sk);
990997
unsigned int h, s_h;

net/ipv4/ipmr.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2587,7 +2587,9 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
25872587

25882588
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
25892589
{
2590-
struct fib_dump_filter filter = {};
2590+
struct fib_dump_filter filter = {
2591+
.rtnl_held = true,
2592+
};
25912593
int err;
25922594

25932595
if (cb->strict_check) {

net/ipv6/ip6_fib.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,11 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
620620

621621
static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
622622
{
623-
struct rt6_rtnl_dump_arg arg = { .filter.dump_exceptions = true,
624-
.filter.dump_routes = true };
623+
struct rt6_rtnl_dump_arg arg = {
624+
.filter.dump_exceptions = true,
625+
.filter.dump_routes = true,
626+
.filter.rtnl_held = true,
627+
};
625628
const struct nlmsghdr *nlh = cb->nlh;
626629
struct net *net = sock_net(skb->sk);
627630
unsigned int h, s_h;

net/ipv6/ip6mr.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2592,7 +2592,9 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
25922592
static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
25932593
{
25942594
const struct nlmsghdr *nlh = cb->nlh;
2595-
struct fib_dump_filter filter = {};
2595+
struct fib_dump_filter filter = {
2596+
.rtnl_held = true,
2597+
};
25962598
int err;
25972599

25982600
if (cb->strict_check) {

net/mpls/af_mpls.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2179,7 +2179,9 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
21792179
const struct nlmsghdr *nlh = cb->nlh;
21802180
struct net *net = sock_net(skb->sk);
21812181
struct mpls_route __rcu **platform_label;
2182-
struct fib_dump_filter filter = {};
2182+
struct fib_dump_filter filter = {
2183+
.rtnl_held = true,
2184+
};
21832185
unsigned int flags = NLM_F_MULTI;
21842186
size_t platform_labels;
21852187
unsigned int index;

0 commit comments

Comments
 (0)