@@ -130,7 +130,7 @@ static struct mr_table *ip6mr_mr_table_iter(struct net *net,
130130 return ret ;
131131}
132132
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 )
134134{
135135 struct mr_table * mrt ;
136136
@@ -141,6 +141,16 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
141141 return NULL ;
142142}
143143
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+
144154static int ip6mr_fib_lookup (struct net * net , struct flowi6 * flp6 ,
145155 struct mr_table * * mrt )
146156{
@@ -182,7 +192,7 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
182192
183193 arg -> table = fib_rule_get_table (rule , arg );
184194
185- mrt = ip6mr_get_table (rule -> fr_net , arg -> table );
195+ mrt = __ip6mr_get_table (rule -> fr_net , arg -> table );
186196 if (!mrt )
187197 return - EAGAIN ;
188198 res -> mrt = mrt ;
@@ -314,6 +324,8 @@ static struct mr_table *ip6mr_get_table(struct net *net, u32 id)
314324 return net -> ipv6 .mrt6 ;
315325}
316326
327+ #define __ip6mr_get_table ip6mr_get_table
328+
317329static int ip6mr_fib_lookup (struct net * net , struct flowi6 * flp6 ,
318330 struct mr_table * * mrt )
319331{
@@ -392,7 +404,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
392404{
393405 struct mr_table * mrt ;
394406
395- mrt = ip6mr_get_table (net , id );
407+ mrt = __ip6mr_get_table (net , id );
396408 if (mrt )
397409 return mrt ;
398410
@@ -425,13 +437,15 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
425437 struct net * net = seq_file_net (seq );
426438 struct mr_table * mrt ;
427439
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 ();
430444 return ERR_PTR (- ENOENT );
445+ }
431446
432447 iter -> mrt = mrt ;
433448
434- rcu_read_lock ();
435449 return mr_vif_seq_start (seq , pos );
436450}
437451
@@ -2292,11 +2306,13 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
22922306 struct mfc6_cache * cache ;
22932307 struct rt6_info * rt = dst_rt6_info (skb_dst (skb ));
22942308
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 ();
22972313 return - ENOENT ;
2314+ }
22982315
2299- rcu_read_lock ();
23002316 cache = ip6mr_cache_find (mrt , & rt -> rt6i_src .addr , & rt -> rt6i_dst .addr );
23012317 if (!cache && skb -> dev ) {
23022318 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,
25762592 grp = nla_get_in6_addr (tb [RTA_DST ]);
25772593 tableid = nla_get_u32_default (tb [RTA_TABLE ], 0 );
25782594
2579- mrt = ip6mr_get_table (net , tableid ?: RT_TABLE_DEFAULT );
2595+ mrt = __ip6mr_get_table (net , tableid ?: RT_TABLE_DEFAULT );
25802596 if (!mrt ) {
25812597 NL_SET_ERR_MSG_MOD (extack , "MR table does not exist" );
25822598 return - ENOENT ;
@@ -2623,7 +2639,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
26232639 if (filter .table_id ) {
26242640 struct mr_table * mrt ;
26252641
2626- mrt = ip6mr_get_table (sock_net (skb -> sk ), filter .table_id );
2642+ mrt = __ip6mr_get_table (sock_net (skb -> sk ), filter .table_id );
26272643 if (!mrt ) {
26282644 if (rtnl_msg_family (cb -> nlh ) != RTNL_FAMILY_IP6MR )
26292645 return skb -> len ;
0 commit comments