Attention is currently required from: flichtenheld, plaisthos.
Hello plaisthos, flichtenheld,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/857?usp=email
to review the following change.
Change subject: dco-win: support for iroutes
......................................................................
dco-win: support for iroutes
Unlike Linux/FreeBSD, dco-win doesn't have access to a
system routing table, so we have to maintain internal routing
table in the driver. For that, we have 4 ioctls to add/delete
IPv4/IPv6 iroutes. When adding iroute, we pass peer-id, so that
the driver is able to associate a subnet with a peer context.
Change-Id: I36a5442c0a5667628f419bc64efe5fb562ad3b57
Signed-off-by: Lev Stipakov <[email protected]>
---
M src/openvpn/dco.c
M src/openvpn/dco_win.c
M src/openvpn/dco_win.h
M src/openvpn/ovpn_dco_win.h
4 files changed, 127 insertions(+), 11 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/57/857/1
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index b5a2136..55fe40a 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -637,7 +637,7 @@
dco_install_iroute(struct multi_context *m, struct multi_instance *mi,
struct mroute_addr *addr)
{
-#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || defined(_WIN32)
if (!dco_enabled(&m->top.options))
{
return;
@@ -653,28 +653,34 @@
}
struct context *c = &mi->context;
- const char *dev = c->c1.tuntap->actual_name;
-
if (addrtype == MR_ADDR_IPV6)
{
+#if defined(_WIN32)
+ dco_win_add_iroute_ipv6(&c->c1.tuntap->dco, addr->v6.addr,
addr->netbits, c->c2.tls_multi->peer_id);
+#else
net_route_v6_add(&m->top.net_ctx, &addr->v6.addr, addr->netbits,
- &mi->context.c2.push_ifconfig_ipv6_local, dev, 0,
+ &mi->context.c2.push_ifconfig_ipv6_local,
c->c1.tuntap->actual_name, 0,
DCO_IROUTE_METRIC);
+#endif
}
else if (addrtype == MR_ADDR_IPV4)
{
+#if defined(_WIN32)
+ dco_win_add_iroute_ipv4(&c->c1.tuntap->dco, addr->v4.addr,
addr->netbits, c->c2.tls_multi->peer_id);
+#else
in_addr_t dest = htonl(addr->v4.addr);
net_route_v4_add(&m->top.net_ctx, &dest, addr->netbits,
- &mi->context.c2.push_ifconfig_local, dev, 0,
+ &mi->context.c2.push_ifconfig_local,
c->c1.tuntap->actual_name, 0,
DCO_IROUTE_METRIC);
+#endif
}
-#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) ||
defined(_WIN32) */
}
void
dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi)
{
-#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || defined(_WIN32)
if (!dco_enabled(&m->top.options))
{
return;
@@ -682,7 +688,6 @@
ASSERT(TUNNEL_TYPE(mi->context.c1.tuntap) == DEV_TYPE_TUN);
struct context *c = &mi->context;
- const char *dev = c->c1.tuntap->actual_name;
if (mi->context.c2.push_ifconfig_defined)
{
@@ -690,9 +695,13 @@
ir;
ir = ir->next)
{
+#if defined(_WIN32)
+ dco_win_del_iroute_ipv4(&c->c1.tuntap->dco, htonl(ir->network),
ir->netbits);
+#else
net_route_v4_del(&m->top.net_ctx, &ir->network, ir->netbits,
- &mi->context.c2.push_ifconfig_local, dev,
+ &mi->context.c2.push_ifconfig_local,
c->c1.tuntap->actual_name,
0, DCO_IROUTE_METRIC);
+#endif
}
}
@@ -702,12 +711,16 @@
ir6;
ir6 = ir6->next)
{
+#if defined(_WIN32)
+ dco_win_del_iroute_ipv6(&c->c1.tuntap->dco, ir6->network,
ir6->netbits);
+#else
net_route_v6_del(&m->top.net_ctx, &ir6->network, ir6->netbits,
- &mi->context.c2.push_ifconfig_ipv6_local, dev,
+ &mi->context.c2.push_ifconfig_ipv6_local,
c->c1.tuntap->actual_name,
0, DCO_IROUTE_METRIC);
+#endif
}
}
-#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) ||
defined(_WIN32) */
}
#endif /* defined(ENABLE_DCO) */
diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c
index 14220b6..db2adac 100644
--- a/src/openvpn/dco_win.c
+++ b/src/openvpn/dco_win.c
@@ -873,4 +873,80 @@
return dco_get_version(&ver) && ver.Major >= 2;
}
+void
+dco_win_add_iroute_ipv4(dco_context_t *dco, in_addr_t dst, unsigned int
netbits, unsigned int peer_id)
+{
+ struct gc_arena gc = gc_new();
+
+ OVPN_MP_IROUTE route = {.Addr.Addr4.S_un.S_addr = dst, .Netbits = netbits,
.PeerId = peer_id, .IPv6 = 0};
+
+ msg(D_DCO_DEBUG, "%s: %s/%d -> peer %d", __func__, print_in_addr_t(dst,
IA_NET_ORDER, &gc), netbits, peer_id);
+
+ DWORD bytes_returned = 0;
+ if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_MP_ADD_IROUTE, &route,
+ sizeof(route), NULL, 0, &bytes_returned, NULL))
+ {
+ msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_MP_ADD_IROUTE)
failed");
+ }
+
+ gc_free(&gc);
+}
+
+void
+dco_win_add_iroute_ipv6(dco_context_t *dco, struct in6_addr dst, unsigned int
netbits, unsigned int peer_id)
+{
+ struct gc_arena gc = gc_new();
+
+ OVPN_MP_IROUTE route = { .Addr.Addr6 = dst, .Netbits = netbits, .PeerId =
peer_id, .IPv6 = 1 };
+
+ msg(D_DCO_DEBUG, "%s: %s/%d -> peer %d", __func__, print_in6_addr(dst,
IA_NET_ORDER, &gc), netbits, peer_id);
+
+ DWORD bytes_returned = 0;
+ if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_MP_ADD_IROUTE, &route,
+ sizeof(route), NULL, 0, &bytes_returned, NULL))
+ {
+ msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_MP_ADD_IROUTE)
failed");
+ }
+
+ gc_free(&gc);
+}
+
+void
+dco_win_del_iroute_ipv4(dco_context_t *dco, in_addr_t dst, unsigned int
netbits)
+{
+ struct gc_arena gc = gc_new();
+
+ OVPN_MP_IROUTE route = { .Addr.Addr4.S_un.S_addr = dst, .Netbits =
netbits, .PeerId = -1, .IPv6 = 0 };
+
+ msg(D_DCO_DEBUG, "%s: %s/%d", __func__, print_in_addr_t(dst, IA_NET_ORDER,
&gc), netbits);
+
+ DWORD bytes_returned = 0;
+ if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_MP_DEL_IROUTE, &route,
+ sizeof(route), NULL, 0, &bytes_returned, NULL))
+ {
+ msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_MP_DEL_IROUTE)
failed");
+ }
+
+ gc_free(&gc);
+}
+
+void
+dco_win_del_iroute_ipv6(dco_context_t *dco, struct in6_addr dst, unsigned int
netbits)
+{
+ struct gc_arena gc = gc_new();
+
+ OVPN_MP_IROUTE route = { .Addr.Addr6 = dst, .Netbits = netbits, .PeerId =
-1, .IPv6 = 1 };
+
+ msg(D_DCO_DEBUG, "%s: %s/%d", __func__, print_in6_addr(dst, IA_NET_ORDER,
&gc), netbits);
+
+ DWORD bytes_returned = 0;
+ if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_MP_DEL_IROUTE, &route,
+ sizeof(route), NULL, 0, &bytes_returned, NULL))
+ {
+ msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_MP_DEL_IROUTE)
failed");
+ }
+
+ gc_free(&gc);
+}
+
#endif /* defined(_WIN32) */
diff --git a/src/openvpn/dco_win.h b/src/openvpn/dco_win.h
index 2c2309f..21cb1de 100644
--- a/src/openvpn/dco_win.h
+++ b/src/openvpn/dco_win.h
@@ -24,6 +24,8 @@
#if defined(ENABLE_DCO) && defined(_WIN32)
+#include <in6addr.h>
+
#include "buffer.h"
#include "ovpn_dco_win.h"
#include "sig.h"
@@ -72,6 +74,18 @@
bool
dco_win_supports_multipeer(void);
+void
+dco_win_add_iroute_ipv4(dco_context_t *dco, in_addr_t dst, unsigned int
netbits, unsigned int peer_id);
+
+void
+dco_win_add_iroute_ipv6(dco_context_t *dco, struct in6_addr dst, unsigned int
netbits, unsigned int peer_id);
+
+void
+dco_win_del_iroute_ipv4(dco_context_t *dco, in_addr_t dst, unsigned int
netbits);
+
+void
+dco_win_del_iroute_ipv6(dco_context_t *dco, struct in6_addr dst, unsigned int
netbits);
+
#else /* if defined(ENABLE_DCO) && defined(_WIN32) */
static inline void
diff --git a/src/openvpn/ovpn_dco_win.h b/src/openvpn/ovpn_dco_win.h
index 8003ace..f798c5a 100644
--- a/src/openvpn/ovpn_dco_win.h
+++ b/src/openvpn/ovpn_dco_win.h
@@ -182,6 +182,16 @@
int PeerId;
} OVPN_MP_SWAP_KEYS, * POVPN_MP_SWAP_KEYS;
+typedef struct _OVPN_MP_IROUTE {
+ union {
+ IN_ADDR Addr4;
+ IN6_ADDR Addr6;
+ } Addr;
+ int Netbits;
+ int PeerId;
+ int IPv6;
+} OVPN_MP_IROUTE, * POVPN_MP_IROUTE;
+
#define OVPN_IOCTL_NEW_PEER CTL_CODE(FILE_DEVICE_UNKNOWN, 1,
METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OVPN_IOCTL_GET_STATS CTL_CODE(FILE_DEVICE_UNKNOWN, 2,
METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OVPN_IOCTL_NEW_KEY CTL_CODE(FILE_DEVICE_UNKNOWN, 3,
METHOD_BUFFERED, FILE_ANY_ACCESS)
@@ -201,3 +211,6 @@
#define OVPN_IOCTL_MP_DEL_PEER CTL_CODE(FILE_DEVICE_UNKNOWN, 15,
METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OVPN_IOCTL_MP_SWAP_KEYS CTL_CODE(FILE_DEVICE_UNKNOWN, 16,
METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define OVPN_IOCTL_MP_ADD_IROUTE CTL_CODE(FILE_DEVICE_UNKNOWN, 17,
METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define OVPN_IOCTL_MP_DEL_IROUTE CTL_CODE(FILE_DEVICE_UNKNOWN, 18,
METHOD_BUFFERED, FILE_ANY_ACCESS)
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/857?usp=email
To unsubscribe, or for help writing mail filters, visit
http://gerrit.openvpn.net/settings
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I36a5442c0a5667628f419bc64efe5fb562ad3b57
Gerrit-Change-Number: 857
Gerrit-PatchSet: 1
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: flichtenheld <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
Gerrit-Attention: flichtenheld <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel