restructure the diskless NFS boot code to keep track of the used trunk
authordrochner <drochner@NetBSD.org>
Sun, 21 Feb 1999 15:07:49 +0000
branchtrunk
changeset 48706 ff720ac195cf
parent 48705 6090f6b76634
child 48707 ec3b25d37f64
restructure the diskless NFS boot code to keep track of the used interface and the address allocated, to roll everything back if the mount fails: -put an interface pointer into "struct nfs_diskless" to have it available for cleanup, don't pass it around anymore where the "struct nfs_diskless" is already passed -add a "cleanup" function which shuts the interface down -in the protocol-specific parts, either return with "everything ready" or "completely shut down" -use common functions for interface initialization and shutdown -add a function to delete all routes associate to an interface (why is this necessary and not done by ~IFF_UP?) g/c diskless swap stuff general cleanup
sys/nfs/nfs_boot.c
sys/nfs/nfs_bootdhcp.c
sys/nfs/nfs_bootparam.c
sys/nfs/nfsdiskless.h
--- a/sys/nfs/nfs_boot.c	Sun Feb 21 14:27:44 1999 +0000
+++ b/sys/nfs/nfs_boot.c	Sun Feb 21 15:07:49 1999 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_boot.c,v 1.49 1998/09/13 13:49:29 christos Exp $	*/
+/*	$NetBSD: nfs_boot.c,v 1.50 1999/02/21 15:07:49 drochner Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
@@ -117,6 +117,7 @@
 		       root_device->dv_xname);
 		return (ENXIO);
 	}
+	nd->nd_ifp = ifp;
 
 	error = EADDRNOTAVAIL; /* ??? */
 #if defined(NFS_BOOT_BOOTP) || defined(NFS_BOOT_DHCP)
@@ -126,13 +127,13 @@
 #else
 		printf("nfs_boot: trying BOOTP\n");
 #endif
-		error = nfs_bootdhcp(ifp, nd, procp);
+		error = nfs_bootdhcp(nd, procp);
 	}
 #endif
 #ifdef NFS_BOOT_BOOTPARAM
 	if (error && nfs_boot_bootparam) {
 		printf("nfs_boot: trying RARP (and RPC/bootparam)\n");
-		error = nfs_bootparam(ifp, nd, procp);
+		error = nfs_bootparam(nd, procp);
 	}
 #endif
 	if (error)
@@ -150,11 +151,171 @@
 	 */
 	error = nfs_boot_getfh(&nd->nd_root);
 
+	if (error)
+		nfs_boot_cleanup(nd, procp);
+
+	return (error);
+}
+
+void
+nfs_boot_cleanup(nd, procp)
+	struct nfs_diskless *nd;
+	struct proc *procp;
+{
+
+	nfs_boot_deladdress(nd->nd_ifp, procp, nd->nd_myip.s_addr);
+	nfs_boot_ifupdown(nd->nd_ifp, procp, 0);
+	nfs_boot_flushrt(nd->nd_ifp);
+}
+
+int
+nfs_boot_ifupdown(ifp, procp, up)
+	struct ifnet *ifp;
+	struct proc *procp;
+	int up;
+{
+	struct socket *so;
+	struct ifreq ireq;
+	int error;
+
+	memset(&ireq, 0, sizeof(ireq));
+	memcpy(ireq.ifr_name, ifp->if_xname, IFNAMSIZ);
+
+	/*
+	 * Get a socket to use for various things in here.
+	 * After this, use "goto out" to cleanup and return.
+	 */
+	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
+	if (error) {
+		printf("ifupdown: socreate, error=%d\n", error);
+		return (error);
+	}
+
+	/*
+	 * Bring up the interface. (just set the "up" flag)
+	 * Get the old interface flags and or IFF_UP into them so
+	 * things like media selection flags are not clobbered.
+	 */
+	error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ireq, procp);
+	if (error) {
+		printf("ifupdown: GIFFLAGS, error=%d\n", error);
+		goto out;
+	}
+	if (up)
+		ireq.ifr_flags |= IFF_UP;
+	else
+		ireq.ifr_flags &= ~IFF_UP;
+	error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)&ireq, procp);
+	if (error) {
+		printf("ifupdown: SIFFLAGS, error=%d\n", error);
+		goto out;
+	}
+
+out:
+	soclose(so);
 	return (error);
 }
 
-int nfs_boot_setrecvtimo(so)
-struct socket *so;
+int
+nfs_boot_setaddress(ifp, procp, addr, netmask, braddr)
+	struct ifnet *ifp;
+	struct proc *procp;
+	u_int32_t addr, netmask, braddr;
+{
+	struct socket *so;
+	struct ifaliasreq iareq;
+	struct sockaddr_in *sin;
+	int error;
+
+	/*
+	 * Get a socket to use for various things in here.
+	 * After this, use "goto out" to cleanup and return.
+	 */
+	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
+	if (error) {
+		printf("setaddress: socreate, error=%d\n", error);
+		return (error);
+	}
+
+	memset(&iareq, 0, sizeof(iareq));
+	memcpy(iareq.ifra_name, ifp->if_xname, IFNAMSIZ);
+
+	/* Set the I/F address */
+	sin = (struct sockaddr_in *)&iareq.ifra_addr;
+	sin->sin_len = sizeof(*sin);
+	sin->sin_family = AF_INET;
+	sin->sin_addr.s_addr = addr;
+
+	/* Set the netmask */
+	if (netmask != INADDR_ANY) {
+		sin = (struct sockaddr_in *)&iareq.ifra_mask;
+		sin->sin_len = sizeof(*sin);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = netmask;
+	} /* else leave subnetmask unspecified (len=0) */
+
+	/* Set the broadcast addr. */
+	if (braddr != INADDR_ANY) {
+		sin = (struct sockaddr_in *)&iareq.ifra_broadaddr;
+		sin->sin_len = sizeof(*sin);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = braddr;
+	} /* else leave broadcast addr unspecified (len=0) */
+
+	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&iareq, procp);
+	if (error) {
+		printf("setaddress, error=%d\n", error);
+		goto out;
+	}
+
+out:
+	soclose(so);
+	return (error);
+}
+
+int
+nfs_boot_deladdress(ifp, procp, addr)
+	struct ifnet *ifp;
+	struct proc *procp;
+	u_int32_t addr;
+{
+	struct socket *so;
+	struct ifreq ireq;
+	struct sockaddr_in *sin;
+	int error;
+
+	/*
+	 * Get a socket to use for various things in here.
+	 * After this, use "goto out" to cleanup and return.
+	 */
+	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
+	if (error) {
+		printf("deladdress: socreate, error=%d\n", error);
+		return (error);
+	}
+
+	memset(&ireq, 0, sizeof(ireq));
+	memcpy(ireq.ifr_name, ifp->if_xname, IFNAMSIZ);
+
+	sin = (struct sockaddr_in *)&ireq.ifr_addr;
+	sin->sin_len = sizeof(*sin);
+	sin->sin_family = AF_INET;
+	sin->sin_addr.s_addr = addr;
+
+	error = ifioctl(so, SIOCDIFADDR, (caddr_t)&ireq, procp);
+	if (error) {
+		printf("deladdress, error=%d\n", error);
+		goto out;
+	}
+
+out:
+	soclose(so);
+	return (error);
+}
+
+int
+nfs_boot_setrecvtimo(so)
+	struct socket *so;
 {
 	struct mbuf *m;
 	struct timeval *tv;
@@ -164,11 +325,12 @@
 	m->m_len = sizeof(*tv);
 	tv->tv_sec = 1;
 	tv->tv_usec = 0;
-	return(sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m));
+	return (sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m));
 }
 
-int nfs_boot_enbroadcast(so)
-struct socket *so;
+int
+nfs_boot_enbroadcast(so)
+	struct socket *so;
 {
 	struct mbuf *m;
 	int32_t *on;
@@ -177,12 +339,13 @@
 	on = mtod(m, int32_t *);
 	m->m_len = sizeof(*on);
 	*on = 1;
-	return(sosetopt(so, SOL_SOCKET, SO_BROADCAST, m));
+	return (sosetopt(so, SOL_SOCKET, SO_BROADCAST, m));
 }
 
-int nfs_boot_sobind_ipport(so, port)
-struct socket *so;
-u_int16_t port;
+int
+nfs_boot_sobind_ipport(so, port)
+	struct socket *so;
+	u_int16_t port;
 {
 	struct mbuf *m;
 	struct sockaddr_in *sin;
@@ -196,7 +359,7 @@
 	sin->sin_port = htons(port);
 	error = sobind(so, m);
 	m_freem(m);
-	return(error);
+	return (error);
 }
 
 /*
@@ -208,15 +371,15 @@
 #define	MAX_RESEND_DELAY 5	/* seconds */
 #define TOTAL_TIMEOUT   30	/* seconds */
 
-int nfs_boot_sendrecv(so, nam, sndproc, snd, rcvproc, rcv,
-		      from_p, context)
-struct socket *so;
-struct mbuf *nam;
-int (*sndproc) __P((struct mbuf*, void*, int));
-struct mbuf *snd;
-int (*rcvproc) __P((struct mbuf*, void*));
-struct mbuf **rcv, **from_p;
-void *context;
+int
+nfs_boot_sendrecv(so, nam, sndproc, snd, rcvproc, rcv, from_p, context)
+	struct socket *so;
+	struct mbuf *nam;
+	int (*sndproc) __P((struct mbuf*, void*, int));
+	struct mbuf *snd;
+	int (*rcvproc) __P((struct mbuf*, void*));
+	struct mbuf **rcv, **from_p;
+	void *context;
 {
 	int error, rcvflg, timo, secs, waited;
 	struct mbuf *m, *from;
@@ -234,7 +397,7 @@
 send_again:
 	waited += timo;
 	if (waited >= TOTAL_TIMEOUT)
-		return(ETIMEDOUT);
+		return (ETIMEDOUT);
 
 	/* Determine new timeout. */
 	if (timo < MAX_RESEND_DELAY)
@@ -307,7 +470,7 @@
 	}
 out:
 	if (from) m_freem(from);
-	return(error);
+	return (error);
 }
 
 /*
@@ -337,13 +500,40 @@
 
 	/* add, dest, gw, mask, flags, 0 */
 	error = rtrequest(RTM_ADD, &dst, &gw, &mask,
-					  (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
+			  (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
 	if (error) {
 		printf("nfs_boot: add route, error=%d\n", error);
 		error = 0;
 	}
 }
 
+static int nfs_boot_delroute __P((struct radix_node *, void *));
+static int
+nfs_boot_delroute(rn, w)
+	struct radix_node *rn;
+	void *w;
+{
+	struct rtentry *rt = (struct rtentry *)rn;
+	int error;
+
+	if (rt->rt_ifp != (struct ifnet *)w)
+		return (0);
+
+	error = rtrequest(RTM_DELETE, rt_key(rt), NULL, rt_mask(rt), 0, NULL);
+	if (error)
+		printf("nfs_boot: del route, error=%d\n", error);
+
+	return (0);
+}
+
+void
+nfs_boot_flushrt(ifp)
+	struct ifnet *ifp;
+{
+
+	rn_walktree(rt_tables[AF_INET], nfs_boot_delroute, ifp);
+}
+
 /*
  * Get an initial NFS file handle using Sun RPC/mountd.
  * Separate function because we used to call it twice.
--- a/sys/nfs/nfs_bootdhcp.c	Sun Feb 21 14:27:44 1999 +0000
+++ b/sys/nfs/nfs_bootdhcp.c	Sun Feb 21 15:07:49 1999 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_bootdhcp.c,v 1.10 1999/02/12 01:38:38 thorpej Exp $	*/
+/*	$NetBSD: nfs_bootdhcp.c,v 1.11 1999/02/21 15:07:49 drochner Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
@@ -220,8 +220,7 @@
 /* Convenience macro */
 #define INTOHL(ina) ((u_int32_t)ntohl((ina).s_addr))
 
-static int bootpc_call __P((struct socket *, struct ifnet *,
-			struct nfs_diskless *, struct proc *));
+static int bootpc_call __P((struct nfs_diskless *, struct proc *));
 static void bootp_extract __P((struct bootp *, int, struct nfs_diskless *));
 
 /* #define DEBUG	XXX */
@@ -237,57 +236,30 @@
  * Get our boot parameters using BOOTP.
  */
 int
-nfs_bootdhcp(ifp, nd, procp)
-	struct ifnet *ifp;
+nfs_bootdhcp(nd, procp)
 	struct nfs_diskless *nd;
 	struct proc *procp;
 {
-	struct ifaliasreq iareq;
-	struct socket *so;
-	struct sockaddr_in *sin;
+	struct ifnet *ifp = nd->nd_ifp;
 	int error;
 
 	/*
-	 * Get a socket to use for various things in here.
-	 * After this, use "goto out" to cleanup and return.
-	 */
-	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
-	if (error) {
-		printf("nfs_boot: socreate, error=%d\n", error);
-		return (error);
-	}
-
-	/*
 	 * Do enough of ifconfig(8) so that the chosen interface
 	 * can talk to the servers.  Use address zero for now.
 	 */
-	memset(&iareq, 0, sizeof(iareq));
-	memcpy(iareq.ifra_name, ifp->if_xname, IFNAMSIZ);
-	/* Set the I/F address */
-	sin = (struct sockaddr_in *)&iareq.ifra_addr;
-	sin->sin_len = sizeof(*sin);
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = INADDR_ANY;
-	/* Leave subnetmask unspecified (len=0) */
-	/* Set the broadcast addr. */
-	sin = (struct sockaddr_in *)&iareq.ifra_broadaddr;
-	sin->sin_len = sizeof(*sin);
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = INADDR_BROADCAST;
-	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&iareq, procp);
+	error = nfs_boot_setaddress(ifp, procp, INADDR_ANY, INADDR_ANY,
+				    INADDR_BROADCAST);
 	if (error) {
 		printf("nfs_boot: set ifaddr zero, error=%d\n", error);
-		goto out;
+		return (error);
 	}
 
 	/* This function call does the real send/recv work. */
-	error = bootpc_call(so, ifp, nd, procp);
+	error = bootpc_call(nd, procp);
+
 	/* Get rid of the temporary (zero) IP address. */
-	/*
-	 * XXX SIOCDIFADDR takes a "struct ifreq", which is
-	 * an exact subset of "struct ifaliasreq".
-	 */
-	(void) ifioctl(so, SIOCDIFADDR, (caddr_t)&iareq, procp);
+	(void) nfs_boot_deladdress(ifp, procp, INADDR_ANY);
+
 	/* NOW we can test the error from bootpc_call. */
 	if (error)
 		goto out;
@@ -295,29 +267,18 @@
 	/*
 	 * Do ifconfig with our real IP address and mask.
 	 */
-	/* I/F address */
-	sin = (struct sockaddr_in *)&iareq.ifra_addr;
-	sin->sin_addr = nd->nd_myip;
-	/* subnetmask */
-	if (nd->nd_mask.s_addr) {
-		sin = (struct sockaddr_in *)&iareq.ifra_mask;
-		sin->sin_len = sizeof(*sin);
-		sin->sin_family = AF_INET;
-		sin->sin_addr = nd->nd_mask;
-	}
-	/* Let ifioctl() default the broadcast address. */
-	sin = (struct sockaddr_in *)&iareq.ifra_broadaddr;
-	sin->sin_len = 0;
-	sin->sin_family = 0;
-	sin->sin_addr.s_addr = 0;
-	error = ifioctl(so, SIOCAIFADDR, (caddr_t)&iareq, procp);
+	error = nfs_boot_setaddress(ifp, procp, nd->nd_myip.s_addr,
+				    nd->nd_mask.s_addr, INADDR_ANY);
 	if (error) {
 		printf("nfs_boot: set ifaddr real, error=%d\n", error);
 		goto out;
 	}
 
 out:
-	soclose(so);
+	if (error) {
+		(void) nfs_boot_ifupdown(ifp, procp, 0);
+		nfs_boot_flushrt(ifp);
+	}
 	return (error);
 }
 
@@ -470,12 +431,12 @@
 }
 
 static int
-bootpc_call(so, ifp, nd, procp)
-	struct socket *so;
-	struct ifnet *ifp;
+bootpc_call(nd, procp)
 	struct nfs_diskless *nd;
 	struct proc *procp;
 {
+	struct socket *so;
+	struct ifnet *ifp = nd->nd_ifp;
 	static u_int32_t xid = ~0xFF;
 	struct bootp *bootp;	/* request */
 	struct mbuf *m, *nam;
@@ -485,6 +446,12 @@
 	u_char hafmt, halen;
 	struct bootpcontext bpc;
 
+	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
+	if (error) {
+		printf("bootp: socreate, error=%d\n", error);
+		return (error);
+	}
+
 	/*
 	 * Initialize to NULL anything that will hold an allocation,
 	 * and free each at the end if not null.
@@ -650,6 +617,7 @@
 		m_freem(m);
 	if (nam)
 		m_freem(nam);
+	soclose(so);
 	return (error);
 }
 
--- a/sys/nfs/nfs_bootparam.c	Sun Feb 21 14:27:44 1999 +0000
+++ b/sys/nfs/nfs_bootparam.c	Sun Feb 21 15:07:49 1999 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_bootparam.c,v 1.10 1998/09/13 13:49:29 christos Exp $	*/
+/*	$NetBSD: nfs_bootparam.c,v 1.11 1999/02/21 15:07:49 drochner Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
@@ -107,52 +107,28 @@
  * is used for all subsequent booptaram RPCs.
  */
 int
-nfs_bootparam(ifp, nd, procp)
-	struct ifnet *ifp;
+nfs_bootparam(nd, procp)
 	struct nfs_diskless *nd;
 	struct proc *procp;
 {
-	struct ifreq ireq;
-	struct in_addr my_ip, gw_ip;
+	struct ifnet *ifp = nd->nd_ifp;
+	struct in_addr my_ip, arps_ip, gw_ip;
 	struct sockaddr_in bp_sin;
 	struct sockaddr_in *sin;
-	struct socket *so;
-	struct nfs_dlmount *gw_ndm;
 #if 0	/* XXX - not yet */
+	struct nfs_dlmount *gw_ndm = 0;
 	char *p;
 	u_int32_t mask;
 #endif	/* XXX */
 	int error;
 
-	gw_ndm = 0;
-	memset(&ireq, 0, sizeof(ireq));
-	memcpy(ireq.ifr_name, ifp->if_xname, IFNAMSIZ);
-
-	/*
-	 * Get a socket to use for various things in here.
-	 * After this, use "goto out" to cleanup and return.
-	 */
-	error = socreate(AF_INET, &so, SOCK_DGRAM, 0);
-	if (error) {
-		printf("nfs_boot: socreate, error=%d\n", error);
-		return (error);
-	}
-
 	/*
 	 * Bring up the interface. (just set the "up" flag)
-	 * Get the old interface flags and or IFF_UP into them so
-	 * things like media selection flags are not clobbered.
 	 */
-	error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ireq, procp);
-	if (error) {
-		printf("nfs_boot: GIFFLAGS, error=%d\n", error);
-		goto out;
-	}
-	ireq.ifr_flags |= IFF_UP;
-	error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)&ireq, procp);
+	error = nfs_boot_ifupdown(ifp, procp, 1);
 	if (error) {
 		printf("nfs_boot: SIFFLAGS, error=%d\n", error);
-		goto out;
+		return (error);
 	}
 
 	error = EADDRNOTAVAIL; /* ??? */
@@ -161,7 +137,7 @@
 		/*
 		 * Do RARP for the interface address.
 		 */
-		error = revarpwhoami(&my_ip, ifp);
+		error = revarpwhoarewe(ifp, &arps_ip, &my_ip);
 		if (error) {
 			printf("revarp failed, error=%d\n", error);
 			goto out;
@@ -170,18 +146,16 @@
 #endif
 
 	nd->nd_myip.s_addr = my_ip.s_addr;
-	printf("nfs_boot: client_addr=0x%x\n",
-	       (u_int32_t)ntohl(my_ip.s_addr));
+	printf("nfs_boot: client_addr=0x%x (RARP from 0x%x)\n",
+	       (u_int32_t)ntohl(my_ip.s_addr),
+	       (u_int32_t)ntohl(arps_ip.s_addr));
 
 	/*
 	 * Do enough of ifconfig(8) so that the chosen interface
 	 * can talk to the servers.  (just set the address)
 	 */
-	sin = (struct sockaddr_in *)&ireq.ifr_addr;
-	sin->sin_len = sizeof(*sin);
-	sin->sin_family = AF_INET;
-	sin->sin_addr = my_ip;
-	error = ifioctl(so, SIOCSIFADDR, (caddr_t)&ireq, procp);
+	error = nfs_boot_setaddress(ifp, procp, my_ip.s_addr,
+				    INADDR_ANY, INADDR_ANY);
 	if (error) {
 		printf("nfs_boot: set ifaddr, error=%d\n", error);
 		goto out;
@@ -205,7 +179,7 @@
 	error = bp_whoami(sin, &my_ip, &gw_ip);
 	if (error) {
 		printf("nfs_boot: bootparam whoami, error=%d\n", error);
-		goto out;
+		goto delout;
 	}
 	printf("nfs_boot: server_addr=0x%x\n",
 		   (u_int32_t)ntohl(sin->sin_addr.s_addr));
@@ -218,15 +192,8 @@
 	error = bp_getfile(sin, "root", &nd->nd_root);
 	if (error) {
 		printf("nfs_boot: bootparam get root: %d\n", error);
-		goto out;
+		goto delout;
 	}
-#if 0
-	error = bp_getfile(sin, "swap", &nd->nd_swap);
-	if (error) {
-		printf("nfs_boot: bootparam get swap: %d\n", error);
-		error = 0;
-	}
-#endif
 
 #ifdef	NFS_BOOT_GATEWAY
 	/*
@@ -281,12 +248,18 @@
 		printf("nfs_boot: set ifmask, error=%d\n", error);
 		error = 0;	/* ignore it */
 	}
+	if (gw_ndm)
+		free(gw_ndm, M_NFSMNT);
 #endif	/* XXX */
 
- out:
-	if (gw_ndm)
-		free(gw_ndm, M_NFSMNT);
-	soclose(so);
+delout:
+	if (error)
+		(void) nfs_boot_deladdress(ifp, procp, my_ip.s_addr);
+out:
+	if (error) {
+		(void) nfs_boot_ifupdown(ifp, procp, 0);
+		nfs_boot_flushrt(ifp);
+	}
 	return (error);
 }
 
--- a/sys/nfs/nfsdiskless.h	Sun Feb 21 14:27:44 1999 +0000
+++ b/sys/nfs/nfsdiskless.h	Sun Feb 21 15:07:49 1999 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfsdiskless.h,v 1.15 1997/09/30 20:44:35 drochner Exp $	*/
+/*	$NetBSD: nfsdiskless.h,v 1.16 1999/02/21 15:07:49 drochner Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
@@ -55,18 +55,23 @@
 	u_char		ndm_fh[NFSX_V3FHMAX]; 	/* The file's file handle */
 };
 struct nfs_diskless {
+	/* the interface used */
+	struct ifnet *nd_ifp;
 	/* A collection of IP addresses, for convenience. */
 	struct in_addr nd_myip; /* My IP address */
 	struct in_addr nd_mask; /* My netmask */
 	struct in_addr nd_gwip; /* My gateway */
 	/* Information for each mount point we need. */
 	struct nfs_dlmount nd_root; 	/* Mount info for root */
-#if 0
-	struct nfs_dlmount nd_swap; 	/* Mount info for swap */
-#endif
 };
 
 int nfs_boot_init __P((struct nfs_diskless *nd, struct proc *procp));
+void nfs_boot_cleanup __P((struct nfs_diskless *nd, struct proc *procp));
+int nfs_boot_ifupdown __P((struct ifnet *, struct proc *, int));
+int nfs_boot_setaddress __P((struct ifnet *, struct proc *,
+			     u_int32_t, u_int32_t, u_int32_t));
+int nfs_boot_deladdress __P((struct ifnet *, struct proc *, u_int32_t));
+void nfs_boot_flushrt __P((struct ifnet *));
 int nfs_boot_setrecvtimo __P((struct socket *));
 int nfs_boot_enbroadcast __P((struct socket *));
 int nfs_boot_sobind_ipport __P((struct socket *, u_int16_t));
@@ -75,6 +80,6 @@
 			   int (*)(struct mbuf*, void*), struct mbuf**,
 			   struct mbuf**, void*));
 
-int nfs_bootdhcp  __P((struct ifnet *, struct nfs_diskless *, struct proc *));
-int nfs_bootparam __P((struct ifnet *, struct nfs_diskless *, struct proc *));
+int nfs_bootdhcp  __P((struct nfs_diskless *, struct proc *));
+int nfs_bootparam __P((struct nfs_diskless *, struct proc *));