Skip to content

Commit

Permalink
Change dev null to be a driver type instead of a special mode of tun/tap
Browse files Browse the repository at this point in the history
Change-Id: I5987ebb7c38ab176eed7efc004ea54f606a77a12
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20240924124328.3037-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg29384.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
  • Loading branch information
schwabe authored and cron2 committed Sep 24, 2024
1 parent d0a9362 commit 8fe14fe
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 105 deletions.
6 changes: 6 additions & 0 deletions src/openvpn/dco.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ dco_check_startup_option(int msglevel, const struct options *o)
return false;
}

if (is_dev_type(o->dev, o->dev_type, "null"))
{
msg(msglevel, "Note: null tun type selected, disabling data channel offload");
return false;
}

if (o->connection_list)
{
const struct connection_list *l = o->connection_list;
Expand Down
16 changes: 15 additions & 1 deletion src/openvpn/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,10 @@ do_init_tun(struct context *c)
/* Using AF_UNIX trumps using DCO */
c->c1.tuntap->backend_driver = DRIVER_AFUNIX;
}
else if (is_dev_type(c->options.dev, c->options.dev_type, "null"))
{
c->c1.tuntap->backend_driver = DRIVER_NULL;
}
#ifdef _WIN32
else
{
Expand Down Expand Up @@ -1858,7 +1862,12 @@ static void
open_tun_backend(struct context *c)
{
struct tuntap *tt = c->c1.tuntap;
if (tt->backend_driver == DRIVER_AFUNIX)

if (tt->backend_driver == DRIVER_NULL)
{
open_tun_null(c->c1.tuntap);
}
else if (tt->backend_driver == DRIVER_AFUNIX)
{
open_tun_afunix(&c->options, c->c2.frame.tun_mtu, tt, c->c2.es);
}
Expand Down Expand Up @@ -2059,6 +2068,11 @@ do_close_tun_simple(struct context *c)
{
close_tun_afunix(c->c1.tuntap);
}
else if (c->c1.tuntap->backend_driver == DRIVER_NULL)
{
free(c->c1.tuntap->actual_name);
free(c->c1.tuntap);
}
else
{
close_tun(c->c1.tuntap, &c->net_ctx);
Expand Down
1 change: 0 additions & 1 deletion src/openvpn/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
* Tunnel types
*/
#define DEV_TYPE_UNDEF 0
#define DEV_TYPE_NULL 1
#define DEV_TYPE_TUN 2 /* point-to-point IP tunnel */
#define DEV_TYPE_TAP 3 /* ethernet (802.3) tunnel */

Expand Down
159 changes: 56 additions & 103 deletions src/openvpn/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ print_tun_backend_driver(enum tun_driver_type driver)
case DRIVER_AFUNIX:
return "unix";

case DRIVER_NULL:
return "null";

case DRIVER_UTUN:
return "utun";

Expand Down Expand Up @@ -463,18 +466,16 @@ is_dev_type(const char *dev, const char *dev_type, const char *match_type)
int
dev_type_enum(const char *dev, const char *dev_type)
{
if (is_dev_type(dev, dev_type, "tun"))
/* We pretend that the null device is also a tun device but it does not
* really matter as it will discard everything anyway */
if (is_dev_type(dev, dev_type, "tun") || is_dev_type(dev, dev_type, "null"))
{
return DEV_TYPE_TUN;
}
else if (is_dev_type(dev, dev_type, "tap"))
{
return DEV_TYPE_TAP;
}
else if (is_dev_type(dev, dev_type, "null"))
{
return DEV_TYPE_NULL;
}
else
{
return DEV_TYPE_UNDEF;
Expand All @@ -492,9 +493,6 @@ dev_type_string(const char *dev, const char *dev_type)
case DEV_TYPE_TAP:
return "tap";

case DEV_TYPE_NULL:
return "null";

default:
return "[unknown-dev-type]";
}
Expand Down Expand Up @@ -768,8 +766,7 @@ is_tun_p2p(const struct tuntap *tt)
bool tun_p2p = false;

if (tt->type == DEV_TYPE_TAP
|| (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET)
|| tt->type == DEV_TYPE_NULL)
|| (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
{
tun_p2p = false;
}
Expand All @@ -780,7 +777,6 @@ is_tun_p2p(const struct tuntap *tt)
else
{
msg(M_FATAL, "Error: problem with tun vs. tap setting"); /* JYFIXME -- needs to be caught earlier, in init_tun? */

}
return tun_p2p;
}
Expand Down Expand Up @@ -1748,7 +1744,7 @@ undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
void
undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
{
if (tt->type != DEV_TYPE_NULL)
if (tt->backend_driver != DRIVER_NULL)
{
if (tt->did_ifconfig_setup)
{
Expand Down Expand Up @@ -1779,13 +1775,6 @@ clear_tuntap(struct tuntap *tuntap)
#endif
}

static void
open_null(struct tuntap *tt)
{
tt->actual_name = string_alloc("null", NULL);
}


#if defined (TARGET_OPENBSD) || (defined(TARGET_DARWIN) && HAVE_NET_IF_UTUN_H)

/*
Expand Down Expand Up @@ -1901,78 +1890,72 @@ open_tun_generic(const char *dev, const char *dev_type, const char *dev_node,
char dynamic_name[256];
bool dynamic_opened = false;

if (tt->type == DEV_TYPE_NULL)
/*
* --dev-node specified, so open an explicit device node
*/
if (dev_node)
{
open_null(tt);
snprintf(tunname, sizeof(tunname), "%s", dev_node);
}
else
{
/*
* --dev-node specified, so open an explicit device node
* dynamic open is indicated by --dev specified without
* explicit unit number. Try opening /dev/[dev]n
* where n = [0, 255].
*/
if (dev_node)
{
snprintf(tunname, sizeof(tunname), "%s", dev_node);
}
else
{
/*
* dynamic open is indicated by --dev specified without
* explicit unit number. Try opening /dev/[dev]n
* where n = [0, 255].
*/

if (!tun_name_is_fixed(dev))
if (!tun_name_is_fixed(dev))
{
for (int i = 0; i < 256; ++i)
{
for (int i = 0; i < 256; ++i)
{
snprintf(tunname, sizeof(tunname),
"/dev/%s%d", dev, i);
snprintf(dynamic_name, sizeof(dynamic_name),
"%s%d", dev, i);
if ((tt->fd = open(tunname, O_RDWR)) > 0)
{
dynamic_opened = true;
break;
}
msg(D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
}
if (!dynamic_opened)
snprintf(tunname, sizeof(tunname),
"/dev/%s%d", dev, i);
snprintf(dynamic_name, sizeof(dynamic_name),
"%s%d", dev, i);
if ((tt->fd = open(tunname, O_RDWR)) > 0)
{
msg(M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
dynamic_opened = true;
break;
}
msg(D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
}
/*
* explicit unit number specified
*/
else
if (!dynamic_opened)
{
snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
msg(M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
}
}
/*
* explicit unit number specified
*/
else
{
snprintf(tunname, sizeof(tunname), "/dev/%s", dev);
}
}

if (!dynamic_opened)
if (!dynamic_opened)
{
/* has named device existed before? if so, don't destroy at end */
if (if_nametoindex( dev ) > 0)
{
/* has named device existed before? if so, don't destroy at end */
if (if_nametoindex( dev ) > 0)
{
msg(M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev );
tt->persistent_if = true;
}
msg(M_INFO, "TUN/TAP device %s exists previously, keep at program end", dev );
tt->persistent_if = true;
}

if ((tt->fd = open(tunname, O_RDWR)) < 0)
{
msg(M_ERR, "Cannot open TUN/TAP dev %s", tunname);
}
if ((tt->fd = open(tunname, O_RDWR)) < 0)
{
msg(M_ERR, "Cannot open TUN/TAP dev %s", tunname);
}
}

set_nonblock(tt->fd);
set_cloexec(tt->fd); /* don't pass fd to scripts */
msg(M_INFO, "TUN/TAP device %s opened", tunname);
set_nonblock(tt->fd);
set_cloexec(tt->fd); /* don't pass fd to scripts */
msg(M_INFO, "TUN/TAP device %s opened", tunname);

/* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
tt->actual_name = string_alloc(dynamic_opened ? dynamic_name : dev, NULL);

/* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
tt->actual_name = string_alloc(dynamic_opened ? dynamic_name : dev, NULL);
}
}
#endif /* !_WIN32 && !TARGET_LINUX && !TARGET_FREEBSD*/

Expand All @@ -1984,12 +1967,6 @@ open_tun_dco_generic(const char *dev, const char *dev_type,
char dynamic_name[256];
bool dynamic_opened = false;

if (tt->type == DEV_TYPE_NULL)
{
open_null(tt);
return;
}

/*
* unlike "open_tun_generic()", DCO on Linux and FreeBSD follows
* the device naming model of "non-DCO linux", that is:
Expand Down Expand Up @@ -2172,14 +2149,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
{
struct ifreq ifr;

/*
* We handle --dev null specially, we do not open /dev/null for this.
*/
if (tt->type == DEV_TYPE_NULL)
{
open_null(tt);
}
else if (tun_dco_enabled(tt))
if (tun_dco_enabled(tt))
{
open_tun_dco_generic(dev, dev_type, tt, ctx);
}
Expand Down Expand Up @@ -2404,12 +2374,6 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
*/
CLEAR(ifr);

if (tt->type == DEV_TYPE_NULL)
{
open_null(tt);
return;
}

if (tt->type == DEV_TYPE_TUN)
{
ip_node = "/dev/udp";
Expand Down Expand Up @@ -3488,12 +3452,6 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
char dynamic_name[20];
const char *p;

if (tt->type == DEV_TYPE_NULL)
{
open_null(tt);
return;
}

if (tt->type == DEV_TYPE_TUN)
{
msg(M_FATAL, "no support for 'tun' devices on AIX" );
Expand Down Expand Up @@ -6835,12 +6793,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun

msg( M_INFO, "open_tun");

if (tt->type == DEV_TYPE_NULL)
{
open_null(tt);
return;
}
else if (tt->type != DEV_TYPE_TAP && tt->type != DEV_TYPE_TUN)
if (tt->type != DEV_TYPE_TAP && tt->type != DEV_TYPE_TUN)
{
msg(M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
}
Expand Down
7 changes: 7 additions & 0 deletions src/openvpn/tun.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ enum tun_driver_type {
* This is always defined. We error out if a user tries to open this type
* of backend on unsupported platforms. */
DRIVER_AFUNIX,
DRIVER_NULL,
DRIVER_DCO,
/** macOS internal tun driver */
DRIVER_UTUN
Expand Down Expand Up @@ -784,4 +785,10 @@ is_tun_type_set(const struct tuntap *tt)
{
return tt && tt->type != DEV_TYPE_UNDEF;
}

static inline void
open_tun_null(struct tuntap *tt)
{
tt->actual_name = string_alloc("null", NULL);
}
#endif /* TUN_H */

0 comments on commit 8fe14fe

Please sign in to comment.