Subject: Re: changing the MTU and TCP MSS
To: None <netbsd-users@netbsd.org>
From: Steven M. Bellovin <smb@research.att.com>
List: netbsd-users
Date: 03/01/2002 11:58:07
This is a multipart MIME message.

--==_Exmh_-13792672640
Content-Type: text/plain; charset=us-ascii

A couple of weeks ago, I posted a query about changing the MSS 
advertised.  I haven't had time to implement a really clean solution, 
but I'm attaching what I have as possibly-useful to others -- it's 
working well for me.

Ideally, I'd like to force the MSS for a connection to be the MTU 
associated with a route.  That turns out not to work as I had expected. 
As the code exists now, it affects transmit size, but not MSS, and my 
problems are with what the far side sends.  (Nor can I get anyone to 
look at that problem, but that's a local issue.)  Trying to use that 
value for the MSS appears to run afoul of the SYN cache code -- the 
route isn't assigned at the time you need to send the TCP MSS, as best 
I could tell at a quick glance.

Changing the interface MTU and setting net.inet.tcp.mss_ifmtu causes 
drive errors when other machines on the same network send large packets.

What I finally did, as a quick-and-dirty hack, was to write some code 
that overrides in_maxmtu as the maximum MSS -- that's a value that has 
nothing to do with particular interfaces, so I felt free to override it 
with an adminstratively-set value.

Anyway, here are the diffs, for a 1.5.3alpha kernel.  Once you do this, 
you need to recompile sysctl with the new tcp_var.h.
--


--==_Exmh_-13792672640
Content-Type: text/plain ; name="tcp_var.h.diff"; charset=us-ascii
Content-Description: tcp_var.h.diff
Content-Disposition: attachment; filename="tcp_var.h.diff"

*** tcp_var.h.orig	Wed Feb 20 16:19:00 2002
--- tcp_var.h	Wed Feb 20 22:27:13 2002
***************
*** 565,571 ****
  #define	TCPCTL_RSTRATELIMIT	23	/* RST rate limit */
  #endif
  #define	TCPCTL_RSTPPSLIMIT	24	/* RST pps limit */
! #define	TCPCTL_MAXID		25
  
  #define	TCPCTL_NAMES { \
  	{ 0, 0 }, \
--- 565,572 ----
  #define	TCPCTL_RSTRATELIMIT	23	/* RST rate limit */
  #endif
  #define	TCPCTL_RSTPPSLIMIT	24	/* RST pps limit */
! #define	TCPCTL_MSS_SETMSS	25	/* set maximum mss */
! #define	TCPCTL_MAXID		26
  
  #define	TCPCTL_NAMES { \
  	{ 0, 0 }, \
***************
*** 593,598 ****
--- 594,600 ----
  	{ "log_refused",CTLTYPE_INT }, \
  	{ 0, 0 }, \
  	{ "rstppslimit", CTLTYPE_INT }, \
+ 	{ "set_mss", CTLTYPE_INT }, \
  }
  
  #ifdef _KERNEL
***************
*** 618,623 ****
--- 620,626 ----
  extern	int tcp_syn_bucket_limit;/* max entries per hash bucket */
  extern	int tcp_syn_cache_interval; /* compressed state timer */
  extern	int tcp_log_refused;	/* log refused connections */
+ extern	int tcp_set_mss;	/* force mss maximum */
  
  extern	int tcp_rst_ppslim;
  
***************
*** 651,656 ****
--- 654,660 ----
  	{ 1, 0, &tcp_log_refused },		\
  	{ 0 },					\
  	{ 1, 0, &tcp_rst_ppslim },		\
+ 	{ 1, 0, &tcp_set_mss },			\
  }
  
  int	 tcp_attach __P((struct socket *));

--==_Exmh_-13792672640
Content-Type: text/plain ; name="tcp_subr.c.diff"; charset=us-ascii
Content-Description: tcp_subr.c.diff
Content-Disposition: attachment; filename="tcp_subr.c.diff"

*** tcp_subr.c.orig	Wed Feb 20 16:23:41 2002
--- tcp_subr.c	Wed Feb 20 22:37:07 2002
***************
*** 168,173 ****
--- 168,174 ----
  int	tcp_ack_on_push = 0;	/* set to enable immediate ACK-on-PUSH */
  int	tcp_init_win = 1;
  int	tcp_mss_ifmtu = 0;
+ int	tcp_set_mss = 0;
  #ifdef TCP_COMPAT_42
  int	tcp_compat_42 = 1;
  #else
***************
*** 1432,1437 ****
--- 1433,1440 ----
  
  	if (tcp_mss_ifmtu == 0)
  		mss = max(in_maxmtu, mss);
+ 	if (tcp_set_mss > 0)
+ 		mss = min(tcp_set_mss, mss);
  
  	switch (af) {
  	case AF_INET:

--==_Exmh_-13792672640
Content-Type: text/plain; charset=us-ascii

		--Steve Bellovin, http://www.research.att.com/~smb
		Full text of "Firewalls" book now at http://www.wilyhacker.com

--==_Exmh_-13792672640--