commit b339e65ab0bd94d38c39e02b22e70235250b8b55 Author: Maximilian Wilhelm Date: Thu Jul 26 01:08:13 2007 +0200 Applied patch 3 from Neil Brown. This is the third for 4 patches. Possible it is a little more controversial. This patch doesn't actually make any functional change to openvpn. However it prepares the way for a functional change to be implemented in the next patch. (Ignoring null,) openvpn has two types for devices, tun and tap. It also has two ways of configuring the local interface: pointopoint or subnet. This is most obvious in the usage of "ifconfig": in "pointopoint" mode the second argument is the remote IP address, in subnet mode the second argument is a subnet. Currently openvpn has a built in assumption that if it is using a tun device it should work in pointopoint mode, and if it is use a tap device it should work in subnet mode. I don't think this assumption is necessarily correct. In particular, I think it can be useful to run with a tun device and subnet mode. This would be only really useful when using the new server mode, but it is (for me at least) particularly useful in that situation. I want to use tun devices (as I am only interested in IP traffic, and I want some checking of source IP address to be done) but I want to treat the collection of openvpn instances (the server and several clients) as a single subnet. A particular advantage of this is that ifconfig-pool can hand out individual IP addresses to clients instead of 2-bit subnets. This patch introduces a concept of a "NET_TYPE" which can be NET_TYPE_PTP or NET_TYPE_SUBNET. In this patch, the NET_TYPE is determines directly from the TUNNEL_TYPE. All the times where TUNNEL_TYPE are currently used where the important issues is "subnet or pointopoint" have been change to use NET_TYPE instead. Thus this change does (as mentioned) not actually affect functionality (yet), only appearance of the code. If you aren't convinced that this is a good idea, I am happy to discuss it further. Thanks, NeilBrown -- http://sourceforge.net/mailarchive/forum.php?thread_name=16645.48660.718636.245182%40cse.unsw.edu.au&forum_name=openvpn-devel Signed-off-by: Maximilian Wilhelm diff --git a/init.c b/init.c index 9bd2960..842c941 100644 --- a/init.c +++ b/init.c @@ -551,9 +551,9 @@ do_init_route_list (const struct options *options, struct env_set *es) { const char *gw = NULL; - int dev = dev_type_enum (options->dev, options->dev_type); + int net = dev_to_net (dev_type_enum (options->dev, options->dev_type)); - if (dev == DEV_TYPE_TUN) + if (net == NET_TYPE_PTP) gw = options->ifconfig_remote_netmask; if (options->route_default_gateway) gw = options->route_default_gateway; diff --git a/multi.c b/multi.c index 22ea677..efd0336 100644 --- a/multi.c +++ b/multi.c @@ -203,7 +203,7 @@ reap_buckets_per_pass (int n_buckets) void multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode) { - int dev = DEV_TYPE_UNDEF; + int net = NET_TYPE_UNDEF; msg (D_MULTI_LOW, "MULTI: multi_init called, r=%d v=%d", t->options.real_hash_size, @@ -212,7 +212,7 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa /* * Get tun/tap/null device type */ - dev = dev_type_enum (t->options.dev, t->options.dev_type); + net = dev_to_net (dev_type_enum (t->options.dev, t->options.dev_type)); /* * Init our multi_context object. @@ -278,14 +278,14 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa */ if (t->options.ifconfig_pool_defined) { - if (dev == DEV_TYPE_TAP || t->options.ifconfig_pool_linear) + if (net == NET_TYPE_SUBNET || t->options.ifconfig_pool_linear) { m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV, t->options.ifconfig_pool_start, t->options.ifconfig_pool_end, t->options.duplicate_cn); } - else if (dev == DEV_TYPE_TUN) + else if (net == NET_TYPE_PTP) { m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_30NET, t->options.ifconfig_pool_start, @@ -1080,7 +1080,7 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi) { /* use pool ifconfig address(es) */ mi->context.c2.push_ifconfig_local = remote; - if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN) + if (NET_TYPE (mi->context.c1.tuntap) == NET_TYPE_PTP) { if (mi->context.options.ifconfig_pool_linear) mi->context.c2.push_ifconfig_remote_netmask = mi->context.c1.tuntap->local; @@ -1088,7 +1088,7 @@ multi_select_virtual_addr (struct multi_context *m, struct multi_instance *mi) mi->context.c2.push_ifconfig_remote_netmask = local; mi->context.c2.push_ifconfig_defined = true; } - else if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TAP) + else if (NET_TYPE (mi->context.c1.tuntap) == NET_TYPE_SUBNET) { mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.ifconfig_pool_netmask; if (!mi->context.c2.push_ifconfig_remote_netmask) diff --git a/tun.c b/tun.c index e904a0c..8e5026a 100644 --- a/tun.c +++ b/tun.c @@ -162,25 +162,25 @@ ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt) static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)"; /* - * If !tun, make sure ifconfig_remote_netmask looks + * If !ptp, make sure ifconfig_remote_netmask looks * like a netmask. * - * If tun, make sure ifconfig_remote_netmask looks + * If ptp, make sure ifconfig_remote_netmask looks * like an IPv4 address. */ static void -ifconfig_sanity_check (bool tun, in_addr_t addr) +ifconfig_sanity_check (bool ptp, in_addr_t addr) { struct gc_arena gc = gc_new (); const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000); - if (tun) + if (ptp) { if (looks_like_netmask) msg (M_WARN, "WARNING: Since you are using --dev tun, the second argument to --ifconfig must be an IP address. You are using something (%s) that looks more like a netmask. %s", print_in_addr_t (addr, 0, &gc), ifconfig_warn_how_to_silence); } - else /* tap */ + else /* subnet */ { if (!looks_like_netmask) msg (M_WARN, "WARNING: Since you are using --dev tap, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s", @@ -221,7 +221,7 @@ check_addr_clash (const char *name, if (public) { - if (type == DEV_TYPE_TUN) + if (type == NET_TYPE_PTP) { const in_addr_t test_netmask = 0xFFFFFF00; const in_addr_t public_net = public & test_netmask; @@ -246,7 +246,7 @@ check_addr_clash (const char *name, print_in_addr_t (remote_netmask, 0, &gc), ifconfig_warn_how_to_silence); } - else if (type == DEV_TYPE_TAP) + else if (type == NET_TYPE_SUBNET) { const in_addr_t public_network = public & remote_netmask; const in_addr_t virtual_network = local & remote_netmask; @@ -283,7 +283,7 @@ ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, str struct buffer out = alloc_buf_gc (256, gc); if (tt->did_ifconfig_setup && !disable) { - if (tt->type == DEV_TYPE_TUN) + if (NET_TYPE(tt) == NET_TYPE_PTP) { const char *l, *r; if (remote) @@ -298,7 +298,7 @@ ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, str } buf_printf (&out, "%s %s", r, l); } - else if (tt->type == DEV_TYPE_TAP) + else if (NET_TYPE(tt) == NET_TYPE_SUBNET) { buf_printf (&out, "%s %s", print_in_addr_t (tt->local & tt->remote_netmask, 0, gc), @@ -371,7 +371,7 @@ init_tun (const char *dev, /* --dev option */ if (ifconfig_local_parm && ifconfig_remote_netmask_parm) { - bool tun = false; + bool ptp = false; const char *ifconfig_local = NULL; const char *ifconfig_remote_netmask = NULL; const char *ifconfig_broadcast = NULL; @@ -379,10 +379,10 @@ init_tun (const char *dev, /* --dev option */ /* * We only handle TUN/TAP devices here, not --dev null devices. */ - if (tt->type == DEV_TYPE_TUN) - tun = true; - else if (tt->type == DEV_TYPE_TAP) - tun = false; + if (NET_TYPE(tt) == NET_TYPE_PTP) + ptp = true; + else if (NET_TYPE(tt) == NET_TYPE_SUBNET) + ptp = false; else msg (M_FATAL, "'%s' is not a TUN/TAP device. The --ifconfig option works only for TUN/TAP devices.", dev); @@ -401,7 +401,7 @@ init_tun (const char *dev, /* --dev option */ NULL); tt->remote_netmask = getaddr ( - (tun ? GETADDR_RESOLVE : 0) + (ptp ? GETADDR_RESOLVE : 0) | GETADDR_HOST_ORDER | GETADDR_FATAL_ON_SIGNAL | GETADDR_FATAL, @@ -415,7 +415,7 @@ init_tun (const char *dev, /* --dev option */ */ if (strict_warn) { - ifconfig_sanity_check (tun, tt->remote_netmask); + ifconfig_sanity_check (ptp, tt->remote_netmask); /* * If local_public or remote_public addresses are defined, @@ -423,14 +423,14 @@ init_tun (const char *dev, /* --dev option */ */ check_addr_clash ("local", - tt->type, + NET_TYPE(tt), local_public, tt->local, tt->remote_netmask); check_addr_clash ("remote", tt->type, - remote_public, + NET_TYPE(tt), tt->local, tt->remote_netmask); } @@ -444,7 +444,7 @@ init_tun (const char *dev, /* --dev option */ /* * If TAP-style interface, generate broadcast address. */ - if (!tun) + if (!ptp) { tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask); ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc); @@ -456,7 +456,7 @@ init_tun (const char *dev, /* --dev option */ if (es) { setenv_str (es, "ifconfig_local", ifconfig_local); - if (tun) + if (ptp) { setenv_str (es, "ifconfig_remote", ifconfig_remote_netmask); } @@ -502,7 +502,7 @@ do_ifconfig (struct tuntap *tt, if (tt->did_ifconfig_setup) { - bool tun = false; + bool ptp = false; const char *ifconfig_local = NULL; const char *ifconfig_remote_netmask = NULL; const char *ifconfig_broadcast = NULL; @@ -511,10 +511,10 @@ do_ifconfig (struct tuntap *tt, /* * We only handle TUN/TAP devices here, not --dev null devices. */ - if (tt->type == DEV_TYPE_TUN) - tun = true; - else if (tt->type == DEV_TYPE_TAP) - tun = false; + if (NET_TYPE(tt) == NET_TYPE_PTP) + ptp = true; + else if (NET_TYPE(tt) == NET_TYPE_SUBNET) + ptp = false; else ASSERT (0); /* should have been caught in init_tun */ @@ -527,7 +527,7 @@ do_ifconfig (struct tuntap *tt, /* * If TAP-style device, generate broadcast address. */ - if (!tun) + if (!ptp) ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc); #ifdef ENABLE_MANAGEMENT @@ -554,7 +554,7 @@ do_ifconfig (struct tuntap *tt, msg (M_INFO, "%s", command_line); system_check (command_line, es, S_FATAL, "Linux ip link set failed"); - if (tun) { + if (ptp) { /* * Set the address for the device @@ -580,7 +580,7 @@ do_ifconfig (struct tuntap *tt, } tt->did_ifconfig = true; #else - if (tun) + if (ptp) openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s pointopoint %s mtu %d", actual, @@ -609,7 +609,7 @@ do_ifconfig (struct tuntap *tt, * ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up * ifconfig tun2 netmask 255.255.255.255 */ - if (tun) + if (ptp) { openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s %s mtu %d up", @@ -658,7 +658,7 @@ do_ifconfig (struct tuntap *tt, msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure"); /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ - if (tun) + if (ptp) openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up", actual, @@ -681,7 +681,7 @@ do_ifconfig (struct tuntap *tt, #elif defined(TARGET_NETBSD) - if (tun) + if (ptp) openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up", actual, @@ -722,7 +722,7 @@ do_ifconfig (struct tuntap *tt, /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ - if (tun) + if (ptp) openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up", actual, @@ -746,7 +746,7 @@ do_ifconfig (struct tuntap *tt, #elif defined(TARGET_FREEBSD) /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ - if (tun) + if (ptp) openvpn_snprintf (command_line, sizeof (command_line), IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up", actual, @@ -775,7 +775,7 @@ do_ifconfig (struct tuntap *tt, * Make sure that both ifconfig addresses are part of the * same .252 subnet. */ - if (tun) + if (ptp) { verify_255_255_255_252 (tt->local, tt->remote_netmask); tt->adapter_netmask = ~3; @@ -3106,7 +3106,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 ep[1] = htonl (tt->adapter_netmask); /* At what IP address should the DHCP server masquerade at? */ - if (tt->type == DEV_TYPE_TUN) + if (NET_TYPE(tt) == NET_TYPE_PTP) { ep[2] = htonl (tt->remote_netmask); if (tt->options.dhcp_masq_custom_offset) @@ -3116,7 +3116,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 { in_addr_t dsa; /* DHCP server addr */ - ASSERT (tt->type == DEV_TYPE_TAP); + ASSERT (NET_TYPE(tt) == NET_TYPE_SUBNET); if (tt->options.dhcp_masq_offset < 0) dsa = (tt->local | (~tt->adapter_netmask)) + tt->options.dhcp_masq_offset; diff --git a/tun.h b/tun.h index 76c4867..483c55b 100644 --- a/tun.h +++ b/tun.h @@ -114,9 +114,23 @@ struct tuntap_options { * Define a TUN/TAP dev. */ +/* The device can be configured as pointopoint or subnet */ +#define NET_TYPE_UNDEF 0 +#define NET_TYPE_PTP 2 /* two IP addresses */ +#define NET_TYPE_SUBNET 3 /* an IP address and a subnet mask */ + +static inline dev_to_net(int dev) +{ + /* values for NET_TYPE cunning chosen to match + * DEV_TYPE for which they match + */ + return dev; +} + struct tuntap { # define TUNNEL_TYPE(tt) ((tt) ? ((tt)->type) : DEV_TYPE_UNDEF) +# define NET_TYPE(tt) (dev_to_net(TUNNEL_TYPE(tt))) int type; /* DEV_TYPE_x as defined in proto.h */ bool did_ifconfig_setup;