int in6_rtrequest(int req, struct sockaddr *dst, struct sockaddr *gw, struct sockaddr *mask, int flags, struct rtentry **ret_nrt, u_int fibnum) { return (rtrequest_fib(req, dst, gw, mask, flags, ret_nrt, fibnum)); }
static int ff_veth_set_gateway(struct ff_veth_softc *sc) { struct sockaddr_in gw; bzero(&gw, sizeof(gw)); gw.sin_len = sizeof(gw); gw.sin_family = AF_INET; gw.sin_addr.s_addr = sc->gateway; struct sockaddr_in dst; bzero(&dst, sizeof(dst)); dst.sin_len = sizeof(dst); dst.sin_family = AF_INET; dst.sin_addr.s_addr = 0; struct sockaddr_in nm; bzero(&nm, sizeof(nm)); nm.sin_len = sizeof(nm); nm.sin_family = AF_INET; nm.sin_addr.s_addr = 0; return rtrequest_fib(RTM_ADD, (struct sockaddr *)&dst, (struct sockaddr *)&gw, (struct sockaddr *)&nm, RTF_GATEWAY, NULL, RT_DEFAULT_FIB); }
static int bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, struct bootpc_globalcontext *gctx, struct thread *td) { int error; struct sockaddr_in defdst; struct sockaddr_in defmask; struct sockaddr_in *sin; struct ifreq *ireq; struct socket *so; struct sockaddr_in *myaddr; struct sockaddr_in *netmask; struct sockaddr_in *gw; ireq = &ifctx->ireq; so = ifctx->so; myaddr = &ifctx->myaddr; netmask = &ifctx->netmask; gw = &ifctx->gw; if (bootpc_ifctx_isresolved(ifctx) == 0) { /* Shutdown interfaces where BOOTP failed */ printf("Shutdown interface %s\n", ifctx->ireq.ifr_name); error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, td); if (error != 0) panic("bootpc_adjust_interface: " "SIOCGIFFLAGS, error=%d", error); ireq->ifr_flags &= ~IFF_UP; error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, td); if (error != 0) panic("bootpc_adjust_interface: " "SIOCSIFFLAGS, error=%d", error); sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); error = ifioctl(so, SIOCDIFADDR, (caddr_t) ireq, td); if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) panic("bootpc_adjust_interface: " "SIOCDIFADDR, error=%d", error); return 0; } printf("Adjusted interface %s\n", ifctx->ireq.ifr_name); /* * Do enough of ifconfig(8) so that the chosen interface * can talk to the servers. (just set the address) */ bcopy(netmask, &ireq->ifr_addr, sizeof(*netmask)); error = ifioctl(so, SIOCSIFNETMASK, (caddr_t) ireq, td); if (error != 0) panic("bootpc_adjust_interface: " "set if netmask, error=%d", error); /* Broadcast is with host part of IP address all 1's */ sin = (struct sockaddr_in *) &ireq->ifr_addr; clear_sinaddr(sin); sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | ~ netmask->sin_addr.s_addr; error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t) ireq, td); if (error != 0) panic("bootpc_adjust_interface: " "set if broadcast addr, error=%d", error); bcopy(myaddr, &ireq->ifr_addr, sizeof(*myaddr)); error = ifioctl(so, SIOCSIFADDR, (caddr_t) ireq, td); if (error != 0 && (error != EEXIST || ifctx == gctx->interfaces)) panic("bootpc_adjust_interface: " "set if addr, error=%d", error); /* Add new default route */ if (ifctx->gotgw != 0 || gctx->gotgw == 0) { clear_sinaddr(&defdst); clear_sinaddr(&defmask); /* XXX MRT just table 0 */ error = rtrequest_fib(RTM_ADD, (struct sockaddr *) &defdst, (struct sockaddr *) gw, (struct sockaddr *) &defmask, (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL, 0); if (error != 0) { printf("bootpc_adjust_interface: " "add net route, error=%d\n", error); return error; } } return 0; }
/* * Mount a remote root fs via. nfs. This depends on the info in the * nfs_diskless structure that has been filled in properly by some primary * bootstrap. * It goes something like this: * - do enough of "ifconfig" by calling ifioctl() so that the system * can talk to the server * - If nfs_diskless.mygateway is filled in, use that address as * a default gateway. * - build the rootfs mount point and call mountnfs() to do the rest. * * It is assumed to be safe to read, modify, and write the nfsv3_diskless * structure, as well as other global NFS client variables here, as * nfs_mountroot() will be called once in the boot before any other NFS * client activity occurs. */ int nfs_mountroot(struct mount *mp) { struct thread *td = curthread; struct nfsv3_diskless *nd = &nfsv3_diskless; struct socket *so; struct vnode *vp; struct ifreq ir; int error; u_long l; char buf[128]; char *cp; #if defined(BOOTP_NFSROOT) && defined(BOOTP) bootpc_init(); /* use bootp to get nfs_diskless filled in */ #elif defined(NFS_ROOT) nfs_setup_diskless(); #endif if (nfs_diskless_valid == 0) { return (-1); } if (nfs_diskless_valid == 1) nfs_convert_diskless(); /* * XXX splnet, so networks will receive... */ splnet(); /* * Do enough of ifconfig(8) so that the critical net interface can * talk to the server. */ error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0, td->td_ucred, td); if (error) panic("nfs_mountroot: socreate(%04x): %d", nd->myif.ifra_addr.sa_family, error); #if 0 /* XXX Bad idea */ /* * We might not have been told the right interface, so we pass * over the first ten interfaces of the same kind, until we get * one of them configured. */ for (i = strlen(nd->myif.ifra_name) - 1; nd->myif.ifra_name[i] >= '0' && nd->myif.ifra_name[i] <= '9'; nd->myif.ifra_name[i] ++) { error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td); if(!error) break; } #endif error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td); if (error) panic("nfs_mountroot: SIOCAIFADDR: %d", error); if ((cp = getenv("boot.netif.mtu")) != NULL) { ir.ifr_mtu = strtol(cp, NULL, 10); bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ); freeenv(cp); error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td); if (error) printf("nfs_mountroot: SIOCSIFMTU: %d", error); } soclose(so); /* * If the gateway field is filled in, set it as the default route. * Note that pxeboot will set a default route of 0 if the route * is not set by the DHCP server. Check also for a value of 0 * to avoid panicking inappropriately in that situation. */ if (nd->mygateway.sin_len != 0 && nd->mygateway.sin_addr.s_addr != 0) { struct sockaddr_in mask, sin; bzero((caddr_t)&mask, sizeof(mask)); sin = mask; sin.sin_family = AF_INET; sin.sin_len = sizeof(sin); /* XXX MRT use table 0 for this sort of thing */ CURVNET_SET(TD_TO_VNET(td)); error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)&nd->mygateway, (struct sockaddr *)&mask, RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB); CURVNET_RESTORE(); if (error) panic("nfs_mountroot: RTM_ADD: %d", error); } /* * Create the rootfs mount point. */ nd->root_args.fh = nd->root_fh; nd->root_args.fhsize = nd->root_fhsize; l = ntohl(nd->root_saddr.sin_addr.s_addr); snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s", (l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam); printf("NFS ROOT: %s\n", buf); nd->root_args.hostname = buf; if ((error = nfs_mountdiskless(buf, &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) { return (error); } /* * This is not really an nfs issue, but it is much easier to * set hostname here and then let the "/etc/rc.xxx" files * mount the right /var based upon its preset value. */ mtx_lock(&prison0.pr_mtx); strlcpy(prison0.pr_hostname, nd->my_hostnam, sizeof (prison0.pr_hostname)); mtx_unlock(&prison0.pr_mtx); inittodr(ntohl(nd->root_time)); return (0); }