support new option "net-type"
PATCH 1/1 support new option "net-type"
As was hinted at with the previous patch, this patch introduces a new config option "net-type". It can be either "ptp" or "subnet".
If net-type is not explicitly given then:
if "dev" is "tun", "net-type" will be "ptp"
if "dev" is "tap", "net-type" will be "subnet"
If it is given, then it overrides that default.
Probably the most useful usage is to set "net-type subnet" when using "dev tap".
This allows you to have a simple subnet of all openvpn clients talking to a given server, and provides some guarantees that only the client allocated a particular IP address will be able to use it.
I'm am not sure how this will work with OPENBSD, NETBSD, or DARWIN as tun.c doesn't seem to be able to ifconfig these with subnets. It definitely works for Linux and should work for WIN32 and FREEBSD.
This patch doesn't include any updates to documentation. If you are happy to accept it, I will update the relevant documentation and send you that patch.
Thanks,
NeilBrown
==========================================
### Diffstat output
./init.c | 3 ++- ./multi.c | 2 +- ./options.c | 25 ++++++++++++++++++++++++- ./options.h | 2 +- ./tun.c | 12 ++++++++++++ ./tun.h | 12 +++--------- 6 files changed, 43 insertions(+), 13 deletions(-)
init.c renamed from init.c~current~ +2 -1
@@ -492,7 +492,7 @@ do_init_route_list (const struct options bool fatal) {const char *gw =NULL ; -int net =dev_to_net (dev_type_enum (options->dev, options->dev_type)); +int net =net_type_enum (options->net_type);if (net ==NET_TYPE_PTP ) gw = options->ifconfig_remote_netmask;
@@ -539,6 +539,7 @@ do_init_tun (struct context *c) c->options.dev_type, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, + c->options.net_type,addr_host (&c->c1.link_socket_addr.local), addr_host (&c->c1.link_socket_addr.remote));
multi.c renamed from multi.c~current~ +1 -1
@@ -204,7 +204,7 @@ multi_init (struct multi_context *m, str/* * Get tun/tap/null device type */ - net =dev_to_net (dev_type_enum (t->options.dev, t->options.dev_type)); + net =net_type_enum (t->options.net_type);/* * Init our multi_context object.
options.c renamed from options.c~current~ +24 -1
@@ -114,6 +114,7 @@ static const char usage_message[] =" does not begin with \"tun\" or \"tap\".\n" "--dev-node node : Explicitly set the device node rather than using\n" " /dev/net/tun, /dev/tun, /dev/tap, etc.\n" +"--net-type ptp|subnet : Override default network type\n" "--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n" "--ifconfig l rn : TUN: configure device to use IP address l as a local\n" " endpoint and rn as a remote endpoint. l & rn should be\n"
@@ -727,6 +728,7 @@ show_settings (const struct options *o)SHOW_STR (dev);SHOW_STR (dev_type);SHOW_STR (dev_node); +SHOW_STR (net_type);SHOW_BOOL (tun_ipv6);SHOW_STR (ifconfig_local);SHOW_STR (ifconfig_remote_netmask);
@@ -901,6 +903,16 @@ options_postprocess (struct options *opt*/ dev =dev_type_enum (options->dev, options->dev_type); +if (options->net_type ==NULL ) +switch (dev) + { +case DEV_TYPE_TUN : options->net_type ="ptp" ;break ; +case DEV_TYPE_TAP : options->net_type ="subnet" ;break ; +default : options->net_type ="ptp" ;break ; + } +if (strcmp (options->net_type,"ptp" ) && +strcmp (options->net_type,"subnet" )) +msg (M_USAGE ,"Options error: --net-type must be 'ptp' or 'subnet'" );/* * Fill in default port number for --remote list */
@@ -1304,6 +1316,7 @@ options_string (const struct options *o, {struct buffer out =alloc_buf (256 );bool tt_local = false; +const char *s;buf_printf (&out,"V4" );
@@ -1311,7 +1324,10 @@ options_string (const struct options *o,* Tunnel Options */ -buf_printf (&out,",dev-type %s" ,dev_type_string (o->dev, o->dev_type)); +buf_printf (&out,",dev-type %s" , (s =dev_type_string (o->dev, o->dev_type))); +if ((strcmp (s,"tun" )==0 &&strcmp (o->net_type,"ptp" ) !=0 ) || + (strcmp (s,"tap" )==0 &&strcmp (o->net_type,"subnet" ) !=0 )) +buf_printf (&out,",net-type %s" , o->net_type);buf_printf (&out,",link-mtu %d" ,EXPANDED_SIZE (frame));buf_printf (&out,",tun-mtu %d" ,PAYLOAD_SIZE (frame));buf_printf (&out,",proto %s" ,proto2ascii (proto_remote (o->proto, remote), true));
@@ -1328,6 +1344,7 @@ options_string (const struct options *o, o->dev_type, o->ifconfig_local, o->ifconfig_remote_netmask, + o->net_type, (in_addr_t )0 , (in_addr_t)0);if (tt)
@@ -1945,6 +1962,12 @@ add_option (struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->dev_node = p[1 ]; } +else if (streq (p[0 ],"net-type" ) && p[1 ]) + { + ++i; +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->net_type = p[1 ]; + }else if (streq (p[0 ],"tun-ipv6" )) {VERIFY_PERMISSION (OPT_P_UP );
options.h renamed from options.h~current~ +1 -1
@@ -109,6 +109,7 @@ struct optionsconst char *dev;const char *dev_type;const char *dev_node; +const char *net_type;const char *ifconfig_local;const char *ifconfig_remote_netmask;bool ifconfig_noexec;
@@ -311,7 +312,6 @@ struct optionsbool exit_event_initial_state;#endif }; -#define streq (x, y) (!strcmp((x), (y)))/*
tun.c renamed from tun.c~current~ +12 -0
@@ -88,6 +88,16 @@ dev_type_string (const char *dev, const } } +int +net_type_enum (const char *net) +{ +if (strcmp (net,"ptp" ) ==0 ) +return NET_TYPE_PTP ; +else if (strcmp (net,"subnet" ) ==0 ) +return NET_TYPE_SUBNET ; +return NET_TYPE_UNDEF ; +} +const char *dev_component_in_dev_node (const char *dev_node) {
@@ -345,6 +355,7 @@ init_tun (const char *dev, /* --deconst char *dev_type,/* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public) {
@@ -355,6 +366,7 @@ init_tun (const char *dev, /* --declear_tuntap (tt); tt->type =dev_type_enum (dev, dev_type); + tt->nettype =net_type_enum (net_type);if (ifconfig_local_parm && ifconfig_remote_netmask_parm) {
tun.h renamed from tun.h~current~ +3 -9
@@ -112,19 +112,12 @@ struct tuntap_options {#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))) +# define NET_TYPE (tt) ((tt) ? (tt)->nettype :NET_TYPE_UNDEF)int type;/* DEV_TYPE_x as defined in proto.h */ +int nettype;/* NET_TYPE_x */ bool did_ifconfig_setup;bool did_ifconfig;
@@ -208,6 +201,7 @@ struct tuntap *init_tun (const char *devconst char *dev_type,/* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public);
Neil,
Comments Inline below...
Quoted 5 lines · Neil Brown
As was hinted at with the previous patch, this patch introduces a new config option "net-type". It can be either "ptp" or "subnet".
Quoted 8 lines
If net-type is not explicitly given then:
if "dev" is "tun", "net-type" will be "ptp"
if "dev" is "tap", "net-type" will be "subnet"If it is given, then it overrides that default.
Probably the most useful usage is to set "net-type subnet" when using "dev tap".
I'm not sure I understand this. Doesn't current OpenVPN usage associate dev tap interfaces with subnet-based networks?
Quoted 3 lines
This allows you to have a simple subnet of all openvpn clients talking to a given server, and provides some guarantees that only the client allocated a particular IP address will be able to use it.
Can you post any config file examples showing how you would use this?
Quoted 3 lines
I'm am not sure how this will work with OPENBSD, NETBSD, or DARWIN as
tun.cdoesn't seem to be able to ifconfig these with subnets. It definitely works for Linux and should work for WIN32 and FREEBSD.
For portability with tun interfaces across various OSes, OpenVPN tries to treat them all as being point-to-point interfaces, rather than allowing (as some OSes do) a subnet mask to be assigned to a tun endpoint.
James
Quoted 94 lines
This patch doesn't include any updates to documentation. If you are happy to accept it, I will update the relevant documentation and send you that patch.
==========================================
### Diffstat output./init.c | 3 ++- ./multi.c | 2 +- ./options.c | 25 ++++++++++++++++++++++++- ./options.h | 2 +- ./tun.c | 12 ++++++++++++ ./tun.h | 12 +++--------- 6 files changed, 43 insertions(+), 13 deletions(-)diff ./init.c~current~ ./init.c
init.c renamed from init.c~current~ +2
-1@@ -492,7 +492,7 @@ do_init_route_list (const struct options bool fatal) {const char *gw =NULL ; -int net =dev_to_net (dev_type_enum (options->dev, options->dev_type)); +int net =net_type_enum (options->net_type);if (net ==NET_TYPE_PTP ) gw = options->ifconfig_remote_netmask;@@ -539,6 +539,7 @@ do_init_tun (struct context *c) c->options.dev_type, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, + c->options.net_type,addr_host (&c->c1.link_socket_addr.local), addr_host (&c->c1.link_socket_addr.remote));diff ./multi.c~current~ ./multi.c
multi.c renamed from multi.c~current~ +1
-1@@ -204,7 +204,7 @@ multi_init (struct multi_context *m, str/* * Get tun/tap/null device type */ - net =dev_to_net (dev_type_enum (t->options.dev, t->options.dev_type)); + net =net_type_enum (t->options.net_type);/* * Init our multi_context object. diff ./options.c~current~ ./options.c
options.c renamed from options.c~current~ +13
-0@@ -114,6 +114,7 @@ static const char usage_message[] =" does not begin with \"tun\" or \"tap\".\n" "--dev-node node : Explicitly set the device node rather than using\n" " /dev/net/tun, /dev/tun, /dev/tap, etc.\n" +"--net-type ptp|subnet : Override default network type\n" "--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n" "--ifconfig l rn : TUN: configure device to use IP address l as a local\n" " endpoint and rn as a remote endpoint. l & rn should be\n" @@ -727,6 +728,7 @@ show_settings (const struct options *o)SHOW_STR (dev);SHOW_STR (dev_type);SHOW_STR (dev_node); +SHOW_STR (net_type);SHOW_BOOL (tun_ipv6);SHOW_STR (ifconfig_local);SHOW_STR (ifconfig_remote_netmask);@@ -901,6 +903,16 @@ options_postprocess (struct options *opt*/ dev =dev_type_enum (options->dev, options->dev_type); +if (options->net_type ==NULL ) +switch (dev) + { +case DEV_TYPE_TUN : options->net_type ="ptp" ;break ; +case DEV_TYPE_TAP : options->net_type ="subnet" ;break ; +default : options->net_type ="ptp" ;break ; + } +if (strcmp (options->net_type,"ptp" ) && +strcmp (options->net_type,"subnet" )) +msg (M_USAGE ,"Options error: --net-type must be 'ptp' or 'subnet'" );/* * Fill in default port number for --remote list */ @@ -1304,6 +1316,7 @@ options_string (const struct options *o, {struct buffer out =alloc_buf (256 );bool tt_local = false; +const char *s;buf_printf (&out,"V4" );
options.c options_string (const struct options *o, · line 1327
Quoted 5 lines
options.c renamed from options.c~current~ +1
-1@@ -1311,7 +1324,10 @@ options_string (const struct options *o,* Tunnel Options */ -buf_printf (&out,",dev-type %s" ,dev_type_string (o->dev, o->dev_type)); + buf_printf (&out, ",dev-type %s", (s = dev_type_string (o->dev,
o->dev_type)));
options.c options_string (const struct options *o,
Quoted 6 lines
options.c renamed from options.c~current~ +3
-0+if ((strcmp (s,"tun" )==0 &&strcmp (o->net_type,"ptp" ) !=0 ) || + (strcmp (s,"tap" )==0 &&strcmp (o->net_type,"subnet" ) !=0 )) +buf_printf (&out,",net-type %s" , o->net_type);buf_printf (&out,",link-mtu %d" ,EXPANDED_SIZE (frame));buf_printf (&out,",tun-mtu %d" ,PAYLOAD_SIZE (frame)); buf_printf (&out, ",proto %s", proto2ascii (proto_remote (o->proto,
remote), true));
Quoted 113 lines
options.c renamed from options.c~current~ +7
-0@@ -1328,6 +1344,7 @@ options_string (const struct options *o, o->dev_type, o->ifconfig_local, o->ifconfig_remote_netmask, + o->net_type, (in_addr_t )0 , (in_addr_t)0);if (tt)@@ -1945,6 +1962,12 @@ add_option (struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->dev_node = p[1 ]; } +else if (streq (p[0 ],"net-type" ) && p[1 ]) + { + ++i; +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->net_type = p[1 ]; + }else if (streq (p[0 ],"tun-ipv6" )) {VERIFY_PERMISSION (OPT_P_UP );diff ./options.h~current~ ./options.h
options.h renamed from options.h~current~ +1
-1@@ -109,6 +109,7 @@ struct optionsconst char *dev;const char *dev_type;const char *dev_node; +const char *net_type;const char *ifconfig_local;const char *ifconfig_remote_netmask;bool ifconfig_noexec;@@ -311,7 +312,6 @@ struct optionsbool exit_event_initial_state;#endif }; -#define streq (x, y) (!strcmp((x), (y)))/* diff ./tun.c~current~ ./tun.c
tun.c renamed from tun.c~current~ +12
-0@@ -88,6 +88,16 @@ dev_type_string (const char *dev, const } } +int +net_type_enum (const char *net) +{ +if (strcmp (net,"ptp" ) ==0 ) +return NET_TYPE_PTP ; +else if (strcmp (net,"subnet" ) ==0 ) +return NET_TYPE_SUBNET ; +return NET_TYPE_UNDEF ; +} +const char *dev_component_in_dev_node (const char *dev_node) {@@ -345,6 +355,7 @@ init_tun (const char *dev, /* --deconst char *dev_type,/* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public) {@@ -355,6 +366,7 @@ init_tun (const char *dev, /* --declear_tuntap (tt); tt->type =dev_type_enum (dev, dev_type); + tt->nettype =net_type_enum (net_type);if (ifconfig_local_parm && ifconfig_remote_netmask_parm) {diff ./tun.h~current~ ./tun.h
tun.h renamed from tun.h~current~ +3
-9@@ -112,19 +112,12 @@ struct tuntap_options {#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))) +# define NET_TYPE (tt) ((tt) ? (tt)->nettype :NET_TYPE_UNDEF)int type;/* DEV_TYPE_x as defined in proto.h */ +int nettype;/* NET_TYPE_x */ bool did_ifconfig_setup;bool did_ifconfig;@@ -208,6 +201,7 @@ struct tuntap *init_tun (const char *devconst char *dev_type,/* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public);
Quoted 15 lines · On Tuesday July 27, [email protected]... wrote:
Neil,
Comments Inline below...
Quoted 9 lines · Neil Brown
As was hinted at with the previous patch, this patch introduces a new config option "net-type". It can be either "ptp" or "subnet".
If net-type is not explicitly given then:
if "dev" is "tun", "net-type" will be "ptp"
if "dev" is "tap", "net-type" will be "subnet"
Quoted 7 lines
Quoted 4 lines
If it is given, then it overrides that default.
Probably the most useful usage is to set "net-type subnet" when using "dev tap".
I'm not sure I understand this. Doesn't current OpenVPN usage associate dev tap interfaces with subnet-based networks?
Uhmm.. yes. I keep confusing "tap" and "tun".
I should have said:
Probably the most useful usage is to set "net-type subnet" when using "dev tun".
Quoted 7 lines
Quoted 4 lines
This allows you to have a simple subnet of all openvpn clients talking to a given server, and provides some guarantees that only the client allocated a particular IP address will be able to use it.
Can you post any config file examples showing how you would use this?
On the server I have:
mode server
dev tun
net-type subnet
ifconfig 129.94.33.129 255.255.255.128
ifconfig-pool 129.94.33.132 129.94.33.254
push "route-gateway 129.94.33.129"(I'm using a 7bit subnet for this vpn)
On the client I have
dev tun
net-type subnet
pull
Quoted 7 lines
Quoted 3 lines
I'm am not sure how this will work with OPENBSD, NETBSD, or DARWIN as
tun.cdoesn't seem to be able to ifconfig these with subnets. It definitely works for Linux and should work for WIN32 and FREEBSD.For portability with tun interfaces across various OSes, OpenVPN tries to treat them all as being point-to-point interfaces, rather than allowing (as some OSes do) a subnet mask to be assigned to a tun endpoint.
I've thought a bit about this...
I think that a subnet interface can be emulated use a strictly point-to-point interface by simply adding a route to the subnet through the interface.
i.e.
ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2 netmask 255.255.255.0
is equivalent to
ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2
route add net 10.0.0.0 netmask 255.255.255.0 gw 10.0.0.2
which should work on any OS.
This should allow you to configure a tun interface with an effective subnet mask anywhere.
thanks,
NeilBrown