[PATCH] ipconfig dhcp mtu option support

From: Hans-Peter Jansen (hpj@urpla.net)
Date: Sat Jun 21 2003 - 20:13:13 EST


Hi,

while experimenting with jumbo frames in a diskless setup, I came
across the problem to enable them properly on the client. This is
due to missing support for the dhcp interface-mtu option in ipconfig.

It took me this patch to make them work. Note, that I ommited the
bootp_init_ext, so this one is limited to dhcp by now... While at
it, I've cleaned up the ifreq struct usage a bit.

If you're going to test this, please let me know, if it __works__
for you, too, since I plan to send it to Marcelo, when 'enough'
positives arrived here.

BTW, anybody willing to apply and test this on 2.5?

Enjoy,
Pete

P.S.: I'm using e1000 (Intel Pro/1000 MT Desktop) GB NICs here.

--- linux-2.4.20/net/ipv4/ipconfig.c.orig 2003-06-21 17:24:21.000000000 +0200
+++ linux/net/ipv4/ipconfig.c 2003-06-22 01:50:53.000000000 +0200
@@ -27,10 +27,13 @@
  * Merged changes from 2.2.19 into 2.4.3
  * -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
  *
  * Multipe Nameservers in /proc/net/pnp
  * -- Josef Siemes <jsiemes@web.de>, Aug 2002
+ *
+ * Support for MTU selection via DHCP
+ * -- Hans-Peter Jansen <hpj@urpla.net>, June 2003
  */
 
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -144,10 +147,13 @@
  */
 
 /* Name of user-selected boot device */
 static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
 
+/* MTU of device (if requested) */
+static int ic_dev_mtu __initdata = 0;
+
 /* Protocols supported by available interfaces */
 static int ic_proto_have_if __initdata = 0;
 
 #ifdef IPCONFIG_DYNAMIC
 static spinlock_t ic_recv_lock = SPIN_LOCK_UNLOCKED;
@@ -262,21 +268,32 @@
         sin->sin_family = AF_INET;
         sin->sin_addr.s_addr = addr;
         sin->sin_port = port;
 }
 
-static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
+static int __init ic_devinet_ioctl(unsigned int cmd, struct ifreq *arg)
 {
         int res;
 
         mm_segment_t oldfs = get_fs();
         set_fs(get_ds());
         res = devinet_ioctl(cmd, arg);
         set_fs(oldfs);
         return res;
 }
 
+static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
+{
+ int res;
+
+ mm_segment_t oldfs = get_fs();
+ set_fs(get_ds());
+ res = dev_ioctl(cmd, arg);
+ set_fs(oldfs);
+ return res;
+}
+
 static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
 {
         int res;
 
         mm_segment_t oldfs = get_fs();
@@ -291,30 +308,38 @@
  */
 
 static int __init ic_setup_if(void)
 {
         struct ifreq ir;
- struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
+ struct sockaddr_in *sin = (void *) &ir.ifr_addr;
         int err;
 
         memset(&ir, 0, sizeof(ir));
- strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
+ strcpy(ir.ifr_name, ic_dev->name);
         set_sockaddr(sin, ic_myaddr, 0);
- if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
+ if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
                 printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
                 return -1;
         }
         set_sockaddr(sin, ic_netmask, 0);
- if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
+ if ((err = ic_devinet_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
                 printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
                 return -1;
         }
         set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
- if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
+ if ((err = ic_devinet_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
                 printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
                 return -1;
         }
+ if (ic_dev_mtu) {
+ strcpy(ir.ifr_name, ic_dev->name);
+ ir.ifr_mtu = ic_dev_mtu;
+ if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
+ printk(KERN_ERR "IP-Config: Unable to set interface mtu to %d (%d).\n",
+ ic_dev_mtu, err);
+ /* Don't error out because set mtu failure, just notice the operator */
+ }
         return 0;
 }
 
 static int __init ic_setup_routes(void)
 {
@@ -576,10 +601,11 @@
                         3, /* Default gateway */
                         6, /* DNS server */
                         12, /* Host name */
                         15, /* Domain name */
                         17, /* Boot path */
+ 26, /* MTU */
                         40, /* NIS domain name */
                 };
 
                 *e++ = 55; /* Parameter request list */
                 *e++ = sizeof(ic_req_params);
@@ -777,10 +803,13 @@
                         break;
                 case 17: /* Root path */
                         if (!root_server_path[0])
                                 ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
                         break;
+ case 26:
+ ic_dev_mtu = ntohs(*(u16 *)(ext+1));
+ break;
                 case 40: /* NIS Domain name (_not_ DNS) */
                         ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
                         break;
         }
 }
@@ -1294,10 +1323,12 @@
         printk(",\n host=%s, domain=%s, nis-domain=%s",
                system_utsname.nodename, ic_domain, system_utsname.domainname);
         printk(",\n bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
         printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
         printk(", rootpath=%s", root_server_path);
+ if (ic_dev_mtu)
+ printk(", mtu=%d", ic_dev_mtu);
         printk("\n");
 #endif /* !SILENT */
 
         return 0;
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jun 23 2003 - 22:00:37 EST