Browse code

Repair topology subnet on FreeBSD 11

We used to add "route for this subnet" by using our own address as
the gateway address, which used to mean "connected to the interface,
no gateway". FreeBSD commit 293159 changed the kernel side of that
assumption so "my address" is now always bound to "lo0" - thus, our
subnet route also ended up pointing to "lo0", breaking connectivity
for all hosts in the subnet except the one we used as "remote".

commit 60fd44e501f200 already introduced a "remote address" we use
for the "ifconfig tunX <us> <remote>" part - extend that to be used
as gateway address for the "tunX subnet" as well, and things will
work more robustly.

Tested on FreeBSD 11.0-RELEASE and 7.4-RELEASE (client and server)
(this particular issue is not present before 11.0, but "adding the
subnet route" never worked right, not even in 7.4 - 11.0 just made
the problem manifest more clearly)

Trac #425
URL: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207831

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <20161108124506.32559-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg12950.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Gert Doering authored on 2016/11/08 21:45:06
Showing 1 changed files
... ...
@@ -721,8 +721,8 @@ void delete_route_connected_v6_net(struct tuntap * tt,
721 721
  * is still point to point and no layer 2 resolution is done...
722 722
  */
723 723
 
724
-const char *
725
-create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
724
+in_addr_t
725
+create_arbitrary_remote( struct tuntap *tt )
726 726
 {
727 727
   in_addr_t remote;
728 728
 
... ...
@@ -730,7 +730,7 @@ create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
730 730
 
731 731
   if ( remote == tt->local ) remote ++;
732 732
 
733
-  return print_in_addr_t (remote, 0, gc);
733
+  return remote;
734 734
 }
735 735
 #endif
736 736
 
... ...
@@ -1230,6 +1230,8 @@ do_ifconfig (struct tuntap *tt,
1230 1230
 
1231 1231
 #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1232 1232
 
1233
+      in_addr_t remote_end;		/* for "virtual" subnet topology */
1234
+
1233 1235
       /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1234 1236
       if (tun)
1235 1237
 	argv_printf (&argv,
... ...
@@ -1242,12 +1244,13 @@ do_ifconfig (struct tuntap *tt,
1242 1242
 			  );
1243 1243
       else if ( tt->topology == TOP_SUBNET )
1244 1244
 	{
1245
+	    remote_end = create_arbitrary_remote( tt );
1245 1246
 	    argv_printf (&argv,
1246 1247
 			  "%s %s %s %s mtu %d netmask %s up",
1247 1248
 			  IFCONFIG_PATH,
1248 1249
 			  actual,
1249 1250
 			  ifconfig_local,
1250
-			  create_arbitrary_remote( tt, &gc ),
1251
+			  print_in_addr_t (remote_end, 0, &gc),
1251 1252
 			  tun_mtu,
1252 1253
 			  ifconfig_remote_netmask
1253 1254
 			  );
... ...
@@ -1274,7 +1277,7 @@ do_ifconfig (struct tuntap *tt,
1274 1274
           r.flags = RT_DEFINED;
1275 1275
           r.network = tt->local & tt->remote_netmask;
1276 1276
           r.netmask = tt->remote_netmask;
1277
-          r.gateway = tt->local;
1277
+          r.gateway = remote_end;
1278 1278
           add_route (&r, tt, 0, NULL, es);
1279 1279
         }
1280 1280