+ struct gif_softc *sc = NULL;
+ struct ifnet_init_params gif_init_params;
+ errno_t error = 0;
+
+ lck_mtx_lock(gif_mtx);
+
+ /* Can't create more than GIF_MAXUNIT */
+ if (ngif >= GIF_MAXUNIT) {
+ error = ENXIO;
+ goto done;
+ }
+
+ sc = _MALLOC(sizeof (struct gif_softc), M_DEVBUF, M_WAITOK);
+ if (sc == NULL) {
+ log(LOG_ERR, "gif_clone_create: failed to allocate gif%d\n",
+ unit);
+ error = ENOBUFS;
+ goto done;
+ }
+ bzero(sc, sizeof (struct gif_softc));
+
+ /* use the interface name as the unique id for ifp recycle */
+ snprintf(sc->gif_ifname, sizeof (sc->gif_ifname), "%s%d",
+ ifc->ifc_name, unit);
+
+ lck_mtx_init(&sc->gif_lock, gif_mtx_grp, gif_mtx_attr);
+
+ bzero(&gif_init_params, sizeof (gif_init_params));
+ gif_init_params.uniqueid = sc->gif_ifname;
+ gif_init_params.uniqueid_len = strlen(sc->gif_ifname);
+ gif_init_params.name = GIFNAME;
+ gif_init_params.unit = unit;
+ gif_init_params.type = IFT_GIF;
+ gif_init_params.family = IFNET_FAMILY_GIF;
+ gif_init_params.output = gif_output;
+ gif_init_params.demux = gif_demux;
+ gif_init_params.add_proto = gif_add_proto;
+ gif_init_params.del_proto = gif_del_proto;
+ gif_init_params.softc = sc;
+ gif_init_params.ioctl = gif_ioctl;
+ gif_init_params.set_bpf_tap = gif_set_bpf_tap;
+ gif_init_params.detach = gif_detach;
+
+ error = ifnet_allocate(&gif_init_params, &sc->gif_if);
+ if (error != 0) {
+ printf("gif_clone_create, ifnet_allocate failed - %d\n", error);
+ _FREE(sc, M_DEVBUF);
+ error = ENOBUFS;
+ goto done;
+ }
+
+ sc->encap_cookie4 = sc->encap_cookie6 = NULL;
+#if INET
+ sc->encap_cookie4 = encap_attach_func(AF_INET, -1,
+ gif_encapcheck, &in_gif_protosw, sc);
+ if (sc->encap_cookie4 == NULL) {
+ printf("%s: unable to attach encap4\n", if_name(sc->gif_if));
+ ifnet_release(sc->gif_if);
+ FREE(sc, M_DEVBUF);
+ error = ENOBUFS;
+ goto done;
+ }
+#endif
+#if INET6
+ sc->encap_cookie6 = encap_attach_func(AF_INET6, -1,
+ gif_encapcheck, (struct protosw *)&in6_gif_protosw, sc);
+ if (sc->encap_cookie6 == NULL) {
+ if (sc->encap_cookie4) {
+ encap_detach(sc->encap_cookie4);
+ sc->encap_cookie4 = NULL;
+ }
+ printf("%s: unable to attach encap6\n", if_name(sc->gif_if));
+ ifnet_release(sc->gif_if);
+ FREE(sc, M_DEVBUF);
+ error = ENOBUFS;
+ goto done;
+ }
+#endif
+ sc->gif_called = 0;
+ ifnet_set_mtu(sc->gif_if, GIF_MTU);
+ ifnet_set_flags(sc->gif_if, IFF_POINTOPOINT | IFF_MULTICAST, 0xffff);