summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGert Doering <gert@greenie.muc.de>2010-01-07 14:51:40 +0100
committerGert Doering <gert@greenie.muc.de>2011-04-24 17:22:37 +0200
commitcddff731a04d261c638e19b5d37c7ee15d81c19e (patch)
tree43f63c6686e900fef30bb6966ee4c9253b2742ac
parent8259bc2599186b87d51e3f4651454693db25b109 (diff)
downloadopenvpn-cddff731a04d261c638e19b5d37c7ee15d81c19e.tar.gz
openvpn-cddff731a04d261c638e19b5d37c7ee15d81c19e.tar.xz
openvpn-cddff731a04d261c638e19b5d37c7ee15d81c19e.zip
Enable IPv6 Payload in OpenVPN p2mp tun server mode. 20100104-1 release.
(cherry picked from commit ec9dce6387afd198881493bfebf13bb121e8a56b)
-rw-r--r--NOTES180
-rw-r--r--mroute.c38
-rw-r--r--push.c2
-rw-r--r--tun.c55
4 files changed, 269 insertions, 6 deletions
diff --git a/NOTES b/NOTES
new file mode 100644
index 0000000..d494073
--- /dev/null
+++ b/NOTES
@@ -0,0 +1,180 @@
+TODO:
+
+ * tun.c -> init_tun()
+ [ifconfig-Parameter vorbereiten]
+
+ init.c -> do_open_tun() -> init.c::do_init_tun() -> tun.c::init_tun()
+ -> do_ifconfig()
+
+ o tun.c -> do_ifconfig()
+ [ifconfig/ip aufrufen]
+
+ * Linux / ifconfig
+ / Linux / iproute2 ** TESTEN **
+ o FreeBSD
+ / NetBSD ("needs patch", googlen) ** TESTEN **
+ / Solaris ** TESTEN **
+ o OpenBSD
+ o MacOS X
+
+ o tun.c (?) -> interface cleanup ("ip addr del dev tun0 ...")
+
+ o TAP mode und IPv6? Fehlermeldung?
+ o einfach confen
+
+ o ifconfig_ipv6_remote -> kann eigentlich ersatzlos wegfallen
+ [tun.c, init.c, options.c, options.h]
+ o [kann nicht, braucht man als default-gateway auf Solaris :( ]
+
+ * push ifconfig-ipv6
+ push::send_push_reply() -> c->c2.push_ifconfig_local
+
+ ** wo wird das gesetzt? ** multi.c (und ggf. options.c / ifconfig-push)
+
+ o /netbits pushen (push.c) -> options.c "ifconfig-ipv6" muss auch
+ damit zurecht kommen, tut es derzeit aber nicht
+
+ * ifconfig_pool_write() -> IPv6 "wenn pool IPv6 hat"
+
+ * multi::multi_init() -> ifconfig_pool_init()
+
+
+ * "route-ipv6"-Option und "push route-ipv6"
+ o "gateway"
+ o "metric"
+ o "route-gateway-ipv6"-Option
+ o "ifconfig-ipv6-push"-Option
+ options.c -> options.push_ifconfig_...
+ multi.c
+ mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
+
+
+ o "server-ipv6"-Option
+
+ o options.c, add_option() -> wird fuer "lokale" und "push"-Options
+ aufgerufen
+ no_more_than_n_args()
+ struct options [options.h]
+
+ * add_route_to_option_list()
+ [route.c -> add_route_ipv6_to_option_list]
+ [options.h -> options->routes_ipv6]
+
+ o was passiert danach damit?
+
+ * socket.c: ip_or_dns_addr_safe()
+ --> ipv6_addr_safe()
+ --> ipv6_addr_safe_hexplusbits()
+
+ * Makro? helper.c -> helper_client_server() ******
+ * Fehler, wenn options->mode != MODE_SERVER
+ * "tun-ipv6" auto-enablen
+
+ * if (options->tun_ipv6)
+ msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server");
+ [options.c, 1710]
+ [raus]
+
+ o struct tuntap->ipv6 = true, wenn "ipv6" und "system kann das"
+ o Fehler, wenn System kein IPv6 kann
+ ("NetBSD needs patch" -> googlen)
+
+ o Adress-Allokation an Clients (/128 aus ifconfig-ipv6-pool /64 erstmal nur)
+ o hash aus Client-Key als host part?
+ (nein, wir nehmen einfach "den gleichen Offset wie bei IPv4" und
+ add_in6_addr())
+
+ o "iroute-ipv6"-Option
+ o "ifconfig-ipv6"
+ o "ifconfig-ipv6-pool"
+ o "ifconfig-pool-persist-ipv6"-Option
+
+ o was tut #define LINUX_IPV6?
+ o was tut bestehender Code mit "ipv6"?
+
+
+ o Routing-/Forwarding-Funktion
+ read_tun() --> ??
+ ?? --> write_tun()
+
+ [muss für p2p schon funktionieren, d.h. vermutlich ist nur die
+ server-seite anzupassen]
+
+ o ICMP
+
+ o Optionen dokumentieren (-> berniv6)
+ o server-ipv6
+ o ifconfig-ipv6
+ o ifconfig-ipv6-pool
+ o ifconfig-pool-persist (v4+v6, Formataenderung im File)
+ o iroute-ipv6
+ o route-ipv6
+ o tun-ipv6
+
+ * http://www.greenie.net/ipv6/openvpn.html - DONE
+ o man pages, --help
+
+ * options.c
+ - get_ip_addr() --> socket.c getaddr()
+ - openvpn_inet_aton -> OIA_IP "ist IP"
+
+ * options.c, show_p2mp_parms()
+
+ * socket.c, print_in_addr_t() --> print_in6_addr()
+
+ o forward_compatible?
+
+ o ifconfig_ipv6_pool_persist --> einfach ifconfig_pool_persist mitbenutzen?
+ Entscheidung: JA
+ o to be implemented: pool.c
+
+ o route.c:
+ clone_route_option_list(), copy_route_option_list(),
+ new_route_list(), add_route(), init_route_list(), ...
+ add_routes(), delete_routes(), setenv_routes(),
+
+ -> wo werden die aufgerufen, wofuer verwendet, IPv6-Anpassung?
+
+ * add_route() ruft "/sbin/route add..." auf
+ o div. (redirect gateway related) -> route.c::add_route3() -> add_route()
+ o init.c::do_route() -> route.c::add_routes() -> add_route()
+ o init.c::do_open_tun() -> do_route()
+ o forward.c::check_add_routes_action() -> do_route()
+ o init.c::do_open_tun() -> init.c::do_init_route_list() ->
+ route.c::init_route_list()
+ * init.c::do_open_tun() -> do_alloc_route_list() -> new_route_ipv6_list()
+
+ o add_route_ipv6() - implementieren und testen
+ * Linux / ifconfig
+ * Linux / iproute2
+ i FreeBSD
+ i NetBSD ("needs patch", googlen)
+ i Solaris *braucht Gateway*
+ i OpenBSD
+ i MacOS X
+
+ o delete_route_ipv6() - implementieren und testen
+ * Linux / ifconfig
+ * Linux / iproute2
+ i FreeBSD
+ i NetBSD ("needs patch", googlen)
+ i Solaris
+ i OpenBSD
+ i MacOS X
+
+ o Gateway-Logik für IPv6-Routen mitschleifen ("explizit angeben oder
+ aus ifconfig-ipv6 $remote")
+
+ o IPv6 TCPMSS oder "fragmentation required"?
+ o IPv6 MTU auf Interface setzen?
+ o sysdep!
+
+
+TESTEN
+ * ipv6_addr_safe() [--ifconfig-ipv6 null/zu lang/invalid]
+ o ipv6_addr_safe_hexplusbits() [--route-ipv6 ...]
+ * get_ipv6_addr() [--server-ipv6 ...]
+
+ o unmodifizierter 2.1-client -> 2.1+ipv6-Server?
+ o unmodifizierter 2.0-client -> 2.1+ipv6-Server?
+ o wie kann der Server das erkennen, und "kein v6" schicken?
diff --git a/mroute.c b/mroute.c
index af00c1e..5ef07b2 100644
--- a/mroute.c
+++ b/mroute.c
@@ -525,6 +525,44 @@ mroute_helper_del_iroute6 (struct mroute_helper *mh,
}
}
+/* this is a bit inelegant, we really should have a helper to that
+ * is only passed the netbits value, and not the whole struct iroute *
+ * - thus one helper could do IPv4 and IPv6. For the sake of "not change
+ * code unrelated to IPv4" this is left for later cleanup, for now.
+ */
+void
+mroute_helper_add_iroute6 (struct mroute_helper *mh,
+ const struct iroute_ipv6 *ir6)
+{
+ if (ir6->netbits >= 0)
+ {
+ ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
+ mroute_helper_lock (mh);
+ ++mh->cache_generation;
+ ++mh->net_len_refcount[ir6->netbits];
+ if (mh->net_len_refcount[ir6->netbits] == 1)
+ mroute_helper_regenerate (mh);
+ mroute_helper_unlock (mh);
+ }
+}
+
+void
+mroute_helper_del_iroute6 (struct mroute_helper *mh,
+ const struct iroute_ipv6 *ir6)
+{
+ if (ir6->netbits >= 0)
+ {
+ ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
+ mroute_helper_lock (mh);
+ ++mh->cache_generation;
+ --mh->net_len_refcount[ir6->netbits];
+ ASSERT (mh->net_len_refcount[ir6->netbits] >= 0);
+ if (!mh->net_len_refcount[ir6->netbits])
+ mroute_helper_regenerate (mh);
+ mroute_helper_unlock (mh);
+ }
+}
+
void
mroute_helper_free (struct mroute_helper *mh)
{
diff --git a/push.c b/push.c
index e2a9182..1fd8bea 100644
--- a/push.c
+++ b/push.c
@@ -189,6 +189,8 @@ send_push_reply (struct context *c)
const int safe_cap = BCAP (&buf) - extra;
bool push_sent = false;
+ msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );
+
buf_printf (&buf, "%s", cmd);
if ( c->c2.push_ifconfig_ipv6_defined )
diff --git a/tun.c b/tun.c
index 9dcd9e6..88e1f0f 100644
--- a/tun.c
+++ b/tun.c
@@ -433,6 +433,7 @@ init_tun (const char *dev, /* --dev option */
{
struct gc_arena gc = gc_new ();
struct tuntap *tt;
+ bool tun;
ALLOC_OBJ (tt, struct tuntap);
clear_tuntap (tt);
@@ -440,19 +441,18 @@ init_tun (const char *dev, /* --dev option */
tt->type = dev_type_enum (dev, dev_type);
tt->topology = topology;
+ /*
+ * We only handle TUN/TAP devices here, not --dev null devices.
+ */
+ tun = is_tun_p2p (tt);
+
if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
{
- bool tun = false;
const char *ifconfig_local = NULL;
const char *ifconfig_remote_netmask = NULL;
const char *ifconfig_broadcast = NULL;
/*
- * We only handle TUN/TAP devices here, not --dev null devices.
- */
- tun = is_tun_p2p (tt);
-
- /*
* Convert arguments to binary IPv4 addresses.
*/
@@ -1973,6 +1973,15 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
*
*/
+static inline int
+netbsd_modify_read_write_return (int len)
+{
+ if (len > 0)
+ return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
+ else
+ return len;
+}
+
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
{
@@ -2074,12 +2083,46 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
int
write_tun (struct tuntap* tt, uint8_t *buf, int len)
{
+ if (tt->type == DEV_TYPE_TUN)
+ {
+ u_int32_t type;
+ struct iovec iv[2];
+ struct openvpn_iphdr *iph;
+
+ iph = (struct openvpn_iphdr *) buf;
+
+ if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
+ type = htonl (AF_INET6);
+ else
+ type = htonl (AF_INET);
+
+ iv[0].iov_base = (char *)&type;
+ iv[0].iov_len = sizeof (type);
+ iv[1].iov_base = buf;
+ iv[1].iov_len = len;
+
+ return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
+ }
+ else
return write (tt->fd, buf, len);
}
int
read_tun (struct tuntap* tt, uint8_t *buf, int len)
{
+ if (tt->type == DEV_TYPE_TUN)
+ {
+ u_int32_t type;
+ struct iovec iv[2];
+
+ iv[0].iov_base = (char *)&type;
+ iv[0].iov_len = sizeof (type);
+ iv[1].iov_base = buf;
+ iv[1].iov_len = len;
+
+ return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
+ }
+ else
return read (tt->fd, buf, len);
}
#endif /* NETBSD_MULTI_AF */