struct sockaddr *saddr, *smask;
struct ifnet *ifp;
- /*
- * remove all L2 entries on the given prefix
- */
saddr = (struct sockaddr *)&addr;
bzero(&addr, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = ntohl(ia->ia_addr.sin_addr.s_addr);
smask = (struct sockaddr *)&mask;
bzero(&mask, sizeof(mask));
mask.sin_len = sizeof(mask);
mask.sin_addr.s_addr = ia->ia_subnetmask;
ifp = ia->ia_ifp;
- if (all)
+ if (all) {
+
+ /*
+ * Remove all L2 entries matching given prefix.
+ * Convert address to host representation to avoid
+ * doing this on every callback. ia_subnetmask is already
+ * stored in host representation.
+ */
+ addr.sin_addr.s_addr = ntohl(ia->ia_addr.sin_addr.s_addr);
lltable_prefix_free(AF_INET, saddr, smask, flags);
- else
+ } else {
+ /* Remove interface address only */
+ addr.sin_addr.s_addr = ia->ia_addr.sin_addr.s_addr;
lltable_delete_addr(LLTABLE(ifp), LLE_IFADDR, saddr);
+ }
}
/*
fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS :
target->ia_ifp->if_fib;
rt_addrmsg(RTM_DELETE, &target->ia_ifa, fibnum);
+
+ /*
+ * Removing address from !IFF_UP interface or
+ * prefix which exists on other interface (along with route).
+ * No entries should exist here except target addr.
+ * Given that, delete this entry only.
+ */
+ in_scrubprefixlle(target, 0, flags);
return (0);
}