+#include <net/if_media.h>
+#include <net/multicast_list.h>
+
+#define IF_MAXUNIT 0x7fff /* historical value */
+
+#define VLANNAME "vlan"
+
+typedef int (bpf_callback_func)(struct ifnet *, struct mbuf *);
+typedef int (if_set_bpf_tap_func)(struct ifnet *ifp, int mode, bpf_callback_func * func);
+
+/**
+ ** vlan locks
+ **/
+static __inline__ lck_grp_t *
+my_lck_grp_alloc_init(const char * grp_name)
+{
+ lck_grp_t * grp;
+ lck_grp_attr_t * grp_attrs;
+
+ grp_attrs = lck_grp_attr_alloc_init();
+ lck_grp_attr_setdefault(grp_attrs);
+ grp = lck_grp_alloc_init(grp_name, grp_attrs);
+ lck_grp_attr_free(grp_attrs);
+ return (grp);
+}
+
+static __inline__ lck_mtx_t *
+my_lck_mtx_alloc_init(lck_grp_t * lck_grp)
+{
+ lck_attr_t * lck_attrs;
+ lck_mtx_t * lck_mtx;
+
+ lck_attrs = lck_attr_alloc_init();
+ lck_attr_setdefault(lck_attrs);
+ lck_mtx = lck_mtx_alloc_init(lck_grp, lck_attrs);
+ lck_attr_free(lck_attrs);
+ return (lck_mtx);
+}
+
+static lck_mtx_t * vlan_lck_mtx;
+
+static __inline__ void
+vlan_lock_init(void)
+{
+ lck_grp_t * vlan_lck_grp;
+
+ vlan_lck_grp = my_lck_grp_alloc_init("if_vlan");
+ vlan_lck_mtx = my_lck_mtx_alloc_init(vlan_lck_grp);
+}
+
+static __inline__ void
+vlan_assert_lock_held(void)
+{
+ lck_mtx_assert(vlan_lck_mtx, LCK_MTX_ASSERT_OWNED);
+ return;
+}
+
+static __inline__ void
+vlan_assert_lock_not_held(void)
+{
+ lck_mtx_assert(vlan_lck_mtx, LCK_MTX_ASSERT_NOTOWNED);
+ return;
+}
+
+static __inline__ void
+vlan_lock(void)
+{
+ lck_mtx_lock(vlan_lck_mtx);
+ return;
+}
+
+static __inline__ void
+vlan_unlock(void)
+{
+ lck_mtx_unlock(vlan_lck_mtx);
+ return;
+}
+
+/**
+ ** vlan structures, types
+ **/
+struct vlan_parent;
+LIST_HEAD(vlan_parent_list, vlan_parent);
+struct ifvlan;
+LIST_HEAD(ifvlan_list, ifvlan);
+
+typedef struct vlan_parent {
+ LIST_ENTRY(vlan_parent) vlp_parent_list;/* list of parents */
+ struct ifnet * vlp_ifp; /* interface */
+ struct ifvlan_list vlp_vlan_list; /* list of VLAN's */
+#define VLPF_SUPPORTS_VLAN_MTU 0x1
+#define VLPF_CHANGE_IN_PROGRESS 0x2
+#define VLPF_DETACHING 0x4
+ u_int32_t vlp_flags;
+ struct ifdevmtu vlp_devmtu;
+ UInt32 vlp_retain_count;
+} vlan_parent, * vlan_parent_ref;
+
+struct ifvlan {
+ LIST_ENTRY(ifvlan) ifv_vlan_list;
+ char ifv_name[IFNAMSIZ]; /* our unique id */
+ struct ifnet * ifv_ifp; /* our interface */
+ vlan_parent_ref ifv_vlp; /* parent information */
+ struct ifv_linkmib {
+ u_int16_t ifvm_encaplen;/* encapsulation length */
+ u_int16_t ifvm_mtufudge;/* MTU fudged by this much */
+ u_int16_t ifvm_proto; /* encapsulation ethertype */
+ u_int16_t ifvm_tag; /* tag to apply on packets leaving if */
+ } ifv_mib;
+ struct multicast_list ifv_multicast;
+#define IFVF_PROMISC 0x1 /* promiscuous mode enabled */
+#define IFVF_DETACHING 0x2 /* interface is detaching */
+#define IFVF_READY 0x4 /* interface is ready */
+ u_int32_t ifv_flags;
+ bpf_packet_func ifv_bpf_input;
+ bpf_packet_func ifv_bpf_output;
+};
+
+typedef struct ifvlan * ifvlan_ref;
+
+typedef struct vlan_globals_s {
+ struct vlan_parent_list parent_list;
+ int verbose;
+} * vlan_globals_ref;
+
+static vlan_globals_ref g_vlan;
+
+#define ifv_tag ifv_mib.ifvm_tag
+#define ifv_encaplen ifv_mib.ifvm_encaplen
+#define ifv_mtufudge ifv_mib.ifvm_mtufudge
+
+
+/**
+ ** vlan_parent_ref vlp_flags in-lines
+ **/
+static __inline__ int
+vlan_parent_flags_supports_vlan_mtu(vlan_parent_ref vlp)
+{
+ return ((vlp->vlp_flags & VLPF_SUPPORTS_VLAN_MTU) != 0);
+}
+
+static __inline__ void
+vlan_parent_flags_set_supports_vlan_mtu(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags |= VLPF_SUPPORTS_VLAN_MTU;
+ return;
+}
+
+static __inline__ void
+vlan_parent_flags_clear_supports_vlan_mtu(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags &= ~VLPF_SUPPORTS_VLAN_MTU;
+ return;
+}
+
+static __inline__ int
+vlan_parent_flags_change_in_progress(vlan_parent_ref vlp)
+{
+ return ((vlp->vlp_flags & VLPF_CHANGE_IN_PROGRESS) != 0);
+}
+
+static __inline__ void
+vlan_parent_flags_set_change_in_progress(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags |= VLPF_CHANGE_IN_PROGRESS;
+ return;
+}
+
+static __inline__ void
+vlan_parent_flags_clear_change_in_progress(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags &= ~VLPF_CHANGE_IN_PROGRESS;
+ return;
+}
+
+static __inline__ int
+vlan_parent_flags_detaching(struct vlan_parent * vlp)
+{
+ return ((vlp->vlp_flags & VLPF_DETACHING) != 0);
+}
+
+static __inline__ void
+vlan_parent_flags_set_detaching(struct vlan_parent * vlp)
+{
+ vlp->vlp_flags |= VLPF_DETACHING;
+ return;
+}
+
+
+/**
+ ** ifvlan_flags in-lines routines
+ **/
+static __inline__ int
+ifvlan_flags_promisc(ifvlan_ref ifv)
+{
+ return ((ifv->ifv_flags & IFVF_PROMISC) != 0);
+}
+
+static __inline__ void
+ifvlan_flags_set_promisc(ifvlan_ref ifv)
+{
+ ifv->ifv_flags |= IFVF_PROMISC;
+ return;
+}
+
+static __inline__ void
+ifvlan_flags_clear_promisc(ifvlan_ref ifv)
+{
+ ifv->ifv_flags &= ~IFVF_PROMISC;
+ return;
+}
+
+static __inline__ int
+ifvlan_flags_ready(ifvlan_ref ifv)
+{
+ return ((ifv->ifv_flags & IFVF_READY) != 0);
+}
+
+static __inline__ void
+ifvlan_flags_set_ready(ifvlan_ref ifv)
+{
+ ifv->ifv_flags |= IFVF_READY;
+ return;
+}
+
+static __inline__ void
+ifvlan_flags_clear_ready(ifvlan_ref ifv)
+{
+ ifv->ifv_flags &= ~IFVF_READY;
+ return;
+}
+
+static __inline__ int
+ifvlan_flags_detaching(ifvlan_ref ifv)
+{
+ return ((ifv->ifv_flags & IFVF_DETACHING) != 0);
+}
+
+static __inline__ void
+ifvlan_flags_set_detaching(ifvlan_ref ifv)
+{
+ ifv->ifv_flags |= IFVF_DETACHING;
+ return;
+}
+
+#if 0