This options allows the user to specify a network interface or VRF
device the OpenVPN process should use when making a connection or
binding to an address.
This is done by setting the SO_BINDTODEVICE option to the corresponding
socket (on Linux). SO_BINDTODEVICE forces all packets sent on that socket
to go out via the specified interface, and only packets coming in on
that interface are received by OpenVPN.
When used in a VRF context on Linux [0], you can also specify the name
of the VRF ("--bind-dev external_vrf"), which will put the OpenVPN
"network side" into this VRF. This allows making connections using a
non-default VRF and having the tun/tap interface in the default VRF.
Thanks to David Ahern (Cumulus Networks) for insights on this.
[0] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/vrf.txt
Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <
1593427748-29801-2-git-send-email-max@rfc2324.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20156.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
c->options.rcvbuf,
c->options.sndbuf,
c->options.mark,
+ c->options.bind_dev,
&c->c2.server_poll_interval,
sockflags);
}
#if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK
"--mark value : Mark encrypted packets being sent with value. The mark value\n"
" can be matched in policy routing and packetfilter rules.\n"
+ "--bind-dev dev : Bind to the given device when making connection to a peer or\n"
+ " listening for connections. This allows sending encrypted packets\n"
+ " via a VRF present on the system.\n"
#endif
"--txqueuelen n : Set the tun/tap TX queue length to n (Linux only).\n"
#ifdef ENABLE_MEMSTATS
}
}
}
+#ifdef TARGET_LINUX
+ else if (streq (p[0], "bind-dev") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_SOCKFLAGS);
+ options->bind_dev = p[1];
+ }
+#endif
else if (streq(p[0], "txqueuelen") && p[1] && !p[2])
{
VERIFY_PERMISSION(OPT_P_GENERAL);
/* mark value */
int mark;
+ char *bind_dev;
/* socket flags */
unsigned int sockflags;
/* set socket to --mark packets with given value */
socket_set_mark(sock->sd, sock->mark);
+#if defined(TARGET_LINUX)
+ if (sock->bind_dev)
+ {
+ msg (M_INFO, "Using bind-dev %s", sock->bind_dev);
+ if (setsockopt (sock->sd, SOL_SOCKET, SO_BINDTODEVICE, sock->bind_dev, strlen (sock->bind_dev) + 1) != 0)
+ {
+ msg(M_WARN|M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);
+ }
+
+ }
+#endif
+
bind_local(sock, addr->ai_family);
}
int rcvbuf,
int sndbuf,
int mark,
+ const char *bind_dev,
struct event_timeout *server_poll_timeout,
unsigned int sockflags)
{
sock->sockflags = sockflags;
sock->mark = mark;
+ sock->bind_dev = bind_dev;
sock->info.proto = proto;
sock->info.af = af;
#define SF_GETADDRINFO_DGRAM (1<<4)
unsigned int sockflags;
int mark;
+ const char *bind_dev;
/* for stream sockets */
struct stream_buf stream_buf;
int rcvbuf,
int sndbuf,
int mark,
+ const char *bind_dev,
struct event_timeout *server_poll_timeout,
unsigned int sockflags);
/* Reenable uncrustify *INDENT-ON* */