Module Name: src Committed By: cyber Date: Mon Oct 4 23:48:23 UTC 2010
Modified Files: src/sys/nfs: nfs_boot.c nfs_bootdhcp.c nfsdiskless.h Log Message: Add support to honor MTU settings from DHCP during netboot. Defines IP_MIN_MTU as 576. Glanced over quickly by martin@ and jo...@. To generate a diff of this commit: cvs rdiff -u -r1.79 -r1.80 src/sys/nfs/nfs_boot.c cvs rdiff -u -r1.51 -r1.52 src/sys/nfs/nfs_bootdhcp.c cvs rdiff -u -r1.29 -r1.30 src/sys/nfs/nfsdiskless.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/nfs/nfs_boot.c diff -u src/sys/nfs/nfs_boot.c:1.79 src/sys/nfs/nfs_boot.c:1.80 --- src/sys/nfs/nfs_boot.c:1.79 Wed Mar 4 06:56:25 2009 +++ src/sys/nfs/nfs_boot.c Mon Oct 4 23:48:22 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_boot.c,v 1.79 2009/03/04 06:56:25 nisimura Exp $ */ +/* $NetBSD: nfs_boot.c,v 1.80 2010/10/04 23:48:22 cyber Exp $ */ /*- * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_boot.c,v 1.79 2009/03/04 06:56:25 nisimura Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_boot.c,v 1.80 2010/10/04 23:48:22 cyber Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -91,6 +91,8 @@ int nfs_boot_bootstatic = 1; /* BOOTSTATIC enabled (default) */ #endif +#define IP_MIN_MTU 576 + /* mountd RPC */ static int md_mount(struct sockaddr_in *mdsin, char *path, struct nfs_args *argp, struct lwp *l); @@ -155,6 +157,12 @@ return (error); /* + * Set MTU if passed + */ + if (nd->nd_mtu >= IP_MIN_MTU ) + nfs_boot_setmtu(nd->nd_ifp, nd->nd_mtu, lwp); + + /* * If the gateway address is set, add a default route. * (The mountd RPCs may go across a gateway.) */ @@ -236,6 +244,48 @@ return (error); } +void +nfs_boot_setmtu(struct ifnet *ifp, int mtu, struct lwp *lwp) +{ + 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, lwp, NULL); + if (error) { + printf("setmtu: socreate, error=%d\n", error); + return; + } + + /* + * Get structure, set the new MTU, push structure. + */ + error = ifioctl(so, SIOCGIFMTU, (void *)&ireq, lwp); + if (error) { + printf("setmtu: GIFMTU, error=%d\n", error); + goto out; + } + + ireq.ifr_mtu = mtu; + + error = ifioctl(so, SIOCSIFMTU, &ireq, lwp); + if (error) { + printf("setmtu: SIFMTU, error=%d\n", error); + goto out; + } + +out: + soclose(so); + return; +} + int nfs_boot_setaddress(struct ifnet *ifp, struct lwp *lwp, uint32_t addr, uint32_t netmask, uint32_t braddr) Index: src/sys/nfs/nfs_bootdhcp.c diff -u src/sys/nfs/nfs_bootdhcp.c:1.51 src/sys/nfs/nfs_bootdhcp.c:1.52 --- src/sys/nfs/nfs_bootdhcp.c:1.51 Fri Jul 10 12:16:31 2009 +++ src/sys/nfs/nfs_bootdhcp.c Mon Oct 4 23:48:22 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_bootdhcp.c,v 1.51 2009/07/10 12:16:31 roy Exp $ */ +/* $NetBSD: nfs_bootdhcp.c,v 1.52 2010/10/04 23:48:22 cyber Exp $ */ /*- * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_bootdhcp.c,v 1.51 2009/07/10 12:16:31 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_bootdhcp.c,v 1.52 2010/10/04 23:48:22 cyber Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs_boot.h" @@ -176,6 +176,8 @@ #define TAG_DOMAIN_NAME ((unsigned char) 15) #define TAG_SWAP_SERVER ((unsigned char) 16) #define TAG_ROOT_PATH ((unsigned char) 17) +/* RFC 2132 */ +#define TAG_INTERFACE_MTU ((unsigned char) 26) /* End of stuff from bootp.h */ #ifdef NFS_BOOT_DHCP @@ -203,6 +205,8 @@ #define DHCPRELEASE 7 #endif +#define IP_MIN_MTU 576 + #ifdef NFS_BOOT_DHCP #define BOOTP_SIZE_MAX (sizeof(struct bootp)+312-64) #else @@ -453,13 +457,14 @@ int vcilen; *area++ = TAG_PARAM_REQ; - *area++ = 6; + *area++ = 7; *area++ = TAG_SUBNET_MASK; *area++ = TAG_GATEWAY; *area++ = TAG_HOST_NAME; *area++ = TAG_DOMAIN_NAME; *area++ = TAG_ROOT_PATH; *area++ = TAG_SWAP_SERVER; + *area++ = TAG_INTERFACE_MTU; /* Insert a NetBSD Vendor Class Identifier option. */ snprintf(vci, sizeof(vci), "%s:%s:kernel:%s", ostype, MACHINE, @@ -699,6 +704,7 @@ char *myname; /* my hostname */ char *mydomain; /* my domainname */ char *rootpath; + uint16_t myinterfacemtu; int mynamelen; int mydomainlen; int rootpathlen; @@ -716,6 +722,8 @@ rootserver = bootp->bp_siaddr; /* assume that server name field is not overloaded by default */ overloaded = 0; + /* MTU can't be less than IP_MIN_MTU, set to 0 to indicate unset */ + myinterfacemtu = 0; p = &bootp->bp_vend[4]; limit = ((u_char*)bootp) + replylen; @@ -776,6 +784,15 @@ rootpath = p; rootpathlen = len; break; + case TAG_INTERFACE_MTU: + if (len != 2) { + printf("nfs_boot: interface-mtu len != 2 (%d)", + len); + break; + } + memcpy(&myinterfacemtu, p, 2); + myinterfacemtu = ntohs(myinterfacemtu); + break; case TAG_SWAP_SERVER: /* override NFS server address */ if (len < 4) { @@ -831,6 +848,10 @@ printf("nfs_boot: gateway=%s\n", inet_ntoa(nd->nd_gwip)); *flags |= NFS_BOOT_HAS_GWIP; } + if (myinterfacemtu >= IP_MIN_MTU) { + nd->nd_mtu = myinterfacemtu; + printf("nfs_boot: mtu=%d\n", nd->nd_mtu); + } /* * Store the information about our NFS root mount. Index: src/sys/nfs/nfsdiskless.h diff -u src/sys/nfs/nfsdiskless.h:1.29 src/sys/nfs/nfsdiskless.h:1.30 --- src/sys/nfs/nfsdiskless.h:1.29 Mon Oct 27 10:58:23 2008 +++ src/sys/nfs/nfsdiskless.h Mon Oct 4 23:48:23 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: nfsdiskless.h,v 1.29 2008/10/27 10:58:23 cegger Exp $ */ +/* $NetBSD: nfsdiskless.h,v 1.30 2010/10/04 23:48:23 cyber Exp $ */ /*- * Copyright (c) 1995, 1997 The NetBSD Foundation, Inc. @@ -56,6 +56,7 @@ struct in_addr nd_myip; /* My IP address */ struct in_addr nd_mask; /* My netmask */ struct in_addr nd_gwip; /* My gateway */ + int nd_mtu; /* Interface MTU */ /* Information for each mount point we need. */ struct nfs_dlmount nd_root; /* Mount info for root */ #ifdef TFTPROOT @@ -65,11 +66,12 @@ }; #ifdef _KERNEL -int nfs_boot_init (struct nfs_diskless *nd, struct lwp *lwp); -void nfs_boot_cleanup (struct nfs_diskless *nd, struct lwp *lwp); +int nfs_boot_init (struct nfs_diskless *, struct lwp *); +void nfs_boot_cleanup (struct nfs_diskless *, struct lwp *); int nfs_boot_ifupdown (struct ifnet *, struct lwp *, int); int nfs_boot_setaddress (struct ifnet *, struct lwp *, uint32_t, uint32_t, uint32_t); +void nfs_boot_setmtu (struct ifnet *, int, struct lwp *); int nfs_boot_deladdress (struct ifnet *, struct lwp *, uint32_t); void nfs_boot_flushrt (struct ifnet *); int nfs_boot_setrecvtimo (struct socket *);