diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.c | 24 | ||||
-rw-r--r-- | sys/net/if.h | 4 | ||||
-rw-r--r-- | sys/net/if_var.h | 3 |
3 files changed, 27 insertions, 4 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 83fc99725c5..fadedd86a96 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.363 2015/09/01 04:56:55 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.364 2015/09/09 16:01:10 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -80,6 +80,7 @@ #include <sys/domain.h> #include <sys/sysctl.h> #include <sys/task.h> +#include <sys/atomic.h> #include <dev/rndvar.h> @@ -260,7 +261,8 @@ if_attachsetup(struct ifnet *ifp) if_addgroup(ifp, IFG_ALL); - ifindex2ifnet[if_index] = ifp; + ifp->if_refcnt = 0; + ifindex2ifnet[if_index] = if_ref(ifp); if (ifp->if_snd.ifq_maxlen == 0) IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); @@ -664,6 +666,7 @@ if_detach(struct ifnet *ifp) rt_ifannouncemsg(ifp, IFAN_DEPARTURE); ifindex2ifnet[ifp->if_index] = NULL; + if_put(ifp); splx(s); } @@ -1231,9 +1234,26 @@ if_get(unsigned int index) if (index < if_indexlim) ifp = ifindex2ifnet[index]; + return (if_ref(ifp)); +} + +struct ifnet * +if_ref(struct ifnet *ifp) +{ + atomic_inc_int(&ifp->if_refcnt); + return (ifp); } +void +if_put(struct ifnet *ifp) +{ + if (ifp == NULL) + return; + + atomic_dec_int(&ifp->if_refcnt); +} + /* * Interface ioctls. */ diff --git a/sys/net/if.h b/sys/net/if.h index c4962b8df80..741ec2be537 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.165 2015/08/30 10:39:16 mpi Exp $ */ +/* $OpenBSD: if.h,v 1.166 2015/09/09 16:01:10 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -462,6 +462,8 @@ int if_delgroup(struct ifnet *, const char *); void if_group_routechange(struct sockaddr *, struct sockaddr *); struct ifnet *ifunit(const char *); struct ifnet *if_get(unsigned int); +struct ifnet *if_ref(struct ifnet *); +void if_put(struct ifnet *); void ifnewlladdr(struct ifnet *); void if_congestion(void); int if_congested(void); diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 034a64e301c..ba57aa11514 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.34 2015/07/02 09:40:02 mpi Exp $ */ +/* $OpenBSD: if_var.h,v 1.35 2015/09/09 16:01:10 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -127,6 +127,7 @@ TAILQ_HEAD(ifnet_head, ifnet); /* the actual queue head */ struct ifnet { /* and the entries */ void *if_softc; /* lower-level data for this if */ + unsigned int if_refcnt; TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */ TAILQ_ENTRY(ifnet) if_txlist; /* list of ifnets ready to tx */ TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */ |