--- zzzz-none-000/linux-4.4.271/net/core/neighbour.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/net/core/neighbour.c 2023-04-19 10:22:30.000000000 +0000 @@ -701,7 +701,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; } @@ -1066,7 +1066,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. @@ -1097,6 +1109,7 @@ int notify = 0; struct net_device *dev; int update_isrouter = 0; + struct neigh_mac_update nmu; write_lock_bh(&neigh->lock); @@ -1104,6 +1117,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; @@ -1134,7 +1149,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; @@ -1257,8 +1276,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; } @@ -3269,4 +3291,3 @@ } subsys_initcall(neigh_init); -