Browse code

Fix --mtu-disc option with IPv6 transport

Socket configuration of MTU discovery was done unconditionally at IP level,
which has no effect for other protocols. This fixes the issue of OpenVPN
sending fragmented tcp6/udp6 packets even when 'mtu-disc yes' option is
passed.

Patch V2 (by Arne Schwabe): Rebase to current master and have
separate #ifdefs for IPv4 an IPv6

Signed-off-by: Julien Muchembled <jm@nexedi.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1444470291-2980-1-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10229
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Julien Muchembled authored on 2015/10/10 18:44:51
Showing 3 changed files
... ...
@@ -153,17 +153,32 @@ frame_print (const struct frame *frame,
153 153
 #define MTUDISC_NOT_SUPPORTED_MSG "--mtu-disc is not supported on this OS"
154 154
 
155 155
 void
156
-set_mtu_discover_type (int sd, int mtu_type)
156
+set_mtu_discover_type (int sd, int mtu_type, sa_family_t proto_af)
157 157
 {
158 158
   if (mtu_type >= 0)
159 159
     {
160
-#if defined(HAVE_SETSOCKOPT) && defined(SOL_IP) && defined(IP_MTU_DISCOVER)
161
-      if (setsockopt (sd, SOL_IP, IP_MTU_DISCOVER, (void *) &mtu_type, sizeof (mtu_type)))
162
-	msg (M_ERR, "Error setting IP_MTU_DISCOVER type=%d on TCP/UDP socket",
163
-	     mtu_type);
164
-#else
165
-      msg (M_FATAL, MTUDISC_NOT_SUPPORTED_MSG);
160
+      switch (proto_af)
161
+	{
162
+#if defined(HAVE_SETSOCKOPT) && defined(IP_MTU_DISCOVER)
163
+	case AF_INET:
164
+	  if (setsockopt
165
+	      (sd, IPPROTO_IP, IP_MTU_DISCOVER, &mtu_type, sizeof (mtu_type)))
166
+	    msg (M_ERR, "Error setting IP_MTU_DISCOVER type=%d on TCP/UDP socket",
167
+		 mtu_type);
168
+	  break;
169
+#endif
170
+#if defined(HAVE_SETSOCKOPT) && defined(IPV6_MTU_DISCOVER)
171
+	case AF_INET6:
172
+	  if (setsockopt
173
+	      (sd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &mtu_type, sizeof (mtu_type)))
174
+	    msg (M_ERR, "Error setting IPV6_MTU_DISCOVER type=%d on TCP6/UDP6 socket",
175
+		 mtu_type);
176
+	  break;
166 177
 #endif
178
+	default:
179
+	  msg (M_FATAL, MTUDISC_NOT_SUPPORTED_MSG);
180
+	  break;
181
+	}
167 182
     }
168 183
 }
169 184
 
... ...
@@ -207,7 +207,7 @@ void frame_print (const struct frame *frame,
207 207
 		  int level,
208 208
 		  const char *prefix);
209 209
 
210
-void set_mtu_discover_type (int sd, int mtu_type);
210
+void set_mtu_discover_type (int sd, int mtu_type, sa_family_t proto_af);
211 211
 int translate_mtu_discover_type_name (const char *name);
212 212
 
213 213
 /*
... ...
@@ -1676,7 +1676,7 @@ phase2_set_socket_flags (struct link_socket* sock)
1676 1676
     set_cloexec (sock->ctrl_sd);
1677 1677
 
1678 1678
   /* set Path MTU discovery options on the socket */
1679
-  set_mtu_discover_type (sock->sd, sock->mtu_discover_type);
1679
+  set_mtu_discover_type (sock->sd, sock->mtu_discover_type, sock->info.af);
1680 1680
 
1681 1681
 #if EXTENDED_SOCKET_ERROR_CAPABILITY
1682 1682
   /* if the OS supports it, enable extended error passing on the socket */