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>
(cherry picked from commit a433b3813d8c38b491d2baa7b433973f2d6cd7c6)

Gert Doering authored on 2016/11/08 21:45:06
Showing 1 changed files
... ...
@@ -635,8 +635,8 @@ void delete_route_connected_v6_net(struct tuntap * tt,
635 635
  * is still point to point and no layer 2 resolution is done...
636 636
  */
637 637
 
638
-const char *
639
-create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
638
+in_addr_t
639
+create_arbitrary_remote( struct tuntap *tt )
640 640
 {
641 641
   in_addr_t remote;
642 642
 
... ...
@@ -644,7 +644,7 @@ create_arbitrary_remote( struct tuntap *tt, struct gc_arena * gc )
644 644
 
645 645
   if ( remote == tt->local ) remote ++;
646 646
 
647
-  return print_in_addr_t (remote, 0, gc);
647
+  return remote;
648 648
 }
649 649
 #endif
650 650
 
... ...
@@ -1126,6 +1126,8 @@ do_ifconfig (struct tuntap *tt,
1126 1126
 
1127 1127
 #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1128 1128
 
1129
+      in_addr_t remote_end;		/* for "virtual" subnet topology */
1130
+
1129 1131
       /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1130 1132
       if (tun)
1131 1133
 	argv_printf (&argv,
... ...
@@ -1138,12 +1140,13 @@ do_ifconfig (struct tuntap *tt,
1138 1138
 			  );
1139 1139
       else if ( tt->topology == TOP_SUBNET )
1140 1140
 	{
1141
+	    remote_end = create_arbitrary_remote( tt );
1141 1142
 	    argv_printf (&argv,
1142 1143
 			  "%s %s %s %s mtu %d netmask %s up",
1143 1144
 			  IFCONFIG_PATH,
1144 1145
 			  actual,
1145 1146
 			  ifconfig_local,
1146
-			  create_arbitrary_remote( tt, &gc ),
1147
+			  print_in_addr_t (remote_end, 0, &gc),
1147 1148
 			  tun_mtu,
1148 1149
 			  ifconfig_remote_netmask
1149 1150
 			  );
... ...
@@ -1170,7 +1173,7 @@ do_ifconfig (struct tuntap *tt,
1170 1170
           r.flags = RT_DEFINED;
1171 1171
           r.network = tt->local & tt->remote_netmask;
1172 1172
           r.netmask = tt->remote_netmask;
1173
-          r.gateway = tt->local;
1173
+          r.gateway = remote_end;
1174 1174
           add_route (&r, tt, 0, NULL, es);
1175 1175
         }
1176 1176