--- zzzz-none-000/linux-4.4.60/net/core/neighbour.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-1750e-727/linux-4.4.60/net/core/neighbour.c 2021-02-04 17:41:59.000000000 +0000 @@ -687,7 +687,7 @@ NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); if (!neigh->dead) { - pr_warn("Destroying alive neighbour %p\n", neigh); + pr_warn("Destroying alive neighbour %pK\n", neigh); dump_stack(); return; } @@ -1049,7 +1049,19 @@ } } +ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list); +void neigh_mac_update_register_notify(struct notifier_block *nb) +{ + atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify); + +void neigh_mac_update_unregister_notify(struct notifier_block *nb) +{ + atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify); /* Generic update routine. -- lladdr is new lladdr or NULL, if it is not supplied. @@ -1080,6 +1092,7 @@ int notify = 0; struct net_device *dev; int update_isrouter = 0; + struct neigh_mac_update nmu; write_lock_bh(&neigh->lock); @@ -1087,6 +1100,8 @@ old = neigh->nud_state; err = -EPERM; + memset(&nmu, 0, sizeof(struct neigh_mac_update)); + if (!(flags & NEIGH_UPDATE_F_ADMIN) && (old & (NUD_NOARP | NUD_PERMANENT))) goto out; @@ -1117,7 +1132,11 @@ and a new address is proposed: - compare new & old - if they are different, check override flag + - copy old and new addresses for neigh update notification */ + memcpy(nmu.old_mac, neigh->ha, dev->addr_len); + memcpy(nmu.update_mac, lladdr, dev->addr_len); + if ((old & NUD_VALID) && !memcmp(lladdr, neigh->ha, dev->addr_len)) lladdr = neigh->ha; @@ -1231,8 +1250,11 @@ } write_unlock_bh(&neigh->lock); - if (notify) + if (notify) { neigh_update_notify(neigh); + atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0, + (struct neigh_mac_update *)&nmu); + } return err; } @@ -3225,4 +3247,3 @@ } subsys_initcall(neigh_init); -