|
@@ -957,6 +957,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
|
|
|
rc = 0;
|
|
|
if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))
|
|
|
goto out_unlock_bh;
|
|
|
+ if (neigh->dead)
|
|
|
+ goto out_dead;
|
|
|
|
|
|
if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {
|
|
|
if (NEIGH_VAR(neigh->parms, MCAST_PROBES) +
|
|
@@ -1013,6 +1015,13 @@ out_unlock_bh:
|
|
|
write_unlock(&neigh->lock);
|
|
|
local_bh_enable();
|
|
|
return rc;
|
|
|
+
|
|
|
+out_dead:
|
|
|
+ if (neigh->nud_state & NUD_STALE)
|
|
|
+ goto out_unlock_bh;
|
|
|
+ write_unlock_bh(&neigh->lock);
|
|
|
+ kfree_skb(skb);
|
|
|
+ return 1;
|
|
|
}
|
|
|
EXPORT_SYMBOL(__neigh_event_send);
|
|
|
|
|
@@ -1076,6 +1085,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
|
|
|
if (!(flags & NEIGH_UPDATE_F_ADMIN) &&
|
|
|
(old & (NUD_NOARP | NUD_PERMANENT)))
|
|
|
goto out;
|
|
|
+ if (neigh->dead)
|
|
|
+ goto out;
|
|
|
|
|
|
if (!(new & NUD_VALID)) {
|
|
|
neigh_del_timer(neigh);
|
|
@@ -1225,6 +1236,8 @@ EXPORT_SYMBOL(neigh_update);
|
|
|
*/
|
|
|
void __neigh_set_probe_once(struct neighbour *neigh)
|
|
|
{
|
|
|
+ if (neigh->dead)
|
|
|
+ return;
|
|
|
neigh->updated = jiffies;
|
|
|
if (!(neigh->nud_state & NUD_FAILED))
|
|
|
return;
|