summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c24
-rw-r--r--sys/net/if.h4
-rw-r--r--sys/net/if_var.h3
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 */