diff options
-rw-r--r-- | sys/net/if.c | 23 | ||||
-rw-r--r-- | sys/net/if.h | 5 | ||||
-rw-r--r-- | sys/net/if_vlan.c | 25 | ||||
-rw-r--r-- | sys/net/if_vlan_var.h | 9 |
4 files changed, 29 insertions, 33 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index a8328ad155f..b65736c5c26 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.269 2013/10/19 11:11:24 mpi Exp $ */ +/* $OpenBSD: if.c,v 1.270 2013/10/19 14:05:14 reyk Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -65,10 +65,9 @@ #include "bpfilter.h" #include "bridge.h" #include "carp.h" -#include "ether.h" #include "pf.h" #include "trunk.h" -#include "vlan.h" +#include "ether.h" #include <sys/param.h> #include <sys/systm.h> @@ -135,10 +134,6 @@ #include <net/pfvar.h> #endif -#if NVLAN > 0 -#include <net/if_vlan_var.h> -#endif - void if_attachsetup(struct ifnet *); void if_attachdomain1(struct ifnet *); void if_attach_common(struct ifnet *); @@ -293,10 +288,6 @@ if_attachsetup(struct ifnet *ifp) pfi_attach_ifnet(ifp); #endif -#if NVLAN > 0 - LIST_INIT(&ifp->if_vlist); -#endif - /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); } @@ -456,6 +447,9 @@ if_attach_common(struct ifnet *ifp) ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks), M_TEMP, M_WAITOK); TAILQ_INIT(ifp->if_linkstatehooks); + ifp->if_detachhooks = malloc(sizeof(*ifp->if_detachhooks), + M_TEMP, M_WAITOK); + TAILQ_INIT(ifp->if_detachhooks); } void @@ -515,10 +509,8 @@ if_detach(struct ifnet *ifp) ifp->if_ioctl = if_detached_ioctl; ifp->if_watchdog = if_detached_watchdog; -#if NVLAN > 0 - if (!LIST_EMPTY(&ifp->if_vlist)) - vlan_ifdetach(ifp); -#endif + /* Call detach hooks, ie. to remove vlan interfaces */ + dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE); #if NTRUNK > 0 if (ifp->if_type == IFT_IEEE8023ADLAG) @@ -621,6 +613,7 @@ do { \ free(ifp->if_addrhooks, M_TEMP); free(ifp->if_linkstatehooks, M_TEMP); + free(ifp->if_detachhooks, M_TEMP); for (dp = domains; dp; dp = dp->dom_next) { if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) diff --git a/sys/net/if.h b/sys/net/if.h index 508407cd6bd..d3d439b6cf7 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.148 2013/10/13 10:10:02 reyk Exp $ */ +/* $OpenBSD: if.h,v 1.149 2013/10/19 14:05:14 reyk Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -101,7 +101,6 @@ struct arpcom; struct rt_addrinfo; struct ifnet; struct hfsc_if; -struct ifvlan; /* * Structure describing a `cloning' interface. @@ -264,12 +263,12 @@ struct ifnet { /* and the entries */ TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ struct hook_desc_head *if_addrhooks; /* address change callbacks */ struct hook_desc_head *if_linkstatehooks; /* link change callbacks */ + struct hook_desc_head *if_detachhooks; /* detach callbacks */ char if_xname[IFNAMSIZ]; /* external name (name + unit) */ int if_pcount; /* number of promiscuous listeners */ caddr_t if_bpf; /* packet filter structure */ caddr_t if_bridgeport; /* used by bridge ports */ caddr_t if_tp; /* used by trunk ports */ - LIST_HEAD(, ifvlan) if_vlist; /* list of vlans on this interface */ caddr_t if_pf_kif; /* pf interface abstraction */ union { caddr_t carp_s; /* carp structure (used by !carp ifs) */ diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 9b84bd56b0b..8e12d1374fd 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.98 2013/09/17 13:34:18 mpi Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.99 2013/10/19 14:05:14 reyk Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -93,6 +93,7 @@ void vlan_ether_purgemulti(struct ifvlan *); void vlan_ether_resetmulti(struct ifvlan *, struct ifnet *); int vlan_clone_create(struct if_clone *, int); int vlan_clone_destroy(struct ifnet *); +void vlan_ifdetach(void *); struct if_clone vlan_cloner = IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); @@ -169,16 +170,17 @@ vlan_clone_destroy(struct ifnet *ifp) } void -vlan_ifdetach(struct ifnet *ifp) +vlan_ifdetach(void *ptr) { - struct ifvlan *ifv, *nifv; - + struct ifvlan *ifv = (struct ifvlan *)ptr; /* - * Destroy the vlan interfaces because the parent has been - * detached. + * Destroy the vlan interface because the parent has been + * detached. Set the dh_cookie to NULL because we're running + * inside of dohooks which is told to disestablish the hook + * for us (otherwise we would kill the TAILQ element...). */ - LIST_FOREACH_SAFE(ifv, &ifp->if_vlist, ifv_next, nifv) - vlan_clone_destroy(&ifv->ifv_if); + ifv->dh_cookie = NULL; + vlan_clone_destroy(&ifv->ifv_if); } void @@ -450,7 +452,8 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, u_int16_t tag) vlan_vlandev_state, ifv); /* Register callback if parent wants to unregister */ - LIST_INSERT_HEAD(&p->if_vlist, ifv, ifv_next); + ifv->dh_cookie = hook_establish(p->if_detachhooks, 1, + vlan_ifdetach, ifv); vlan_vlandev_state(ifv); splx(s); @@ -482,7 +485,9 @@ vlan_unconfig(struct ifnet *ifp, struct ifnet *newp) LIST_REMOVE(ifv, ifv_list); if (ifv->lh_cookie != NULL) hook_disestablish(p->if_linkstatehooks, ifv->lh_cookie); - LIST_REMOVE(ifv, ifv_next); + /* The cookie is NULL if disestablished externally */ + if (ifv->dh_cookie != NULL) + hook_disestablish(p->if_detachhooks, ifv->dh_cookie); /* Reset link state */ if (newp != NULL) { ifp->if_link_state = LINK_STATE_INVALID; diff --git a/sys/net/if_vlan_var.h b/sys/net/if_vlan_var.h index 6ce58cb4995..e58cff42628 100644 --- a/sys/net/if_vlan_var.h +++ b/sys/net/if_vlan_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan_var.h,v 1.22 2013/09/17 13:34:18 mpi Exp $ */ +/* $OpenBSD: if_vlan_var.h,v 1.23 2013/10/19 14:05:14 reyk Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -56,10 +56,10 @@ struct ifvlan { u_int16_t ifvm_type; /* non-standard ethertype or 0x8100 */ } ifv_mib; LIST_HEAD(__vlan_mchead, vlan_mc_entry) vlan_mc_listhead; - LIST_ENTRY(ifvlan) ifv_list; /* list of vlan on the same hash */ - LIST_ENTRY(ifvlan) ifv_next; /* list of vlan on a phys interface */ + LIST_ENTRY(ifvlan) ifv_list; int ifv_flags; void *lh_cookie; + void *dh_cookie; }; #define ifv_if ifv_ac.ac_if @@ -97,7 +97,6 @@ struct vlanreq { }; #ifdef _KERNEL -int vlan_input(struct ether_header *eh, struct mbuf *m); -void vlan_ifdetach(struct ifnet *); +extern int vlan_input(struct ether_header *eh, struct mbuf *m); #endif /* _KERNEL */ #endif /* _NET_IF_VLAN_VAR_H_ */ |