Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.363 diff -u -p -r1.363 if.c --- net/if.c 1 Sep 2015 04:56:55 -0000 1.363 +++ net/if.c 9 Sep 2015 15:37:13 -0000 @@ -80,6 +80,7 @@ #include #include #include +#include #include @@ -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,7 +1234,24 @@ 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); } /* Index: net/if.h =================================================================== RCS file: /cvs/src/sys/net/if.h,v retrieving revision 1.165 diff -u -p -r1.165 if.h --- net/if.h 30 Aug 2015 10:39:16 -0000 1.165 +++ net/if.h 9 Sep 2015 15:37:13 -0000 @@ -462,6 +462,8 @@ int if_delgroup(struct ifnet *, const ch 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); Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.34 diff -u -p -r1.34 if_var.h --- net/if_var.h 2 Jul 2015 09:40:02 -0000 1.34 +++ net/if_var.h 9 Sep 2015 15:37:14 -0000 @@ -127,6 +127,7 @@ TAILQ_HEAD(ifnet_head, ifnet); /* the a 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 */