- int error;
- ifbond_ref ifb;
- struct ifnet * ifp;
-
- error = bond_globals_init();
- if (error != 0) {
- return (error);
- }
-
- ifb = _MALLOC(sizeof(ifbond), M_BOND, M_WAITOK);
- if (ifb == NULL) {
- return (ENOMEM);
- }
- bzero(ifb, sizeof(*ifb));
-
- ifbond_retain(ifb);
- TAILQ_INIT(&ifb->ifb_port_list);
- TAILQ_INIT(&ifb->ifb_lag_list);
- ifb->ifb_key = unit + 1;
-
- /* use the interface name as the unique id for ifp recycle */
- if ((u_long)snprintf(ifb->ifb_name, sizeof(ifb->ifb_name), "%s%d",
- ifc->ifc_name, unit) >= sizeof(ifb->ifb_name)) {
- ifbond_release(ifb);
- return (EINVAL);
- }
- error = dlil_if_acquire(APPLE_IF_FAM_BOND,
- ifb->ifb_name,
- strlen(ifb->ifb_name),
- &ifp);
- if (error) {
- ifbond_release(ifb);
- return (error);
- }
- ifb->ifb_ifp = ifp;
- ifp->if_name = ifc->ifc_name;
- ifp->if_unit = unit;
- ifp->if_family = APPLE_IF_FAM_BOND;
- ifp->if_private = NULL;
- ifp->if_ioctl = bond_ioctl;
- ifp->if_set_bpf_tap = bond_set_bpf_tap;
- ifp->if_free = bond_if_free;
- ifp->if_output = bond_output;
- ifp->if_hwassist = 0;
- ifp->if_addrlen = ETHER_ADDR_LEN;
- ifp->if_baudrate = 0;
- ifp->if_type = IFT_IEEE8023ADLAG;
- ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
- ifp->if_mtu = 0;
-
- /* 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 != 0) {
- dlil_if_release(ifp);
- ifbond_release(ifb);
- return (error);
- }
- error = ifbond_add_slow_proto_multicast(ifb);
- if (error != 0) {
- printf("bond_clone_create(%s): "
- "failed to add slow_proto multicast, %d\n",
- ifb->ifb_name, error);
- }
-
- /* attach as ethernet */
- bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
-
- bond_lock();
- ifp->if_private = ifb;
- TAILQ_INSERT_HEAD(&g_bond->ifbond_list, ifb, ifb_bond_list);
- bond_unlock();
-
- return (0);
+ int error;
+ ifbond_ref ifb;
+ ifnet_t ifp;
+ struct ifnet_init_params bond_init;
+
+ error = bond_globals_init();
+ if (error != 0) {
+ return (error);
+ }
+
+ ifb = _MALLOC(sizeof(ifbond), M_BOND, M_WAITOK);
+ if (ifb == NULL) {
+ return (ENOMEM);
+ }
+ bzero(ifb, sizeof(*ifb));
+
+ ifbond_retain(ifb);
+ TAILQ_INIT(&ifb->ifb_port_list);
+ TAILQ_INIT(&ifb->ifb_lag_list);
+ ifb->ifb_key = unit + 1;
+
+ /* use the interface name as the unique id for ifp recycle */
+ if ((u_int32_t)snprintf(ifb->ifb_name, sizeof(ifb->ifb_name), "%s%d",
+ ifc->ifc_name, unit) >= sizeof(ifb->ifb_name)) {
+ ifbond_release(ifb);
+ return (EINVAL);
+ }
+
+ bzero(&bond_init, sizeof(bond_init));
+ bond_init.uniqueid = ifb->ifb_name;
+ bond_init.uniqueid_len = strlen(ifb->ifb_name);
+ bond_init.name = ifc->ifc_name;
+ bond_init.unit = unit;
+ bond_init.family = IFNET_FAMILY_BOND;
+ bond_init.type = IFT_IEEE8023ADLAG;
+ bond_init.output = bond_output;
+ bond_init.demux = ether_demux;
+ bond_init.add_proto = ether_add_proto;
+ bond_init.del_proto = ether_del_proto;
+ bond_init.check_multi = ether_check_multi;
+ bond_init.framer = ether_frameout;
+ bond_init.ioctl = bond_ioctl;
+ bond_init.set_bpf_tap = bond_set_bpf_tap;
+ bond_init.detach = bond_if_free;
+ bond_init.broadcast_addr = etherbroadcastaddr;
+ bond_init.broadcast_len = ETHER_ADDR_LEN;
+ bond_init.softc = ifb;
+ error = ifnet_allocate(&bond_init, &ifp);
+
+ if (error) {
+ ifbond_release(ifb);
+ return (error);
+ }
+
+ ifb->ifb_ifp = ifp;
+ ifnet_set_offload(ifp, 0);
+ ifnet_set_addrlen(ifp, ETHER_ADDR_LEN); /* XXX ethernet specific */
+ ifnet_set_flags(ifp, IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX, 0xffff);
+ ifnet_set_baudrate(ifp, 0);
+ ifnet_set_mtu(ifp, 0);
+
+ error = ifnet_attach(ifp, NULL);
+ if (error != 0) {
+ ifnet_release(ifp);
+ ifbond_release(ifb);
+ return (error);
+ }
+ error = ifbond_add_slow_proto_multicast(ifb);
+ if (error != 0) {
+ printf("bond_clone_create(%s): "
+ "failed to add slow_proto multicast, %d\n",
+ ifb->ifb_name, error);
+ }
+
+ /* attach as ethernet */
+ bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
+
+ bond_lock();
+ TAILQ_INSERT_HEAD(&g_bond->ifbond_list, ifb, ifb_bond_list);
+ bond_unlock();
+
+ return (0);