Exemplo n.º 1
0
ipfpoll(dev_t dev, int events, struct proc *td)
#endif
{
	int unit = GET_MINOR(dev);
	int revents;

	if (unit < 0 || unit > IPL_LOGMAX)
		return 0;

	revents = 0;

	CURVNET_SET(TD_TO_VNET(td));
	switch (unit)
	{
	case IPL_LOGIPF :
	case IPL_LOGNAT :
	case IPL_LOGSTATE :
#ifdef IPFILTER_LOG
		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&V_ipfmain, unit))
			revents |= events & (POLLIN | POLLRDNORM);
#endif
		break;
	case IPL_LOGAUTH :
		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&V_ipfmain))
			revents |= events & (POLLIN | POLLRDNORM);
		break;
	case IPL_LOGSYNC :
		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&V_ipfmain))
			revents |= events & (POLLIN | POLLRDNORM);
		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&V_ipfmain))
			revents |= events & (POLLOUT | POLLWRNORM);
		break;
	case IPL_LOGSCAN :
	case IPL_LOGLOOKUP :
	default :
		break;
	}

	if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
		selrecord(td, &V_ipfmain.ipf_selwait[unit]);
	CURVNET_RESTORE();

	return revents;
}
Exemplo n.º 2
0
void
bootpc_init(void)
{
	struct bootpc_ifcontext *ifctx, *nctx;	/* Interface BOOTP contexts */
	struct bootpc_globalcontext *gctx; 	/* Global BOOTP context */
	struct ifnet *ifp;
	int error;
#ifndef BOOTP_WIRED_TO
	int ifcnt;
#endif
	struct nfsv3_diskless *nd;
	struct thread *td;

	nd = &nfsv3_diskless;
	td = curthread;

	/*
	 * If already filled in, don't touch it here
	 */
	if (nfs_diskless_valid != 0)
		return;

	gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO);
	if (gctx == NULL)
		panic("Failed to allocate bootp global context structure");

	gctx->xid = ~0xFFFF;
	gctx->starttime = time_second;

	/*
	 * Find a network interface.
	 */
	CURVNET_SET(TD_TO_VNET(td));
#ifdef BOOTP_WIRED_TO
	printf("bootpc_init: wired to interface '%s'\n",
	       __XSTRING(BOOTP_WIRED_TO));
	allocifctx(gctx);
#else
	/*
	 * Preallocate interface context storage, if another interface
	 * attaches and wins the race, it won't be eligible for bootp.
	 */
	IFNET_RLOCK();
	for (ifp = TAILQ_FIRST(&V_ifnet), ifcnt = 0;
	     ifp != NULL;
	     ifp = TAILQ_NEXT(ifp, if_link)) {
		if ((ifp->if_flags &
		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
		    IFF_BROADCAST)
			continue;
		ifcnt++;
	}
	IFNET_RUNLOCK();
	if (ifcnt == 0)
		panic("bootpc_init: no eligible interfaces");
	for (; ifcnt > 0; ifcnt--)
		allocifctx(gctx);
#endif

	IFNET_RLOCK();
	for (ifp = TAILQ_FIRST(&V_ifnet), ifctx = gctx->interfaces;
	     ifp != NULL && ifctx != NULL;
	     ifp = TAILQ_NEXT(ifp, if_link)) {
		strlcpy(ifctx->ireq.ifr_name, ifp->if_xname,
		    sizeof(ifctx->ireq.ifr_name));
#ifdef BOOTP_WIRED_TO
		if (strcmp(ifctx->ireq.ifr_name,
			   __XSTRING(BOOTP_WIRED_TO)) != 0)
			continue;
#else
		if ((ifp->if_flags &
		     (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
		    IFF_BROADCAST)
			continue;
#endif
		ifctx->ifp = ifp;
		ifctx = ifctx->next;
	}
	IFNET_RUNLOCK();
	CURVNET_RESTORE();

	if (gctx->interfaces == NULL || gctx->interfaces->ifp == NULL) {
#ifdef BOOTP_WIRED_TO
		panic("bootpc_init: Could not find interface specified "
		      "by BOOTP_WIRED_TO: "
		      __XSTRING(BOOTP_WIRED_TO));
#else
		panic("bootpc_init: no suitable interface");
#endif
	}

	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
		bootpc_fakeup_interface(ifctx, gctx, td);

	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
		bootpc_compose_query(ifctx, gctx, td);

	error = bootpc_call(gctx, td);

	if (error != 0) {
#ifdef BOOTP_NFSROOT
		panic("BOOTP call failed");
#else
		printf("BOOTP call failed\n");
#endif
	}

	rootdevnames[0] = "nfs:";
#ifdef NFSCLIENT
	rootdevnames[1] = "oldnfs:";
#endif
	mountopts(&nd->root_args, NULL);

	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
		if (bootpc_ifctx_isresolved(ifctx) != 0)
			bootpc_decode_reply(nd, ifctx, gctx);

#ifdef BOOTP_NFSROOT
	if (gctx->gotrootpath == 0)
		panic("bootpc: No root path offered");
#endif

	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next) {
		bootpc_adjust_interface(ifctx, gctx, td);

		soclose(ifctx->so);
	}

	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
		if (ifctx->gotrootpath != 0)
			break;
	if (ifctx == NULL) {
		for (ifctx = gctx->interfaces;
		     ifctx != NULL;
		     ifctx = ifctx->next)
			if (bootpc_ifctx_isresolved(ifctx) != 0)
				break;
	}
	if (ifctx == NULL)
		goto out;

	if (gctx->gotrootpath != 0) {

		setenv("boot.netif.name", ifctx->ifp->if_xname);

		error = md_mount(&nd->root_saddr, nd->root_hostnam,
				 nd->root_fh, &nd->root_fhsize,
				 &nd->root_args, td);
		if (error != 0)
			panic("nfs_boot: mountd root, error=%d", error);

		nfs_diskless_valid = 3;
	}

	strcpy(nd->myif.ifra_name, ifctx->ireq.ifr_name);
	bcopy(&ifctx->myaddr, &nd->myif.ifra_addr, sizeof(ifctx->myaddr));
	bcopy(&ifctx->myaddr, &nd->myif.ifra_broadaddr, sizeof(ifctx->myaddr));
	((struct sockaddr_in *) &nd->myif.ifra_broadaddr)->sin_addr.s_addr =
		ifctx->myaddr.sin_addr.s_addr |
		~ ifctx->netmask.sin_addr.s_addr;
	bcopy(&ifctx->netmask, &nd->myif.ifra_mask, sizeof(ifctx->netmask));

out:
	for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = nctx) {
		nctx = ifctx->next;
		free(ifctx, M_TEMP);
	}
	free(gctx, M_TEMP);
}
Exemplo n.º 3
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);
}