Skip to content

Commit eeb866a

Browse files
committed
Change '--multihome' behaviour regarding egress interface selection.
Traditional OpenVPN ``--multihome`` behaviour is to send packets out the same interface that they were received on (copy ipi_ifindex from ingress to egress packet info). For some scenarios this makes sense, for other scenarios it is breaking connectivity when there are no routes pointing out the ingress interface (intentionally asymmetric traffic). For 2.7.0, change the default(!) to always send out packets with ipi_ifindex = 0, to follow normal system interface selection rules. Add a flag ``--multihome same-interface`` to restore the pre-2.7 behavior of copying ipi_ifindex from ingress to egress packets. There are use cases for this, and we want to give users a chance to read the release notes and adjust their setups to "not break after upgrading to 2.7.0". Github: #855 Github: #554 v2: fix whitespace v3: turn logic around - new default is "egress ifindex 0" now v4: typo fixed in commit message v5: fix invalid rst in Changes.rst Change-Id: Id429241e1b17a8ff51d9019efc357c910f3bde4c Signed-off-by: Gert Doering <[email protected]> Acked-by: Frank Lichtenheld <[email protected]> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1383 Message-Id: <[email protected]> URL: https://www.mail-archive.com/[email protected]/msg34709.html Signed-off-by: Gert Doering <[email protected]>
1 parent dd1524c commit eeb866a

File tree

5 files changed

+33
-10
lines changed

5 files changed

+33
-10
lines changed

Changes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@ User-visible Changes
326326
Win-DCO as well), add printing of the hwid to all adapter outputs, and
327327
change the default adapter type created to `ovpn-dco`.
328328

329+
- the default for ``multihome`` egress interface handling has changed.
330+
2.7.0 will default to ipi_ifindex=0, that is, leave the decision to the
331+
routing/policy setup of the operating system. The pre-2.7 behaviour
332+
(force egress = ingress interface) can be achieved with the new
333+
``--multihome same-interface`` sub-option.
334+
329335
Deprecated features
330336
-------------------
331337
``--opt-verify`` feature removed

doc/man-sections/server-options.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ fast hardware. SSL/TLS authentication must be used in this mode.
342342
by ``--ifconfig-ipv6``, OpenVPN will install a /128 host route for the
343343
``ipv6addr`` IP address.
344344

345-
--multihome
345+
--multihome [same-interface]
346346
Configure a multi-homed UDP server. This option needs to be used when a
347347
server has more than one IP address (e.g. multiple interfaces, or
348348
secondary IP addresses), and is not using ``--local`` to force binding
@@ -353,12 +353,18 @@ fast hardware. SSL/TLS authentication must be used in this mode.
353353
default.
354354

355355
*Notes:*
356-
- This option is only relevant for UDP servers.
357-
- If you do an IPv6+IPv4 dual-stack bind on a Linux machine with
358-
multiple IPv4 address, connections to IPv4 addresses will not
359-
work right on kernels before 3.15, due to missing kernel
360-
support for the IPv4-mapped case (some distributions have
361-
ported this to earlier kernel versions, though).
356+
- This option is only relevant for UDP servers.
357+
- Starting with 2.7.0, OpenVPN will ignore the incoming interface of
358+
the packet, and leave selection of the outgoing interface to the
359+
normal routing/policy mechanisms of the OS ("set ipi_ifindex=0").
360+
- if the ``same-interface`` flag is added, OpenVPN will copy the
361+
incoming interface index to the outgoing interface index,
362+
trying to send the packet out over the same interface where it came
363+
in on (= restoring earlier OpenVPN behaviour). This might not work
364+
if there are no usable routes on that interface.
365+
- the \*BSD systems use a different API for IPv4 that does not provide
366+
the interface index anyway (IP_RECVDSTADDR), so there the difference
367+
applies only to IPv6.
362368

363369
--iroute args
364370
Generate an internal route to a specific client. The ``netmask``

src/openvpn/options.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6335,10 +6335,18 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file,
63356335
options->mlock = true;
63366336
}
63376337
#if ENABLE_IP_PKTINFO
6338-
else if (streq(p[0], "multihome") && !p[1])
6338+
else if (streq(p[0], "multihome") && !p[2])
63396339
{
63406340
VERIFY_PERMISSION(OPT_P_GENERAL);
63416341
options->sockflags |= SF_USE_IP_PKTINFO;
6342+
if (p[1] && streq(p[1], "same-interface"))
6343+
{
6344+
options->sockflags |= SF_PKTINFO_COPY_IIF;
6345+
}
6346+
else if (p[1])
6347+
{
6348+
msg(msglevel, "Unknown parameter to --multihome: %s", p[1]);
6349+
}
63426350
}
63436351
#endif
63446352
else if (streq(p[0], "verb") && p[1] && !p[2])

src/openvpn/socket.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,7 +2393,8 @@ link_socket_read_udp_posix_recvmsg(struct link_socket *sock, struct buffer *buf,
23932393
{
23942394
#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
23952395
struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(cmsg);
2396-
from->pi.in4.ipi_ifindex = pkti->ipi_ifindex;
2396+
from->pi.in4.ipi_ifindex =
2397+
(sock->sockflags & SF_PKTINFO_COPY_IIF) ? pkti->ipi_ifindex : 0;
23972398
from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst;
23982399
#elif defined(IP_RECVDSTADDR)
23992400
from->pi.in4 = *(struct in_addr *)CMSG_DATA(cmsg);
@@ -2406,7 +2407,8 @@ link_socket_read_udp_posix_recvmsg(struct link_socket *sock, struct buffer *buf,
24062407
&& cmsg->cmsg_len >= CMSG_LEN(sizeof(struct in6_pktinfo)))
24072408
{
24082409
struct in6_pktinfo *pkti6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
2409-
from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex;
2410+
from->pi.in6.ipi6_ifindex =
2411+
(sock->sockflags & SF_PKTINFO_COPY_IIF) ? pkti6->ipi6_ifindex : 0;
24102412
from->pi.in6.ipi6_addr = pkti6->ipi6_addr;
24112413
}
24122414
else if (cmsg != NULL)

src/openvpn/socket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ struct link_socket
195195
#define SF_GETADDRINFO_DGRAM (1 << 4)
196196
#define SF_DCO_WIN (1 << 5)
197197
#define SF_PREPEND_SA (1 << 6)
198+
#define SF_PKTINFO_COPY_IIF (1 << 7)
198199
unsigned int sockflags;
199200
int mark;
200201
const char *bind_dev;

0 commit comments

Comments
 (0)