@@ -142,7 +142,7 @@ static struct mr_table *ipmr_mr_table_iter(struct net *net,
142142 return ret ;
143143}
144144
145- static struct mr_table * ipmr_get_table (struct net * net , u32 id )
145+ static struct mr_table * __ipmr_get_table (struct net * net , u32 id )
146146{
147147 struct mr_table * mrt ;
148148
@@ -153,6 +153,16 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
153153 return NULL ;
154154}
155155
156+ static struct mr_table * ipmr_get_table (struct net * net , u32 id )
157+ {
158+ struct mr_table * mrt ;
159+
160+ rcu_read_lock ();
161+ mrt = __ipmr_get_table (net , id );
162+ rcu_read_unlock ();
163+ return mrt ;
164+ }
165+
156166static int ipmr_fib_lookup (struct net * net , struct flowi4 * flp4 ,
157167 struct mr_table * * mrt )
158168{
@@ -194,7 +204,7 @@ static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp,
194204
195205 arg -> table = fib_rule_get_table (rule , arg );
196206
197- mrt = ipmr_get_table (rule -> fr_net , arg -> table );
207+ mrt = __ipmr_get_table (rule -> fr_net , arg -> table );
198208 if (!mrt )
199209 return - EAGAIN ;
200210 res -> mrt = mrt ;
@@ -325,6 +335,8 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
325335 return net -> ipv4 .mrt ;
326336}
327337
338+ #define __ipmr_get_table ipmr_get_table
339+
328340static int ipmr_fib_lookup (struct net * net , struct flowi4 * flp4 ,
329341 struct mr_table * * mrt )
330342{
@@ -413,7 +425,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
413425 if (id != RT_TABLE_DEFAULT && id >= 1000000000 )
414426 return ERR_PTR (- EINVAL );
415427
416- mrt = ipmr_get_table (net , id );
428+ mrt = __ipmr_get_table (net , id );
417429 if (mrt )
418430 return mrt ;
419431
@@ -1388,7 +1400,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
13881400 goto out_unlock ;
13891401 }
13901402
1391- mrt = ipmr_get_table (net , raw_sk (sk )-> ipmr_table ? : RT_TABLE_DEFAULT );
1403+ mrt = __ipmr_get_table (net , raw_sk (sk )-> ipmr_table ? : RT_TABLE_DEFAULT );
13921404 if (!mrt ) {
13931405 ret = - ENOENT ;
13941406 goto out_unlock ;
@@ -2276,11 +2288,13 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
22762288 struct mr_table * mrt ;
22772289 int err ;
22782290
2279- mrt = ipmr_get_table (net , RT_TABLE_DEFAULT );
2280- if (!mrt )
2291+ rcu_read_lock ();
2292+ mrt = __ipmr_get_table (net , RT_TABLE_DEFAULT );
2293+ if (!mrt ) {
2294+ rcu_read_unlock ();
22812295 return - ENOENT ;
2296+ }
22822297
2283- rcu_read_lock ();
22842298 cache = ipmr_cache_find (mrt , saddr , daddr );
22852299 if (!cache && skb -> dev ) {
22862300 int vif = ipmr_find_vif (mrt , skb -> dev );
@@ -2564,7 +2578,7 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
25642578 grp = nla_get_in_addr_default (tb [RTA_DST ], 0 );
25652579 tableid = nla_get_u32_default (tb [RTA_TABLE ], 0 );
25662580
2567- mrt = ipmr_get_table (net , tableid ? tableid : RT_TABLE_DEFAULT );
2581+ mrt = __ipmr_get_table (net , tableid ? tableid : RT_TABLE_DEFAULT );
25682582 if (!mrt ) {
25692583 err = - ENOENT ;
25702584 goto errout_free ;
@@ -2618,7 +2632,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
26182632 if (filter .table_id ) {
26192633 struct mr_table * mrt ;
26202634
2621- mrt = ipmr_get_table (sock_net (skb -> sk ), filter .table_id );
2635+ mrt = __ipmr_get_table (sock_net (skb -> sk ), filter .table_id );
26222636 if (!mrt ) {
26232637 if (rtnl_msg_family (cb -> nlh ) != RTNL_FAMILY_IPMR )
26242638 return skb -> len ;
@@ -2726,7 +2740,7 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
27262740 break ;
27272741 }
27282742 }
2729- mrt = ipmr_get_table (net , tblid );
2743+ mrt = __ipmr_get_table (net , tblid );
27302744 if (!mrt ) {
27312745 ret = - ENOENT ;
27322746 goto out ;
@@ -2934,13 +2948,15 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
29342948 struct net * net = seq_file_net (seq );
29352949 struct mr_table * mrt ;
29362950
2937- mrt = ipmr_get_table (net , RT_TABLE_DEFAULT );
2938- if (!mrt )
2951+ rcu_read_lock ();
2952+ mrt = __ipmr_get_table (net , RT_TABLE_DEFAULT );
2953+ if (!mrt ) {
2954+ rcu_read_unlock ();
29392955 return ERR_PTR (- ENOENT );
2956+ }
29402957
29412958 iter -> mrt = mrt ;
29422959
2943- rcu_read_lock ();
29442960 return mr_vif_seq_start (seq , pos );
29452961}
29462962
0 commit comments