Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Sep 2016 21:14:29 +0000 (UTC)
From:      "Conrad E. Meyer" <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305306 - head/sbin/dhclient
Message-ID:  <201609022114.u82LETjU007369@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Fri Sep  2 21:14:29 2016
New Revision: 305306
URL: https://svnweb.freebsd.org/changeset/base/305306

Log:
  dhclient: add support for interface-mtu (26)
  
  Make dhclient set interface MTU if it was provided.
  
  This version implements MTU setting in dhclient itself before it runs
  dhclient-script.
  
  PR:		206721
  Submitted by:	novel@
  Reported by:	Jarrod Petz <jlpetz at gmail.com>
  Reviewed by:	cem, allanjude
  Differential Revision:	https://reviews.freebsd.org/D5675

Modified:
  head/sbin/dhclient/clparse.c
  head/sbin/dhclient/dhclient.c
  head/sbin/dhclient/dhcpd.h
  head/sbin/dhclient/dispatch.c
  head/sbin/dhclient/privsep.c
  head/sbin/dhclient/privsep.h

Modified: head/sbin/dhclient/clparse.c
==============================================================================
--- head/sbin/dhclient/clparse.c	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/clparse.c	Fri Sep  2 21:14:29 2016	(r305306)
@@ -102,6 +102,8 @@ read_client_conf(void)
 	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 	top_level_config.requested_options
 	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
+	top_level_config.requested_options
+	    [top_level_config.requested_option_count++] = DHO_INTERFACE_MTU;
 
 	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
 		do {

Modified: head/sbin/dhclient/dhclient.c
==============================================================================
--- head/sbin/dhclient/dhclient.c	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/dhclient.c	Fri Sep  2 21:14:29 2016	(r305306)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include "privsep.h"
 
 #include <sys/capsicum.h>
+#include <sys/endian.h>
 
 #include <net80211/ieee80211_freebsd.h>
 
@@ -132,6 +133,9 @@ int		 fork_privchld(int, int);
 	    ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 #define	ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
 
+/* Minimum MTU is 68 as per RFC791, p. 24 */
+#define MIN_MTU 68
+
 static time_t	scripttime;
 
 int
@@ -798,9 +802,20 @@ dhcpack(struct packet *packet)
 void
 bind_lease(struct interface_info *ip)
 {
+	struct option_data *opt;
+
 	/* Remember the medium. */
 	ip->client->new->medium = ip->client->medium;
 
+	opt = &ip->client->new->options[DHO_INTERFACE_MTU];
+	if (opt->len == sizeof(u_int16_t)) {
+		u_int16_t mtu = be16dec(opt->data);
+		if (mtu < MIN_MTU)
+			warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
+		else
+			interface_set_mtu_unpriv(privfd, mtu);
+	}
+
 	/* Write out the new lease. */
 	write_client_lease(ip, ip->client->new, 0);
 

Modified: head/sbin/dhclient/dhcpd.h
==============================================================================
--- head/sbin/dhclient/dhcpd.h	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/dhcpd.h	Fri Sep  2 21:14:29 2016	(r305306)
@@ -319,6 +319,8 @@ void cancel_timeout(void (*)(void *), vo
 void add_protocol(char *, int, void (*)(struct protocol *), void *);
 void remove_protocol(struct protocol *);
 int interface_link_status(char *);
+void interface_set_mtu_unpriv(int, u_int16_t);
+void interface_set_mtu_priv(char *, u_int16_t); 
 
 /* hash.c */
 struct hash_table *new_hash(void);

Modified: head/sbin/dhclient/dispatch.c
==============================================================================
--- head/sbin/dhclient/dispatch.c	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/dispatch.c	Fri Sep  2 21:14:29 2016	(r305306)
@@ -43,6 +43,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "dhcpd.h"
+#include "privsep.h"
 
 #include <sys/ioctl.h>
 
@@ -501,3 +502,46 @@ interface_link_status(char *ifname)
 	}
 	return (1);
 }
+
+void
+interface_set_mtu_unpriv(int privfd, u_int16_t mtu)
+{
+	struct imsg_hdr hdr;
+	struct buf *buf;
+	int errs = 0;
+
+	hdr.code = IMSG_SET_INTERFACE_MTU;
+	hdr.len = sizeof(hdr) +
+		sizeof(u_int16_t);
+
+	if ((buf = buf_open(hdr.len)) == NULL)
+		error("buf_open: %m");
+
+	errs += buf_add(buf, &hdr, sizeof(hdr));
+	errs += buf_add(buf, &mtu, sizeof(mtu));
+	if (errs)
+		error("buf_add: %m");
+	
+	if (buf_close(privfd, buf) == -1)
+		error("buf_close: %m");
+}
+
+void
+interface_set_mtu_priv(char *ifname, u_int16_t mtu)
+{
+	struct ifreq ifr;
+	int sock;
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		error("Can't create socket");
+
+	memset(&ifr, 0, sizeof(ifr));
+
+	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	ifr.ifr_mtu = mtu;
+
+	if (ioctl(sock, SIOCSIFMTU, &ifr) == -1)
+		warning("SIOCSIFMTU failed (%d): %s", mtu,
+			strerror(errno));
+	close(sock);
+}

Modified: head/sbin/dhclient/privsep.c
==============================================================================
--- head/sbin/dhclient/privsep.c	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/privsep.c	Fri Sep  2 21:14:29 2016	(r305306)
@@ -111,6 +111,7 @@ dispatch_imsg(struct interface_info *ifi
 	struct client_lease	 lease;
 	int			 ret, i, optlen;
 	struct buf		*buf;
+	u_int16_t		mtu;
 
 	buf_read(fd, &hdr, sizeof(hdr));
 
@@ -235,6 +236,13 @@ dispatch_imsg(struct interface_info *ifi
 	case IMSG_SEND_PACKET:
 		send_packet_priv(ifi, &hdr, fd);
 		break;
+	case IMSG_SET_INTERFACE_MTU:
+		if (hdr.len < sizeof(hdr) + sizeof(u_int16_t))
+			error("corrupted message received");	
+	
+		buf_read(fd, &mtu, sizeof(u_int16_t));
+		interface_set_mtu_priv(ifi->name, mtu);
+		break;
 	default:
 		error("received unknown message, code %d", hdr.code);
 	}

Modified: head/sbin/dhclient/privsep.h
==============================================================================
--- head/sbin/dhclient/privsep.h	Fri Sep  2 21:13:46 2016	(r305305)
+++ head/sbin/dhclient/privsep.h	Fri Sep  2 21:14:29 2016	(r305306)
@@ -36,7 +36,8 @@ enum imsg_code {
 	IMSG_SCRIPT_WRITE_PARAMS,
 	IMSG_SCRIPT_GO,
 	IMSG_SCRIPT_GO_RET,
-	IMSG_SEND_PACKET
+	IMSG_SEND_PACKET,
+	IMSG_SET_INTERFACE_MTU,
 };
 
 struct imsg_hdr {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609022114.u82LETjU007369>