Skip to content
  • He Chunhui's avatar
    net: neigh: disallow transition to NUD_STALE if lladdr is unchanged in neigh_update() · d1c2b501
    He Chunhui authored
    
    
    NUD_STALE is used when the caller(e.g. arp_process()) can't guarantee
    neighbour reachability. If the entry was NUD_VALID and lladdr is unchanged,
    the entry state should not be changed.
    
    Currently the code puts an extra "NUD_CONNECTED" condition. So if old state
    was NUD_DELAY or NUD_PROBE (they are NUD_VALID but not NUD_CONNECTED), the
    state can be changed to NUD_STALE.
    
    This may cause problem. Because NUD_STALE lladdr doesn't guarantee
    reachability, when we send traffic, the state will be changed to
    NUD_DELAY. In normal case, if we get no confirmation (by dst_confirm()),
    we will change the state to NUD_PROBE and send probe traffic. But now the
    state may be reset to NUD_STALE again(e.g. by broadcast ARP packets),
    so the probe traffic will not be sent. This situation may happen again and
    again, and packets will be sent to an non-reachable lladdr forever.
    
    The fix is to remove the "NUD_CONNECTED" condition. After that the
    "NEIGH_UPDATE_F_WEAK_OVERRIDE" condition (used by IPv6) in that branch will
    be redundant, so remove it.
    
    This change may increase probe traffic, but it's essential since NUD_STALE
    lladdr is unreliable. To ensure correctness, we prefer to resolve lladdr,
    when we can't get confirmation, even while remote packets try to set
    NUD_STALE state.
    
    Signed-off-by: default avatarChunhui He <hchunhui@mail.ustc.edu.cn>
    Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
    Reviewed-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d1c2b501