@@ -76,7 +76,7 @@ static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
7676{
7777 /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
7878 struct icmp6hdr * icmp6 = (struct icmp6hdr * ) (skb -> data + offset );
79- struct net * net = dev_net (skb -> dev );
79+ struct net * net = dev_net_rcu (skb -> dev );
8080
8181 if (type == ICMPV6_PKT_TOOBIG )
8282 ip6_update_pmtu (skb , net , info , skb -> dev -> ifindex , 0 , sock_net_uid (net , NULL ));
@@ -473,7 +473,10 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
473473
474474 if (!skb -> dev )
475475 return ;
476- net = dev_net (skb -> dev );
476+
477+ rcu_read_lock ();
478+
479+ net = dev_net_rcu (skb -> dev );
477480 mark = IP6_REPLY_MARK (net , skb -> mark );
478481 /*
479482 * Make sure we respect the rules
@@ -496,7 +499,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
496499 !(type == ICMPV6_PARAMPROB &&
497500 code == ICMPV6_UNK_OPTION &&
498501 (opt_unrec (skb , info ))))
499- return ;
502+ goto out ;
500503
501504 saddr = NULL ;
502505 }
@@ -526,7 +529,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
526529 if ((addr_type == IPV6_ADDR_ANY ) || (addr_type & IPV6_ADDR_MULTICAST )) {
527530 net_dbg_ratelimited ("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n" ,
528531 & hdr -> saddr , & hdr -> daddr );
529- return ;
532+ goto out ;
530533 }
531534
532535 /*
@@ -535,7 +538,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
535538 if (is_ineligible (skb )) {
536539 net_dbg_ratelimited ("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n" ,
537540 & hdr -> saddr , & hdr -> daddr );
538- return ;
541+ goto out ;
539542 }
540543
541544 /* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */
@@ -582,7 +585,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
582585 np = inet6_sk (sk );
583586
584587 if (!icmpv6_xrlim_allow (sk , type , & fl6 , apply_ratelimit ))
585- goto out ;
588+ goto out_unlock ;
586589
587590 tmp_hdr .icmp6_type = type ;
588591 tmp_hdr .icmp6_code = code ;
@@ -600,7 +603,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
600603
601604 dst = icmpv6_route_lookup (net , skb , sk , & fl6 );
602605 if (IS_ERR (dst ))
603- goto out ;
606+ goto out_unlock ;
604607
605608 ipc6 .hlimit = ip6_sk_dst_hoplimit (np , & fl6 , dst );
606609
@@ -616,7 +619,6 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
616619 goto out_dst_release ;
617620 }
618621
619- rcu_read_lock ();
620622 idev = __in6_dev_get (skb -> dev );
621623
622624 if (ip6_append_data (sk , icmpv6_getfrag , & msg ,
@@ -630,13 +632,15 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
630632 icmpv6_push_pending_frames (sk , & fl6 , & tmp_hdr ,
631633 len + sizeof (struct icmp6hdr ));
632634 }
633- rcu_read_unlock ();
635+
634636out_dst_release :
635637 dst_release (dst );
636- out :
638+ out_unlock :
637639 icmpv6_xmit_unlock (sk );
638640out_bh_enable :
639641 local_bh_enable ();
642+ out :
643+ rcu_read_unlock ();
640644}
641645EXPORT_SYMBOL (icmp6_send );
642646
@@ -679,8 +683,8 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
679683 skb_pull (skb2 , nhs );
680684 skb_reset_network_header (skb2 );
681685
682- rt = rt6_lookup (dev_net (skb -> dev ), & ipv6_hdr (skb2 )-> saddr , NULL , 0 ,
683- skb , 0 );
686+ rt = rt6_lookup (dev_net_rcu (skb -> dev ), & ipv6_hdr (skb2 )-> saddr ,
687+ NULL , 0 , skb , 0 );
684688
685689 if (rt && rt -> dst .dev )
686690 skb2 -> dev = rt -> dst .dev ;
@@ -717,7 +721,7 @@ EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach);
717721
718722static enum skb_drop_reason icmpv6_echo_reply (struct sk_buff * skb )
719723{
720- struct net * net = dev_net (skb -> dev );
724+ struct net * net = dev_net_rcu (skb -> dev );
721725 struct sock * sk ;
722726 struct inet6_dev * idev ;
723727 struct ipv6_pinfo * np ;
@@ -832,7 +836,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
832836 u8 code , __be32 info )
833837{
834838 struct inet6_skb_parm * opt = IP6CB (skb );
835- struct net * net = dev_net (skb -> dev );
839+ struct net * net = dev_net_rcu (skb -> dev );
836840 const struct inet6_protocol * ipprot ;
837841 enum skb_drop_reason reason ;
838842 int inner_offset ;
@@ -889,7 +893,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type,
889893static int icmpv6_rcv (struct sk_buff * skb )
890894{
891895 enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED ;
892- struct net * net = dev_net (skb -> dev );
896+ struct net * net = dev_net_rcu (skb -> dev );
893897 struct net_device * dev = icmp6_dev (skb );
894898 struct inet6_dev * idev = __in6_dev_get (dev );
895899 const struct in6_addr * saddr , * daddr ;
@@ -921,7 +925,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
921925 skb_set_network_header (skb , nh );
922926 }
923927
924- __ICMP6_INC_STATS (dev_net (dev ), idev , ICMP6_MIB_INMSGS );
928+ __ICMP6_INC_STATS (dev_net_rcu (dev ), idev , ICMP6_MIB_INMSGS );
925929
926930 saddr = & ipv6_hdr (skb )-> saddr ;
927931 daddr = & ipv6_hdr (skb )-> daddr ;
@@ -939,7 +943,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
939943
940944 type = hdr -> icmp6_type ;
941945
942- ICMP6MSGIN_INC_STATS (dev_net (dev ), idev , type );
946+ ICMP6MSGIN_INC_STATS (dev_net_rcu (dev ), idev , type );
943947
944948 switch (type ) {
945949 case ICMPV6_ECHO_REQUEST :
@@ -1034,9 +1038,9 @@ static int icmpv6_rcv(struct sk_buff *skb)
10341038
10351039csum_error :
10361040 reason = SKB_DROP_REASON_ICMP_CSUM ;
1037- __ICMP6_INC_STATS (dev_net (dev ), idev , ICMP6_MIB_CSUMERRORS );
1041+ __ICMP6_INC_STATS (dev_net_rcu (dev ), idev , ICMP6_MIB_CSUMERRORS );
10381042discard_it :
1039- __ICMP6_INC_STATS (dev_net (dev ), idev , ICMP6_MIB_INERRORS );
1043+ __ICMP6_INC_STATS (dev_net_rcu (dev ), idev , ICMP6_MIB_INERRORS );
10401044drop_no_count :
10411045 kfree_skb_reason (skb , reason );
10421046 return 0 ;
0 commit comments