| From 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 Mon Sep 17 00:00:00 2001 |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Wed, 1 Dec 2021 18:26:35 -0800 |
| Subject: ipv4: convert fib_num_tclassid_users to atomic_t |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| commit 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 upstream. |
| |
| Before commit faa041a40b9f ("ipv4: Create cleanup helper for fib_nh") |
| changes to net->ipv4.fib_num_tclassid_users were protected by RTNL. |
| |
| After the change, this is no longer the case, as free_fib_info_rcu() |
| runs after rcu grace period, without rtnl being held. |
| |
| Fixes: faa041a40b9f ("ipv4: Create cleanup helper for fib_nh") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Cc: David Ahern <dsahern@kernel.org> |
| Reviewed-by: David Ahern <dsahern@kernel.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| include/net/ip_fib.h | 2 +- |
| include/net/netns/ipv4.h | 2 +- |
| net/ipv4/fib_frontend.c | 2 +- |
| net/ipv4/fib_rules.c | 4 ++-- |
| net/ipv4/fib_semantics.c | 4 ++-- |
| 5 files changed, 7 insertions(+), 7 deletions(-) |
| |
| --- a/include/net/ip_fib.h |
| +++ b/include/net/ip_fib.h |
| @@ -437,7 +437,7 @@ int fib_validate_source(struct sk_buff * |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| static inline int fib_num_tclassid_users(struct net *net) |
| { |
| - return net->ipv4.fib_num_tclassid_users; |
| + return atomic_read(&net->ipv4.fib_num_tclassid_users); |
| } |
| #else |
| static inline int fib_num_tclassid_users(struct net *net) |
| --- a/include/net/netns/ipv4.h |
| +++ b/include/net/netns/ipv4.h |
| @@ -61,7 +61,7 @@ struct netns_ipv4 { |
| #endif |
| bool fib_has_custom_local_routes; |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| - int fib_num_tclassid_users; |
| + atomic_t fib_num_tclassid_users; |
| #endif |
| struct hlist_head *fib_table_hash; |
| bool fib_offload_disabled; |
| --- a/net/ipv4/fib_frontend.c |
| +++ b/net/ipv4/fib_frontend.c |
| @@ -1578,7 +1578,7 @@ static int __net_init fib_net_init(struc |
| int error; |
| |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| - net->ipv4.fib_num_tclassid_users = 0; |
| + atomic_set(&net->ipv4.fib_num_tclassid_users, 0); |
| #endif |
| error = ip_fib_net_init(net); |
| if (error < 0) |
| --- a/net/ipv4/fib_rules.c |
| +++ b/net/ipv4/fib_rules.c |
| @@ -264,7 +264,7 @@ static int fib4_rule_configure(struct fi |
| if (tb[FRA_FLOW]) { |
| rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); |
| if (rule4->tclassid) |
| - net->ipv4.fib_num_tclassid_users++; |
| + atomic_inc(&net->ipv4.fib_num_tclassid_users); |
| } |
| #endif |
| |
| @@ -296,7 +296,7 @@ static int fib4_rule_delete(struct fib_r |
| |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| if (((struct fib4_rule *)rule)->tclassid) |
| - net->ipv4.fib_num_tclassid_users--; |
| + atomic_dec(&net->ipv4.fib_num_tclassid_users); |
| #endif |
| net->ipv4.fib_has_custom_rules = true; |
| |
| --- a/net/ipv4/fib_semantics.c |
| +++ b/net/ipv4/fib_semantics.c |
| @@ -222,7 +222,7 @@ void fib_nh_release(struct net *net, str |
| { |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| if (fib_nh->nh_tclassid) |
| - net->ipv4.fib_num_tclassid_users--; |
| + atomic_dec(&net->ipv4.fib_num_tclassid_users); |
| #endif |
| fib_nh_common_release(&fib_nh->nh_common); |
| } |
| @@ -633,7 +633,7 @@ int fib_nh_init(struct net *net, struct |
| #ifdef CONFIG_IP_ROUTE_CLASSID |
| nh->nh_tclassid = cfg->fc_flow; |
| if (nh->nh_tclassid) |
| - net->ipv4.fib_num_tclassid_users++; |
| + atomic_inc(&net->ipv4.fib_num_tclassid_users); |
| #endif |
| #ifdef CONFIG_IP_ROUTE_MULTIPATH |
| nh->fib_nh_weight = nh_weight; |