[Openvpn-devel] Fix --show-gateway for IPv6 on NetBSD/i386.

Message ID 20200913145621.12125-1-gert@greenie.muc.de
State Accepted
Headers show
Series
  • [Openvpn-devel] Fix --show-gateway for IPv6 on NetBSD/i386.
Related show

Commit Message

Gert Doering Sept. 13, 2020, 2:56 p.m.
Our ROUNDUP() macro to achieve the required system-specific alignment
for data structures sent to the routing socket was wrong for NetBSD -
unlike OpenBSD/FreeBSD, NetBSD is not using "long" (32/64 bit depending
on OS architecture), and not "uint32_t" either (32/32) like MacOS, but
uint64_t.

So our use of "long" always worked on NetBSD/amd64 and stopped working
on NetBSD/i386 when this was changed on the OS side...

NetBSD conveniently exports a RT_ROUNDUP() macro from <net/route.h> - use
that, and avoid trying to second-guess OS requirements.

While at it, add M_ERRNO to ominous "GDG6: problem writing to routing socket"
error message to differenciate between "EINVAL" and other errors.

Trac: #734

Signed-off-by: Gert Doering <gert@greenie.net>
---
 src/openvpn/route.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Arne Schwabe Sept. 13, 2020, 9:30 p.m. | #1
Am 13.09.20 um 16:56 schrieb Gert Doering:
> Our ROUNDUP() macro to achieve the required system-specific alignment
> for data structures sent to the routing socket was wrong for NetBSD -
> unlike OpenBSD/FreeBSD, NetBSD is not using "long" (32/64 bit depending
> on OS architecture), and not "uint32_t" either (32/32) like MacOS, but
> uint64_t.
> 
> So our use of "long" always worked on NetBSD/amd64 and stopped working
> on NetBSD/i386 when this was changed on the OS side...
> 
> NetBSD conveniently exports a RT_ROUNDUP() macro from <net/route.h> - use
> that, and avoid trying to second-guess OS requirements.
> 
> While at it, add M_ERRNO to ominous "GDG6: problem writing to routing socket"
> error message to differenciate between "EINVAL" and other errors.

Have not tested it but looks sane and using OS code should be more sane
indeed.

Acked-By: Arne Schwabe <arne@rfc2549.org>

Arne
Gert Doering Sept. 14, 2020, 8:02 a.m. | #2
Patch has been applied to many branches... (bugfix).

commit 37aab49b083a9e385970e3ab2dd727ea1a95ff35 (master)
commit 9a695902402faafa343783c38761c4c0ccbb2b83 (HEAD -> release/2.5)
commit 9e9fd488d7d939ac9992f8bd4c7394a39b73d7e4 (HEAD -> release/2.4)
Author: Gert Doering
Date:   Sun Sep 13 16:56:21 2020 +0200

     Fix --show-gateway for IPv6 on NetBSD/i386.

     Signed-off-by: Gert Doering <gert@greenie.net>
     Acked-by: Arne Schwabe <arne@rfc2549.org>
     Message-Id: <20200913145621.12125-1-gert@greenie.muc.de>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20983.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index f127a90a..87febf49 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -49,6 +49,10 @@ 
 #include <linux/rtnetlink.h>            /* RTM_GETROUTE etc. */
 #endif
 
+#if defined(TARGET_NETBSD)
+#include <net/route.h>			/* RT_ROUNDUP(), RT_ADVANCE() */
+#endif
+
 #ifdef _WIN32
 #include "openvpn-msg.h"
 
@@ -3408,11 +3412,15 @@  struct rtmsg {
 
 /* the route socket code is identical for all 4 supported BSDs and for
  * MacOS X (Darwin), with one crucial difference: when going from
- * 32 bit to 64 bit, the BSDs increased the structure size but kept
+ * 32 bit to 64 bit, FreeBSD/OpenBSD increased the structure size but kept
  * source code compatibility by keeping the use of "long", while
  * MacOS X decided to keep binary compatibility by *changing* the API
  * to use "uint32_t", thus 32 bit on all OS X variants
  *
+ * NetBSD does the MacOS way of "fixed number of bits, no matter if
+ * 32 or 64 bit OS", but chose uint64_t.  For maximum portability, we
+ * just use the OS RT_ROUNDUP() macro, which is guaranteed to be correct.
+ *
  * We used to have a large amount of duplicate code here which really
  * differed only in this (long) vs. (uint32_t) - IMHO, worse than
  * having a combined block for all BSDs with this single #ifdef inside
@@ -3421,6 +3429,8 @@  struct rtmsg {
 #if defined(TARGET_DARWIN)
 #define ROUNDUP(a) \
     ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+#elif defined(TARGET_NETBSD)
+#define ROUNDUP(a) RT_ROUNDUP(a)
 #else
 #define ROUNDUP(a) \
     ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@@ -3729,7 +3739,7 @@  get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
     }
     if (write(sockfd, (char *)&m_rtmsg, l) < 0)
     {
-        msg(M_WARN, "GDG6: problem writing to routing socket");
+        msg(M_WARN|M_ERRNO, "GDG6: problem writing to routing socket");
         goto done;
     }