+ while (*p)
+ p = &((*p)->if_next);
+ *p = ifp;
+ ifp->if_index = ++if_index;
+ /* create a link level name for this device */
+ sprint_d(workbuf, ifp->if_unit);
+ namelen = strlen(ifp->if_name);
+ unitlen = strlen(workbuf);
+#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
+ socksize = _offsetof(struct sockaddr_dl, sdl_data[0]) +
+ unitlen + namelen + ifp->if_addrlen;
+#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
+ socksize = ROUNDUP(socksize);
+ ifasize = sizeof(*ifa) + 2 * socksize;
+ ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
+ if (ifa == 0)
+ return;
+ bzero((caddr_t)ifa, ifasize);
+ sdl = (struct sockaddr_dl *)(ifa + 1);
+ ifa->ifa_addr = (struct sockaddr *)sdl;
+ ifa->ifa_ifp = ifp;
+ sdl->sdl_len = socksize;
+ sdl->sdl_family = AF_LINK;
+ bcopy(ifp->if_name, sdl->sdl_data, namelen);
+ bcopy((caddr_t)workbuf, namelen + (caddr_t)sdl->sdl_data, unitlen);
+ sdl->sdl_nlen = (namelen += unitlen);
+ sdl->sdl_index = ifp->if_index;
+ sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
+ ifa->ifa_netmask = (struct sockaddr *)sdl;
+ sdl->sdl_len = socksize - ifp->if_addrlen;
+ while (namelen != 0)
+ sdl->sdl_data[--namelen] = 0xff;
+ ifa->ifa_next = ifp->if_addrlist;
+ ifp->if_addrlist = ifa;