RFC {get,set}socktopt SO_DONTFRAGMENT

Mario Sergio Fujikawa Ferreira lioux at FreeBSD.org
Fri May 5 03:38:13 UTC 2006


Hi,

	I would like to propose a new socket option: SO_DONTFRAGMENT
on the lines of IP_DONTFRAG.

	I was trying to tell a socket that it should not fragment
the packets. However, I found out that I could only do it if I had
a "struct socket". If I had a "struct socket" I could set INP_DONTFRAG
which would solve all my problems.

	Unfortunaly, I only had a file descriptor fd from a

int fd = socket(...);

invocation. it is a shame that there is no way to tell a socket fd
that it should not fragment packets on userland (it is possible on
kernel space).

	That is why I wrote this little modification:

1) Added SO_DONTFRAGMENT option to src/sys/sys/socket.h

2) Added SO_DONTFRAGMENT handling to src/sys/kern/uipc_socket.c.
   Actually, it sets either

(struct inpcb *)->inp_flags &= INP_DONTFRAG;

or 

(struct inpcb *)->inp_flags |= ~INP_DONTFRAG;

	I would like to know if the code is correct and what do you
think about this approach. I do think this should be handled by
{get,set}sockopt(2) instead of a ioctl(2) because it is specific
to sockets.

	Moreover, I think this is a very useful option. For instance,
I want to add this to net-im/libjingle to emulate the behavior of
both windows and linux.

	The patch is attached. It can also be found at

http://people.freebsd.org/~lioux/patch-sockopt-dontfragment

	Regards,

-- 
Mario S F Ferreira - DF - Brazil - "I guess this is a signature."
feature, n: a documented bug | bug, n: an undocumented feature
-------------- next part --------------
--- /usr/src/sys/sys/socket.h.orig	Thu May  4 12:56:39 2006
+++ /usr/src/sys/sys/socket.h	Fri May  5 00:14:41 2006
@@ -118,6 +118,7 @@
 #define	SO_ACCEPTFILTER	0x1000		/* there is an accept filter */
 #define	SO_BINTIME	0x2000		/* timestamp received dgram traffic */
 #endif
+#define	SO_DONTFRAGMENT	0x4000		/* don't fragment packet */
 
 /*
  * Additional options, not kept in so_options.
--- /usr/src/sys/kern/uipc_socket.c.orig	Thu May  4 13:00:50 2006
+++ /usr/src/sys/kern/uipc_socket.c	Fri May  5 00:11:39 2006
@@ -1553,6 +1553,7 @@
 #ifdef MAC
 	struct mac extmac;
 #endif
+	struct	inpcb *inp = sotoinpcb(so);
 
 	error = 0;
 	if (sopt->sopt_level != SOL_SOCKET) {
@@ -1594,6 +1595,7 @@
 		case SO_TIMESTAMP:
 		case SO_BINTIME:
 		case SO_NOSIGPIPE:
+		case SO_DONTFRAGMENT:
 			error = sooptcopyin(sopt, &optval, sizeof optval,
 					    sizeof optval);
 			if (error)
@@ -1603,6 +1605,23 @@
 				so->so_options |= sopt->sopt_name;
 			else
 				so->so_options &= ~sopt->sopt_name;
+
+			switch (sopt->sopt_name) {
+
+#define OPTSET(bit) do {						\
+	INP_LOCK(inp);							\
+	if (optval)							\
+		inp->inp_flags |= bit;					\
+	else								\
+		inp->inp_flags &= ~bit;					\
+	INP_UNLOCK(inp);						\
+} while (0)
+
+			case SO_DONTFRAGMENT:
+				OPTSET(INP_DONTFRAG);
+				break;
+			}
+
 			SOCK_UNLOCK(so);
 			break;
 


More information about the freebsd-arch mailing list