Add support to honor MTU settings from DHCP during netboot.

Defines IP_MIN_MTU as 576.

Glanced over quickly by martin@ and joerg@.
This commit is contained in:
cyber 2010-10-04 23:48:22 +00:00
parent 1d6d6927fd
commit 753a25a966
3 changed files with 81 additions and 8 deletions

View File

@ -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_bootparam = 1; /* BOOTPARAM enabled (default) */
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);
@ -154,6 +156,12 @@ nfs_boot_init(struct nfs_diskless *nd, struct lwp *lwp)
if (error)
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 @@ out:
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)

View File

@ -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 @@ static const u_int8_t vm_rfc1048[4] = { 99, 130, 83, 99 };
#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 @@ static const u_int8_t vm_rfc1048[4] = { 99, 130, 83, 99 };
#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 @@ bootp_addvend(u_char *area)
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 @@ bootp_extract(struct bootp *bootp, int replylen,
char *myname; /* my hostname */
char *mydomain; /* my domainname */
char *rootpath;
uint16_t myinterfacemtu;
int mynamelen;
int mydomainlen;
int rootpathlen;
@ -716,6 +722,8 @@ bootp_extract(struct bootp *bootp, int replylen,
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 @@ bootp_extract(struct bootp *bootp, int replylen,
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 @@ bootp_extract(struct bootp *bootp, int replylen,
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.

View File

@ -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 nfs_diskless {
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 @@ struct nfs_diskless {
};
#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 *);