@@ -3049,27 +3049,29 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3049
3049
if (!skb )
3050
3050
return - ENOBUFS ;
3051
3051
3052
+ rcu_read_lock ();
3053
+
3052
3054
tbl = neigh_find_table (ndm -> ndm_family );
3053
3055
if (!tbl ) {
3054
3056
NL_SET_ERR_MSG (extack , "Unsupported family in header for neighbor get request" );
3055
3057
err = - EAFNOSUPPORT ;
3056
- goto err_free_skb ;
3058
+ goto err_unlock ;
3057
3059
}
3058
3060
3059
3061
if (nla_len (tb [NDA_DST ]) != (int )tbl -> key_len ) {
3060
3062
NL_SET_ERR_MSG (extack , "Invalid network address in neighbor get request" );
3061
3063
err = - EINVAL ;
3062
- goto err_free_skb ;
3064
+ goto err_unlock ;
3063
3065
}
3064
3066
3065
3067
dst = nla_data (tb [NDA_DST ]);
3066
3068
3067
3069
if (ndm -> ndm_ifindex ) {
3068
- dev = __dev_get_by_index (net , ndm -> ndm_ifindex );
3070
+ dev = dev_get_by_index_rcu (net , ndm -> ndm_ifindex );
3069
3071
if (!dev ) {
3070
3072
NL_SET_ERR_MSG (extack , "Unknown device ifindex" );
3071
3073
err = - ENODEV ;
3072
- goto err_free_skb ;
3074
+ goto err_unlock ;
3073
3075
}
3074
3076
}
3075
3077
@@ -3080,28 +3082,31 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3080
3082
if (!pn ) {
3081
3083
NL_SET_ERR_MSG (extack , "Proxy neighbour entry not found" );
3082
3084
err = - ENOENT ;
3083
- goto err_free_skb ;
3085
+ goto err_unlock ;
3084
3086
}
3085
3087
3086
3088
err = pneigh_fill_info (skb , pn , pid , seq , RTM_NEWNEIGH , 0 , tbl );
3087
3089
if (err )
3088
- goto err_free_skb ;
3090
+ goto err_unlock ;
3089
3091
} else {
3090
3092
neigh = neigh_lookup (tbl , dst , dev );
3091
3093
if (!neigh ) {
3092
3094
NL_SET_ERR_MSG (extack , "Neighbour entry not found" );
3093
3095
err = - ENOENT ;
3094
- goto err_free_skb ;
3096
+ goto err_unlock ;
3095
3097
}
3096
3098
3097
3099
err = neigh_fill_info (skb , neigh , pid , seq , RTM_NEWNEIGH , 0 );
3098
3100
neigh_release (neigh );
3099
3101
if (err )
3100
- goto err_free_skb ;
3102
+ goto err_unlock ;
3101
3103
}
3102
3104
3105
+ rcu_read_unlock ();
3106
+
3103
3107
return rtnl_unicast (skb , net , pid );
3104
- err_free_skb :
3108
+ err_unlock :
3109
+ rcu_read_unlock ();
3105
3110
kfree_skb (skb );
3106
3111
return err ;
3107
3112
}
@@ -3904,7 +3909,7 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
3904
3909
{.msgtype = RTM_NEWNEIGH , .doit = neigh_add },
3905
3910
{.msgtype = RTM_DELNEIGH , .doit = neigh_delete },
3906
3911
{.msgtype = RTM_GETNEIGH , .doit = neigh_get , .dumpit = neigh_dump_info ,
3907
- .flags = RTNL_FLAG_DUMP_UNLOCKED },
3912
+ .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED },
3908
3913
{.msgtype = RTM_GETNEIGHTBL , .dumpit = neightbl_dump_info },
3909
3914
{.msgtype = RTM_SETNEIGHTBL , .doit = neightbl_set },
3910
3915
};
0 commit comments