0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 12:02:28 +02:00

Enable IPv6 Payload in OpenVPN p2mp tun server mode. 20100104-1 release.

(cherry picked from commit ec9dce6387afd198881493bfebf13bb121e8a56b)
This commit is contained in:
Gert Doering 2010-01-07 14:51:40 +01:00
parent 8259bc2599
commit cddff731a0
4 changed files with 269 additions and 6 deletions

180
NOTES Normal file
View File

@ -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?

View File

@ -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)
{

2
push.c
View File

@ -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 )

55
tun.c
View File

@ -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,18 +441,17 @@ 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 */