- int error;
- ifvlan_ref ifv;
- struct ifnet * ifp;
-
- error = vlan_globals_init();
- if (error != 0) {
- return (error);
- }
- ifv = _MALLOC(sizeof(struct ifvlan), M_VLAN, M_WAITOK);
- bzero(ifv, sizeof(struct ifvlan));
- multicast_list_init(&ifv->ifv_multicast);
-
- /* use the interface name as the unique id for ifp recycle */
- if ((unsigned int)snprintf(ifv->ifv_name, sizeof(ifv->ifv_name), "%s%d",
- ifc->ifc_name, unit) >= sizeof(ifv->ifv_name)) {
- FREE(ifv, M_VLAN);
- return (EINVAL);
- }
- error = dlil_if_acquire(APPLE_IF_FAM_VLAN,
- ifv->ifv_name,
- strlen(ifv->ifv_name),
- &ifp);
- if (error) {
- FREE(ifv, M_VLAN);
- return (error);
- }
- ifp->if_name = ifc->ifc_name;
- ifp->if_unit = unit;
- ifp->if_family = APPLE_IF_FAM_VLAN;
-
-#if 0
- /* NB: flags are not set here */
- ifp->if_linkmib = &ifv->ifv_mib;
- ifp->if_linkmiblen = sizeof ifv->ifv_mib;
- /* NB: mtu is not set here */
-#endif 0
-
- ifp->if_ioctl = vlan_ioctl;
- ifp->if_set_bpf_tap = vlan_set_bpf_tap;
- ifp->if_free = vlan_if_free;
- ifp->if_output = vlan_output;
- ifp->if_hwassist = 0;
- ifp->if_addrlen = ETHER_ADDR_LEN; /* XXX ethernet specific */
- ifp->if_baudrate = 0;
- ifp->if_type = IFT_L2VLAN;
- ifp->if_hdrlen = ETHER_VLAN_ENCAP_LEN;
-
- /* XXX ethernet specific */
- ifp->if_broadcast.length = ETHER_ADDR_LEN;
- bcopy(etherbroadcastaddr, ifp->if_broadcast.u.buffer, ETHER_ADDR_LEN);
-
- error = dlil_if_attach(ifp);
- if (error) {
- dlil_if_release(ifp);
- FREE(ifv, M_VLAN);
- return (error);
- }
- ifp->if_private = ifv;
- ifv->ifv_ifp = ifp;
-
- /* attach as ethernet */
- bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
- return (0);
+ int error;
+ ifvlan_ref ifv;
+ ifnet_t ifp;
+ struct ifnet_init_eparams vlan_init;
+
+ error = vlan_globals_init();
+ if (error != 0) {
+ return (error);
+ }
+ ifv = _MALLOC(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
+ if (ifv == NULL)
+ return ENOBUFS;
+ ifv->ifv_retain_count = 1;
+ ifv->ifv_signature = IFV_SIGNATURE;
+ multicast_list_init(&ifv->ifv_multicast);
+
+ /* use the interface name as the unique id for ifp recycle */
+ if ((unsigned int)
+ snprintf(ifv->ifv_name, sizeof(ifv->ifv_name), "%s%d",
+ ifc->ifc_name, unit) >= sizeof(ifv->ifv_name)) {
+ ifvlan_release(ifv);
+ return (EINVAL);
+ }
+
+ 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.unit = unit;
+ vlan_init.family = IFNET_FAMILY_VLAN;
+ vlan_init.type = IFT_L2VLAN;
+ vlan_init.output = vlan_output;
+ vlan_init.demux = ether_demux;
+ vlan_init.add_proto = ether_add_proto;
+ vlan_init.del_proto = ether_del_proto;
+ vlan_init.check_multi = ether_check_multi;
+ 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_extended(&vlan_init, &ifp);
+
+ if (error) {
+ ifvlan_release(ifv);
+ return (error);
+ }
+
+ ifnet_set_offload(ifp, 0);
+ ifnet_set_addrlen(ifp, ETHER_ADDR_LEN); /* XXX ethernet specific */
+ ifnet_set_baudrate(ifp, 0);
+ ifnet_set_hdrlen(ifp, ETHER_VLAN_ENCAP_LEN);
+
+ error = ifnet_attach(ifp, NULL);
+ if (error) {
+ ifnet_release(ifp);
+ ifvlan_release(ifv);
+ return (error);
+ }
+ ifv->ifv_ifp = ifp;
+
+ /* attach as ethernet */
+ bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
+ return (0);