+
+void
+ifafree(struct ifaddr *ifa)
+{
+ int oldval;
+
+ oldval = OSAddAtomic(-1, &ifa->ifa_refcnt);
+ if (oldval >= 1 && ifa->ifa_trace != NULL)
+ (*ifa->ifa_trace)(ifa, FALSE);
+ if (oldval == 0) {
+ panic("%s: ifa %p negative refcnt\n", __func__, ifa);
+ } else if (oldval == 1) {
+ if (ifa->ifa_debug & IFD_ATTACHED)
+ panic("ifa %p attached to ifp is being freed\n", ifa);
+ /*
+ * Some interface addresses are allocated either statically
+ * or carved out of a larger block; e.g. AppleTalk addresses.
+ * Only free it if it was allocated via MALLOC or via the
+ * corresponding per-address family allocator. Otherwise,
+ * leave it alone.
+ */
+ if (ifa->ifa_debug & IFD_ALLOC) {
+ if (ifa->ifa_free == NULL)
+ FREE(ifa, M_IFADDR);
+ else
+ (*ifa->ifa_free)(ifa);
+ }
+ }
+}
+
+void
+ifaref(struct ifaddr *ifa)
+{
+ int oldval;
+
+ oldval = OSAddAtomic(1, &ifa->ifa_refcnt);
+ if (oldval < 0)
+ panic("%s: ifa %p negative refcnt\n", __func__, ifa);
+ else if (ifa->ifa_trace != NULL)
+ (*ifa->ifa_trace)(ifa, TRUE);
+}