@@ -130,7 +130,7 @@ static struct mr_table *ip6mr_mr_table_iter(struct net *net,
130
130
return ret ;
131
131
}
132
132
133
- static struct mr_table * ip6mr_get_table (struct net * net , u32 id )
133
+ static struct mr_table * __ip6mr_get_table (struct net * net , u32 id )
134
134
{
135
135
struct mr_table * mrt ;
136
136
@@ -141,6 +141,16 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
141
141
return NULL ;
142
142
}
143
143
144
+ static struct mr_table * ip6mr_get_table (struct net * net , u32 id )
145
+ {
146
+ struct mr_table * mrt ;
147
+
148
+ rcu_read_lock ();
149
+ mrt = __ip6mr_get_table (net , id );
150
+ rcu_read_unlock ();
151
+ return mrt ;
152
+ }
153
+
144
154
static int ip6mr_fib_lookup (struct net * net , struct flowi6 * flp6 ,
145
155
struct mr_table * * mrt )
146
156
{
@@ -182,7 +192,7 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
182
192
183
193
arg -> table = fib_rule_get_table (rule , arg );
184
194
185
- mrt = ip6mr_get_table (rule -> fr_net , arg -> table );
195
+ mrt = __ip6mr_get_table (rule -> fr_net , arg -> table );
186
196
if (!mrt )
187
197
return - EAGAIN ;
188
198
res -> mrt = mrt ;
@@ -314,6 +324,8 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
314
324
return net -> ipv6 .mrt6 ;
315
325
}
316
326
327
+ #define __ip6mr_get_table ip6mr_get_table
328
+
317
329
static int ip6mr_fib_lookup (struct net * net , struct flowi6 * flp6 ,
318
330
struct mr_table * * mrt )
319
331
{
@@ -392,7 +404,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
392
404
{
393
405
struct mr_table * mrt ;
394
406
395
- mrt = ip6mr_get_table (net , id );
407
+ mrt = __ip6mr_get_table (net , id );
396
408
if (mrt )
397
409
return mrt ;
398
410
@@ -425,13 +437,15 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
425
437
struct net * net = seq_file_net (seq );
426
438
struct mr_table * mrt ;
427
439
428
- mrt = ip6mr_get_table (net , RT6_TABLE_DFLT );
429
- if (!mrt )
440
+ rcu_read_lock ();
441
+ mrt = __ip6mr_get_table (net , RT6_TABLE_DFLT );
442
+ if (!mrt ) {
443
+ rcu_read_unlock ();
430
444
return ERR_PTR (- ENOENT );
445
+ }
431
446
432
447
iter -> mrt = mrt ;
433
448
434
- rcu_read_lock ();
435
449
return mr_vif_seq_start (seq , pos );
436
450
}
437
451
@@ -2292,11 +2306,13 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
2292
2306
struct mfc6_cache * cache ;
2293
2307
struct rt6_info * rt = dst_rt6_info (skb_dst (skb ));
2294
2308
2295
- mrt = ip6mr_get_table (net , RT6_TABLE_DFLT );
2296
- if (!mrt )
2309
+ rcu_read_lock ();
2310
+ mrt = __ip6mr_get_table (net , RT6_TABLE_DFLT );
2311
+ if (!mrt ) {
2312
+ rcu_read_unlock ();
2297
2313
return - ENOENT ;
2314
+ }
2298
2315
2299
- rcu_read_lock ();
2300
2316
cache = ip6mr_cache_find (mrt , & rt -> rt6i_src .addr , & rt -> rt6i_dst .addr );
2301
2317
if (!cache && skb -> dev ) {
2302
2318
int vif = ip6mr_find_vif (mrt , skb -> dev );
@@ -2576,7 +2592,7 @@ static int ip6mr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
2576
2592
grp = nla_get_in6_addr (tb [RTA_DST ]);
2577
2593
tableid = nla_get_u32_default (tb [RTA_TABLE ], 0 );
2578
2594
2579
- mrt = ip6mr_get_table (net , tableid ?: RT_TABLE_DEFAULT );
2595
+ mrt = __ip6mr_get_table (net , tableid ?: RT_TABLE_DEFAULT );
2580
2596
if (!mrt ) {
2581
2597
NL_SET_ERR_MSG_MOD (extack , "MR table does not exist" );
2582
2598
return - ENOENT ;
@@ -2623,7 +2639,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2623
2639
if (filter .table_id ) {
2624
2640
struct mr_table * mrt ;
2625
2641
2626
- mrt = ip6mr_get_table (sock_net (skb -> sk ), filter .table_id );
2642
+ mrt = __ip6mr_get_table (sock_net (skb -> sk ), filter .table_id );
2627
2643
if (!mrt ) {
2628
2644
if (rtnl_msg_family (cb -> nlh ) != RTNL_FAMILY_IP6MR )
2629
2645
return skb -> len ;
0 commit comments