@@ -399,10 +399,10 @@ static void icmp_push_reply(struct sock *sk,
399399
400400static void icmp_reply (struct icmp_bxm * icmp_param , struct sk_buff * skb )
401401{
402- struct ipcm_cookie ipc ;
403402 struct rtable * rt = skb_rtable (skb );
404- struct net * net = dev_net (rt -> dst .dev );
403+ struct net * net = dev_net_rcu (rt -> dst .dev );
405404 bool apply_ratelimit = false;
405+ struct ipcm_cookie ipc ;
406406 struct flowi4 fl4 ;
407407 struct sock * sk ;
408408 struct inet_sock * inet ;
@@ -608,12 +608,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
608608 struct sock * sk ;
609609
610610 if (!rt )
611- goto out ;
611+ return ;
612+
613+ rcu_read_lock ();
612614
613615 if (rt -> dst .dev )
614- net = dev_net (rt -> dst .dev );
616+ net = dev_net_rcu (rt -> dst .dev );
615617 else if (skb_in -> dev )
616- net = dev_net (skb_in -> dev );
618+ net = dev_net_rcu (skb_in -> dev );
617619 else
618620 goto out ;
619621
@@ -785,7 +787,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
785787 icmp_xmit_unlock (sk );
786788out_bh_enable :
787789 local_bh_enable ();
788- out :;
790+ out :
791+ rcu_read_unlock ();
789792}
790793EXPORT_SYMBOL (__icmp_send );
791794
@@ -834,7 +837,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
834837 * avoid additional coding at protocol handlers.
835838 */
836839 if (!pskb_may_pull (skb , iph -> ihl * 4 + 8 )) {
837- __ICMP_INC_STATS (dev_net (skb -> dev ), ICMP_MIB_INERRORS );
840+ __ICMP_INC_STATS (dev_net_rcu (skb -> dev ), ICMP_MIB_INERRORS );
838841 return ;
839842 }
840843
@@ -868,7 +871,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb)
868871 struct net * net ;
869872 u32 info = 0 ;
870873
871- net = dev_net (skb_dst (skb )-> dev );
874+ net = dev_net_rcu (skb_dst (skb )-> dev );
872875
873876 /*
874877 * Incomplete header ?
@@ -979,7 +982,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb)
979982static enum skb_drop_reason icmp_redirect (struct sk_buff * skb )
980983{
981984 if (skb -> len < sizeof (struct iphdr )) {
982- __ICMP_INC_STATS (dev_net (skb -> dev ), ICMP_MIB_INERRORS );
985+ __ICMP_INC_STATS (dev_net_rcu (skb -> dev ), ICMP_MIB_INERRORS );
983986 return SKB_DROP_REASON_PKT_TOO_SMALL ;
984987 }
985988
@@ -1011,7 +1014,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
10111014 struct icmp_bxm icmp_param ;
10121015 struct net * net ;
10131016
1014- net = dev_net (skb_dst (skb )-> dev );
1017+ net = dev_net_rcu (skb_dst (skb )-> dev );
10151018 /* should there be an ICMP stat for ignored echos? */
10161019 if (READ_ONCE (net -> ipv4 .sysctl_icmp_echo_ignore_all ))
10171020 return SKB_NOT_DROPPED_YET ;
@@ -1040,9 +1043,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
10401043
10411044bool icmp_build_probe (struct sk_buff * skb , struct icmphdr * icmphdr )
10421045{
1046+ struct net * net = dev_net_rcu (skb -> dev );
10431047 struct icmp_ext_hdr * ext_hdr , _ext_hdr ;
10441048 struct icmp_ext_echo_iio * iio , _iio ;
1045- struct net * net = dev_net (skb -> dev );
10461049 struct inet6_dev * in6_dev ;
10471050 struct in_device * in_dev ;
10481051 struct net_device * dev ;
@@ -1181,7 +1184,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)
11811184 return SKB_NOT_DROPPED_YET ;
11821185
11831186out_err :
1184- __ICMP_INC_STATS (dev_net (skb_dst (skb )-> dev ), ICMP_MIB_INERRORS );
1187+ __ICMP_INC_STATS (dev_net_rcu (skb_dst (skb )-> dev ), ICMP_MIB_INERRORS );
11851188 return SKB_DROP_REASON_PKT_TOO_SMALL ;
11861189}
11871190
@@ -1198,7 +1201,7 @@ int icmp_rcv(struct sk_buff *skb)
11981201{
11991202 enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED ;
12001203 struct rtable * rt = skb_rtable (skb );
1201- struct net * net = dev_net (rt -> dst .dev );
1204+ struct net * net = dev_net_rcu (rt -> dst .dev );
12021205 struct icmphdr * icmph ;
12031206
12041207 if (!xfrm4_policy_check (NULL , XFRM_POLICY_IN , skb )) {
@@ -1371,9 +1374,9 @@ int icmp_err(struct sk_buff *skb, u32 info)
13711374 struct iphdr * iph = (struct iphdr * )skb -> data ;
13721375 int offset = iph -> ihl <<2 ;
13731376 struct icmphdr * icmph = (struct icmphdr * )(skb -> data + offset );
1377+ struct net * net = dev_net_rcu (skb -> dev );
13741378 int type = icmp_hdr (skb )-> type ;
13751379 int code = icmp_hdr (skb )-> code ;
1376- struct net * net = dev_net (skb -> dev );
13771380
13781381 /*
13791382 * Use ping_err to handle all icmp errors except those
0 commit comments