Hello,

On Tue, 15 Aug 2017, Eric Dumazet wrote:

> Please try this :
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 
> 16a1a4c4eb57fa1147f230916e2e62e18ef89562..95e0d7702029b583de8229e3c3eb923f6395b072
>  100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -991,14 +991,18 @@ static void neigh_timer_handler(unsigned long arg)
>  
>  int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
>  {
> -     int rc;
>       bool immediate_probe = false;
> +     int rc;
> +
> +     /* We _should_ test this under write_lock_bh(&neigh->lock),
> +      * but this is too costly.
> +      */
> +     if (READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY | 
> NUD_PROBE))
> +             return 0;

        The same fast check is already done in the only caller,
neigh_event_send. Now we risk to enter the
'if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {' block...

>       write_lock_bh(&neigh->lock);
>  
>       rc = 0;
> -     if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
> -             goto out_unlock_bh;
>       if (neigh->dead)
>               goto out_dead;

Regards

--
Julian Anastasov <j...@ssi.bg>

Reply via email to