Skip to content

Commit 7f7c6bb

Browse files
committed
Merge branch 'ipv6-follow-up-for-rtnl-free-rtm_newroute-series'
Kuniyuki Iwashima says: ==================== ipv6: Follow up for RTNL-free RTM_NEWROUTE series. Patch 1 removes rcu_read_lock() in fib6_get_table(). Patch 2 removes rtnl_is_held arg for lwtunnel_valid_encap_type(), which was short-term fix and is no longer used. Patch 3 fixes RCU vs GFP_KERNEL report by syzkaller. Patch 4~7 reverts GFP_ATOMIC uses to GFP_KERNEL. v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 5b1ced4 + 002dba1 commit 7f7c6bb

File tree

8 files changed

+131
-220
lines changed

8 files changed

+131
-220
lines changed

include/net/lwtunnel.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,9 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
116116
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
117117
unsigned int num);
118118
int lwtunnel_valid_encap_type(u16 encap_type,
119-
struct netlink_ext_ack *extack,
120-
bool rtnl_is_held);
119+
struct netlink_ext_ack *extack);
121120
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
122-
struct netlink_ext_ack *extack,
123-
bool rtnl_is_held);
121+
struct netlink_ext_ack *extack);
124122
int lwtunnel_build_state(struct net *net, u16 encap_type,
125123
struct nlattr *encap,
126124
unsigned int family, const void *cfg,
@@ -203,15 +201,14 @@ static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
203201
}
204202

205203
static inline int lwtunnel_valid_encap_type(u16 encap_type,
206-
struct netlink_ext_ack *extack,
207-
bool rtnl_is_held)
204+
struct netlink_ext_ack *extack)
208205
{
209206
NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
210207
return -EOPNOTSUPP;
211208
}
209+
212210
static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
213-
struct netlink_ext_ack *extack,
214-
bool rtnl_is_held)
211+
struct netlink_ext_ack *extack)
215212
{
216213
/* return 0 since we are not walking attr looking for
217214
* RTA_ENCAP_TYPE attribute on nexthops.

net/core/lwtunnel.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ int lwtunnel_build_state(struct net *net, u16 encap_type,
149149
}
150150
EXPORT_SYMBOL_GPL(lwtunnel_build_state);
151151

152-
int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack,
153-
bool rtnl_is_held)
152+
int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack)
154153
{
155154
const struct lwtunnel_encap_ops *ops;
156155
int ret = -EINVAL;
@@ -167,12 +166,7 @@ int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack,
167166
const char *encap_type_str = lwtunnel_encap_str(encap_type);
168167

169168
if (encap_type_str) {
170-
if (rtnl_is_held)
171-
__rtnl_unlock();
172169
request_module("rtnl-lwt-%s", encap_type_str);
173-
if (rtnl_is_held)
174-
rtnl_lock();
175-
176170
ops = rcu_access_pointer(lwtun_encaps[encap_type]);
177171
}
178172
}
@@ -186,8 +180,7 @@ int lwtunnel_valid_encap_type(u16 encap_type, struct netlink_ext_ack *extack,
186180
EXPORT_SYMBOL_GPL(lwtunnel_valid_encap_type);
187181

188182
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining,
189-
struct netlink_ext_ack *extack,
190-
bool rtnl_is_held)
183+
struct netlink_ext_ack *extack)
191184
{
192185
struct rtnexthop *rtnh = (struct rtnexthop *)attr;
193186
struct nlattr *nla_entype;
@@ -208,9 +201,7 @@ int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining,
208201
}
209202
encap_type = nla_get_u16(nla_entype);
210203

211-
if (lwtunnel_valid_encap_type(encap_type,
212-
extack,
213-
rtnl_is_held) != 0)
204+
if (lwtunnel_valid_encap_type(encap_type, extack))
214205
return -EOPNOTSUPP;
215206
}
216207
}

net/ipv4/fib_frontend.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
807807
case RTA_MULTIPATH:
808808
err = lwtunnel_valid_encap_type_attr(nla_data(attr),
809809
nla_len(attr),
810-
extack, false);
810+
extack);
811811
if (err < 0)
812812
goto errout;
813813
cfg->fc_mp = nla_data(attr);
@@ -825,7 +825,7 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
825825
case RTA_ENCAP_TYPE:
826826
cfg->fc_encap_type = nla_get_u16(attr);
827827
err = lwtunnel_valid_encap_type(cfg->fc_encap_type,
828-
extack, false);
828+
extack);
829829
if (err < 0)
830830
goto errout;
831831
break;

net/ipv4/fib_semantics.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,10 @@ int fib_nh_common_init(struct net *net, struct fib_nh_common *nhc,
617617
{
618618
int err;
619619

620-
if (!nhc->nhc_pcpu_rth_output) {
621-
nhc->nhc_pcpu_rth_output = alloc_percpu_gfp(struct rtable __rcu *,
622-
gfp_flags);
623-
if (!nhc->nhc_pcpu_rth_output)
624-
return -ENOMEM;
625-
}
620+
nhc->nhc_pcpu_rth_output = alloc_percpu_gfp(struct rtable __rcu *,
621+
gfp_flags);
622+
if (!nhc->nhc_pcpu_rth_output)
623+
return -ENOMEM;
626624

627625
if (encap) {
628626
struct lwtunnel_state *lwtstate;

net/ipv4/nexthop.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3180,8 +3180,7 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
31803180
}
31813181

31823182
cfg->nh_encap_type = nla_get_u16(tb[NHA_ENCAP_TYPE]);
3183-
err = lwtunnel_valid_encap_type(cfg->nh_encap_type,
3184-
extack, false);
3183+
err = lwtunnel_valid_encap_type(cfg->nh_encap_type, extack);
31853184
if (err < 0)
31863185
goto out;
31873186

net/ipv6/ip6_fib.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -281,22 +281,20 @@ EXPORT_SYMBOL_GPL(fib6_new_table);
281281

282282
struct fib6_table *fib6_get_table(struct net *net, u32 id)
283283
{
284-
struct fib6_table *tb;
285284
struct hlist_head *head;
286-
unsigned int h;
285+
struct fib6_table *tb;
287286

288-
if (id == 0)
287+
if (!id)
289288
id = RT6_TABLE_MAIN;
290-
h = id & (FIB6_TABLE_HASHSZ - 1);
291-
rcu_read_lock();
292-
head = &net->ipv6.fib_table_hash[h];
293-
hlist_for_each_entry_rcu(tb, head, tb6_hlist) {
294-
if (tb->tb6_id == id) {
295-
rcu_read_unlock();
289+
290+
head = &net->ipv6.fib_table_hash[id & (FIB6_TABLE_HASHSZ - 1)];
291+
292+
/* See comment in fib6_link_table(). RCU is not required,
293+
* but rcu_dereference_raw() is used to avoid data-race.
294+
*/
295+
hlist_for_each_entry_rcu(tb, head, tb6_hlist, true)
296+
if (tb->tb6_id == id)
296297
return tb;
297-
}
298-
}
299-
rcu_read_unlock();
300298

301299
return NULL;
302300
}
@@ -1029,8 +1027,9 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i,
10291027
.table = table
10301028
};
10311029

1032-
nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_drop_pcpu_from,
1033-
&arg);
1030+
rcu_read_lock();
1031+
nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_drop_pcpu_from, &arg);
1032+
rcu_read_unlock();
10341033
} else {
10351034
struct fib6_nh *fib6_nh;
10361035

@@ -1223,7 +1222,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
12231222
fib6_nsiblings++;
12241223
}
12251224
BUG_ON(fib6_nsiblings != rt->fib6_nsiblings);
1225+
rcu_read_lock();
12261226
rt6_multipath_rebalance(temp_sibling);
1227+
rcu_read_unlock();
12271228
}
12281229

12291230
/*
@@ -1266,7 +1267,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
12661267
sibling->fib6_nsiblings--;
12671268
rt->fib6_nsiblings = 0;
12681269
list_del_rcu(&rt->fib6_siblings);
1270+
rcu_read_lock();
12691271
rt6_multipath_rebalance(next_sibling);
1272+
rcu_read_unlock();
12701273
return err;
12711274
}
12721275
}

0 commit comments

Comments
 (0)