/*
- * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
vlan_parent_entry 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
+#define VLPF_SUPPORTS_VLAN_MTU 0x00000001
+#define VLPF_CHANGE_IN_PROGRESS 0x00000002
+#define VLPF_DETACHING 0x00000004
+#define VLPF_LINK_EVENT_REQUIRED 0x00000008
u_int32_t vlp_flags;
+ u_int32_t vlp_event_code;
struct ifdevmtu vlp_devmtu;
- SInt32 vlp_retain_count;
- UInt32 vlp_signature; /* VLP_SIGNATURE */
+ int32_t vlp_retain_count;
+ u_int32_t vlp_signature; /* VLP_SIGNATURE */
} vlan_parent, * vlan_parent_ref;
#define IFV_SIGNATURE 0xbeefbeef
u_int32_t ifv_flags;
bpf_packet_func ifv_bpf_input;
bpf_packet_func ifv_bpf_output;
- SInt32 ifv_retain_count;
- UInt32 ifv_signature; /* IFV_SIGNATURE */
+ int32_t ifv_retain_count;
+ u_int32_t ifv_signature; /* IFV_SIGNATURE */
};
typedef struct ifvlan * ifvlan_ref;
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;
}
+static __inline__ int
+vlan_parent_flags_link_event_required(vlan_parent_ref vlp)
+{
+ return ((vlp->vlp_flags & VLPF_LINK_EVENT_REQUIRED) != 0);
+}
+
+static __inline__ void
+vlan_parent_flags_set_link_event_required(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags |= VLPF_LINK_EVENT_REQUIRED;
+ return;
+}
+
+static __inline__ void
+vlan_parent_flags_clear_link_event_required(vlan_parent_ref vlp)
+{
+ vlp->vlp_flags &= ~VLPF_LINK_EVENT_REQUIRED;
+ return;
+}
+
/**
** ifvlan_flags in-lines routines
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)
{
static void
ifvlan_release(ifvlan_ref ifv)
{
- UInt32 old_retain_count;
+ u_int32_t old_retain_count;
if (ifv->ifv_signature != IFV_SIGNATURE) {
panic("ifvlan_release: bad signature\n");
{
vlan_parent_ref vlp = ifv->ifv_vlp;
- if (vlan_parent_flags_detaching(vlp)) {
+ if (vlp == NULL || vlan_parent_flags_detaching(vlp)) {
return (NULL);
}
vlan_parent_retain(vlp);
static void
vlan_parent_release(vlan_parent_ref vlp)
{
- UInt32 old_retain_count;
+ u_int32_t old_retain_count;
if (vlp->vlp_signature != VLP_SIGNATURE) {
panic("vlan_parent_release: signature is bad\n");
static void
vlan_parent_signal(vlan_parent_ref vlp, const char * msg)
{
+ struct ifnet * vlp_ifp = vlp->vlp_ifp;
+
+ if (vlan_parent_flags_link_event_required(vlp)) {
+ vlan_parent_flags_clear_link_event_required(vlp);
+ if (!vlan_parent_flags_detaching(vlp)) {
+ u_int32_t event_code = vlp->vlp_event_code;
+ ifvlan_ref ifv;
+
+ vlan_unlock();
+
+ /* we can safely walk the list unlocked */
+ LIST_FOREACH(ifv, &vlp->vlp_vlan_list, ifv_vlan_list) {
+ struct ifnet * ifp = ifv->ifv_ifp;
+
+ interface_link_event(ifp, event_code);
+ }
+ if (g_vlan->verbose) {
+ printf("%s%d: propagated link event to vlans\n",
+ ifnet_name(vlp_ifp), ifnet_unit(vlp_ifp));
+ }
+ vlan_lock();
+ }
+ }
vlan_parent_flags_clear_change_in_progress(vlp);
wakeup((caddr_t)vlp);
if (g_vlan->verbose) {
- struct ifnet * ifp = vlp->vlp_ifp;
-
- printf("%s%d: %s wakeup\n", ifnet_name(ifp), ifnet_unit(ifp), msg);
+ printf("%s%d: %s wakeup\n",
+ ifnet_name(vlp_ifp), ifnet_unit(vlp_ifp), msg);
}
return;
}
vlan_parent_ref vlp;
*ret_vlp = NULL;
- vlp = _MALLOC(sizeof(*vlp), M_VLAN, M_WAITOK);
+ vlp = _MALLOC(sizeof(*vlp), M_VLAN, M_WAITOK | M_ZERO);
if (vlp == NULL) {
return (ENOMEM);
}
- bzero(vlp, sizeof(*vlp));
error = siocgifdevmtu(p, &vlp->vlp_devmtu);
if (error != 0) {
printf("vlan_parent_create (%s%d): siocgifdevmtu failed, %d\n",
vlan_parent_retain(vlp);
vlan_parent_wait(vlp, "vlan_parent_remove_all_vlans");
need_vlp_release++;
- vlp = parent_list_lookup(p);
+
/* check again */
- if (vlp == NULL) {
+ if (parent_list_lookup(p) != vlp) {
goto signal_done;
}
int error;
ifvlan_ref ifv;
ifnet_t ifp;
- struct ifnet_init_params vlan_init;
+ struct ifnet_init_eparams vlan_init;
error = vlan_globals_init();
if (error != 0) {
return (error);
}
- ifv = _MALLOC(sizeof(struct ifvlan), M_VLAN, M_WAITOK);
+ ifv = _MALLOC(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
if (ifv == NULL)
return ENOBUFS;
- bzero(ifv, sizeof(struct ifvlan));
ifv->ifv_retain_count = 1;
ifv->ifv_signature = IFV_SIGNATURE;
multicast_list_init(&ifv->ifv_multicast);
}
bzero(&vlan_init, sizeof(vlan_init));
+ vlan_init.ver = IFNET_INIT_CURRENT_VERSION;
+ vlan_init.len = sizeof (vlan_init);
+ vlan_init.flags = IFNET_INIT_LEGACY;
vlan_init.uniqueid = ifv->ifv_name;
vlan_init.uniqueid_len = strlen(ifv->ifv_name);
vlan_init.name = ifc->ifc_name;
vlan_init.add_proto = ether_add_proto;
vlan_init.del_proto = ether_del_proto;
vlan_init.check_multi = ether_check_multi;
- vlan_init.framer = ether_frameout;
+ vlan_init.framer_extended = ether_frameout_extended;
vlan_init.softc = ifv;
vlan_init.ioctl = vlan_ioctl;
vlan_init.set_bpf_tap = vlan_set_bpf_tap;
vlan_init.detach = vlan_if_free;
vlan_init.broadcast_addr = etherbroadcastaddr;
vlan_init.broadcast_len = ETHER_ADDR_LEN;
- error = ifnet_allocate(&vlan_init, &ifp);
+ error = ifnet_allocate_extended(&vlan_init, &ifp);
if (error) {
ifvlan_release(ifv);
m->m_pkthdr.csum_flags |= CSUM_VLAN_TAG_VALID;
m->m_pkthdr.vlan_tag = tag;
} else {
- M_PREPEND(m, encaplen, M_DONTWAIT);
+ M_PREPEND(m, encaplen, M_DONTWAIT, 1);
if (m == NULL) {
printf("%s%d: unable to prepend VLAN header\n", ifnet_name(ifp),
ifnet_unit(ifp));
ifnet_type(p));
m_freem(m);
return 0;
- break;
}
}
if (tag != 0) {
}
if (tag != 0) {
m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.header = frame_header;
+ m->m_pkthdr.pkt_hdr = frame_header;
(void)ifnet_stat_increment_in(ifp, 1,
m->m_pkthdr.len + ETHER_HDR_LEN, 0);
vlan_bpf_input(ifp, m, bpf_func, frame_header, ETHER_HDR_LEN,
/* We found a vlan interface, inject on that interface. */
dlil_input_packet_list(ifp, m);
} else {
- m->m_pkthdr.header = frame_header;
+ m->m_pkthdr.pkt_hdr = frame_header;
/* Send priority-tagged packet up through the parent */
dlil_input_packet_list(p, m);
}
}
/* set our ethernet address to that of the parent */
- ifnet_set_lladdr_and_type(ifp, ifnet_lladdr(p), ETHER_ADDR_LEN, IFT_ETHER);
+ ifnet_set_lladdr_and_type(ifp, IF_LLADDR(p), ETHER_ADDR_LEN, IFT_ETHER);
/* no failures past this point */
vlan_lock();
event.header.event_code = event_code;
event.header.event_data[0] = ifnet_family(ifp);
event.unit = (u_int32_t) ifnet_unit(ifp);
- strncpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
+ strlcpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
ifnet_event(ifp, &event.header);
return;
}
static void
vlan_parent_link_event(struct ifnet * p, u_int32_t event_code)
{
- ifvlan_ref ifv;
vlan_parent_ref vlp;
vlan_lock();
vlan_unlock();
return;
}
-
+ vlan_parent_flags_set_link_event_required(vlp);
+ vlp->vlp_event_code = event_code;
+ if (vlan_parent_flags_change_in_progress(vlp)) {
+ /* don't block waiting to generate an event */
+ vlan_unlock();
+ return;
+ }
vlan_parent_retain(vlp);
vlan_parent_wait(vlp, "vlan_parent_link_event");
- if (vlan_parent_flags_detaching(vlp)) {
- goto signal_done;
- }
-
- vlan_unlock();
-
- /* vlan_parent_wait() gives us exclusive access to the list */
- LIST_FOREACH(ifv, &vlp->vlp_vlan_list, ifv_vlan_list) {
- struct ifnet * ifp = ifv->ifv_ifp;
-
- interface_link_event(ifp, event_code);
- }
-
- vlan_lock();
-
- signal_done:
vlan_parent_signal(vlp, "vlan_parent_link_event");
vlan_unlock();
vlan_parent_release(vlp);
}
#endif /* INET6 */
-#if NETAT
-static errno_t
-vlan_attach_at(struct ifnet *ifp, protocol_family_t protocol_family)
-{
- return (ether_attach_at(ifp, protocol_family));
-}
-
-static void
-vlan_detach_at(struct ifnet *ifp, protocol_family_t protocol_family)
-{
- ether_detach_at(ifp, protocol_family);
-}
-#endif /* NETAT */
-
__private_extern__ int
vlan_family_init(void)
{
goto done;
}
#endif
-#if NETAT
- error = proto_register_plumber(PF_APPLETALK, IFNET_FAMILY_VLAN,
- vlan_attach_at, vlan_detach_at);
- if (error != 0) {
- printf("proto_register_plumber failed for AF_APPLETALK error=%d\n",
- error);
- goto done;
- }
-#endif /* NETAT */
error = vlan_clone_attach();
if (error != 0) {
printf("proto_register_plumber failed vlan_clone_attach error=%d\n",