diff options
author | hsu <hsu@FreeBSD.org> | 2002-12-18 11:46:59 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2002-12-18 11:46:59 +0000 |
commit | c3153934cb24d911042c92eedf9e5dd6d7be07e1 (patch) | |
tree | 079e82ffd683b796c6432b8bcf3ff23f996d4e04 /sys/net/if_var.h | |
parent | 2d0e93bb2eab2533104a92a432361a0d75aae7da (diff) | |
download | FreeBSD-src-c3153934cb24d911042c92eedf9e5dd6d7be07e1.zip FreeBSD-src-c3153934cb24d911042c92eedf9e5dd6d7be07e1.tar.gz |
Lock up ifaddr reference counts.
Diffstat (limited to 'sys/net/if_var.h')
-rw-r--r-- | sys/net/if_var.h | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 4f943bb..bf9ee0c 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -348,13 +348,19 @@ struct ifaddr { #endif int (*ifa_claim_addr) /* check if an addr goes to this if */ (struct ifaddr *, struct sockaddr *); - + struct mtx ifa_mtx; }; #define IFA_ROUTE RTF_UP /* route installed */ /* for compatibility with other BSDs */ #define ifa_list ifa_link +#define IFA_LOCK_INIT(ifa) \ + mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) +#define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) +#define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) +#define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) + /* * The prefix structure contains information about one prefix * of an interface. They are maintained by the different address families, @@ -385,12 +391,23 @@ struct ifmultiaddr { }; #ifdef _KERNEL -#define IFAFREE(ifa) \ - do { \ - if ((ifa)->ifa_refcnt <= 0) \ - ifafree(ifa); \ - else \ - (ifa)->ifa_refcnt--; \ +#define IFAFREE(ifa) \ + do { \ + IFA_LOCK(ifa); \ + if ((ifa)->ifa_refcnt == 0) { \ + IFA_DESTROY(ifa); \ + free(ifa, M_IFADDR); \ + } else { \ + --(ifa)->ifa_refcnt; \ + IFA_UNLOCK(ifa); \ + } \ + } while (0) + +#define IFAREF(ifa) \ + do { \ + IFA_LOCK(ifa); \ + ++(ifa)->ifa_refcnt; \ + IFA_UNLOCK(ifa); \ } while (0) struct ifindex_entry { @@ -438,7 +455,6 @@ struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); struct ifaddr *ifa_ifwithnet(struct sockaddr *); struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); -void ifafree(struct ifaddr *); struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *); int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); |