- gif = sc = _MALLOC (ngif * sizeof(struct gif_softc), M_DEVBUF, M_WAIT);
- bzero(sc, ngif * sizeof(struct gif_softc));
- for (i = 0; i < ngif; sc++, i++) {
- sc->gif_if.if_name = "gif";
- sc->gif_if.if_unit = i;
- sc->gif_if.if_family = APPLE_IF_FAM_GIF;
- sc->gif_if.if_mtu = GIF_MTU;
- sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- sc->gif_if.if_ioctl = gif_ioctl;
- sc->gif_if.if_output = NULL;
- sc->gif_if.if_type = IFT_GIF;
- dlil_if_attach(&sc->gif_if);
+ /* Create first device */
+ gif_create_dev();
+}
+
+/* Creates another gif device if there are none free */
+static void
+gif_create_dev(void)
+{
+ struct gif_softc *sc;
+
+
+ /* Can't create more than GIF_MAXUNIT */
+ if (ngif >= GIF_MAXUNIT)
+ return;
+
+ /* Check for unused gif interface */
+ TAILQ_FOREACH(sc, &gifs, gif_link) {
+ /* If unused, return, no need to create a new interface */
+ if ((sc->gif_if.if_flags & IFF_RUNNING) == 0)
+ return;
+ }
+
+ sc = _MALLOC(sizeof(struct gif_softc), M_DEVBUF, M_WAITOK);
+ if (sc == NULL) {
+ log(LOG_ERR, "gifattach: failed to allocate gif%d\n", ngif);
+ return;
+ }
+
+ bzero(sc, sizeof(struct gif_softc));
+ sc->gif_if.if_softc = sc;
+ sc->gif_if.if_name = GIFNAME;
+ sc->gif_if.if_unit = ngif;
+
+ sc->encap_cookie4 = sc->encap_cookie6 = NULL;
+#ifdef 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));
+ FREE(sc, M_DEVBUF);
+ return;
+ }
+#endif
+#ifdef 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));
+ FREE(sc, M_DEVBUF);
+ return;
+ }
+#endif
+
+ sc->gif_if.if_family= APPLE_IF_FAM_GIF;
+ sc->gif_if.if_mtu = GIF_MTU;
+ sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;