Suppose a user configures two IPv4 addresses with the same prefix on
their system (call them x.y.z.A/24 and x.y.z.B/24), and then
moves the subnet route from A to B with:
route change x.y.z.0/24 -ifa x.y.z.B
The kernel is left in a very confused state. ifa A has the
IFA_ROUTE flag still set on it, indicating that the kernel
believes that there is still a subnet route using A as its
source address. If the user subsequently tries to remove A from
the interface, things become even more confused. in_scrubprefix
tries to remove the subnet route and fails (because no subnet
route is associated with A), and as a result the static arp
entry for A is never destroyed. This leaves the system in a
state where it is impossible to assign A to any interface.
We hit this at $WORK in some code that attempted to fail over
some routes from one address to another, and later tried to fail
over an IP address. The system was left in a state where it was
no longer responding to one of the IP addresses that had been
configured on it, because we couldn't assign the IP to any
interface.
Fix this by detecting the case where a subnet route is being modified,
and migrate the IFA_ROUTE flag from the old ifa to the new one.
Sponsored by: Dell EMC Isilon