New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --bind-dev option. #65

Open
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
9 participants
@BarbarossaTM
Copy link

BarbarossaTM commented Oct 21, 2016

This options allows the user to specify a network device the OpenVPN process
should use when making a connection or binding to an address. This translates
in setting the SO_BINDTODEVICE option to the corresponding socket (on Linux).

When for example using VRFs on Linux [0] this allows making connections using
the non-default VRF and having the tun/tap interface in the default VRF.

It seems FreeBSD does not support the SO_BINDTODEVICE socket option, but has
a similar one called IP_SENDIF. As I don't have any BSD running, this part is
untested.

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@rfc2324.org

@BarbarossaTM

This comment has been minimized.

Copy link

BarbarossaTM commented Oct 21, 2016

This is an update to #64

@spagu

This comment has been minimized.

Copy link

spagu commented Oct 23, 2016

can this patch can be connected with this issue? https://forums.freebsd.org/threads/58019/

@cron2

This comment has been minimized.

Copy link
Contributor

cron2 commented Oct 25, 2016

Hi,

On Sun, Oct 23, 2016 at 07:00:56AM -0700, spagu wrote:

can this patch can be connected with this issue? https://forums.freebsd.org/threads/58019/

Totally unrelated.

gert

USENET is not the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany gert@greenie.muc.de
fax: +49-89-35655025 gert@net.informatik.tu-muenchen.de

@BarbarossaTM BarbarossaTM force-pushed the BarbarossaTM:bind-dev branch from 1baa7e6 to 82322b6 Sep 20, 2017

@BarbarossaTM

This comment has been minimized.

Copy link

BarbarossaTM commented Sep 20, 2017

Hi @cron2

I rebased the PR on v2.4.3, reordered some function paramters as requested on the mailing list, and remove the untested code for FreeBSD.

Please review and merge :-)

Best
Max

Add --bind-dev option.
  This options allows the user to specify a network device the OpenVPN process
  should use when making a connection or binding to an address. This translates
  in setting the SO_BINDTODEVICE option to the corresponding socket (on Linux).

  When for example using VRFs on Linux [0] this allows making connections using
  the 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@rfc2324.org>

@BarbarossaTM BarbarossaTM force-pushed the BarbarossaTM:bind-dev branch from 82322b6 to 71bf2f7 Sep 21, 2017

@BarbarossaTM

This comment has been minimized.

Copy link

BarbarossaTM commented Sep 21, 2017

Hi again,

Just got feedback, that --bind-dev should only be shown on Linux as it's only evaluated on Linux, so I move the help text next to --mark which is already only shown on Linux systems and does something similar.

Please review and merge :-)

Best
Max

@cron2

This comment has been minimized.

Copy link
Contributor

cron2 commented Sep 21, 2017

@BarbarossaTM

This comment has been minimized.

Copy link

BarbarossaTM commented Sep 21, 2017

I thought you have BSD code as well?

I had some in the earlier pull request which I found by googing. As I don' have any FreeBSD and zero experience with it, I can't test it. Any Arne suggested, that the code I googled doesn't work / the options don't exist. As there was no other feedback on *BSD, I dropped it.

Best
Max

@cron2

This comment has been minimized.

Copy link
Contributor

cron2 commented Sep 21, 2017

@BarbarossaTM

This comment has been minimized.

Copy link

BarbarossaTM commented Sep 21, 2017

Well, my initial requirement was "keep the things open so platform specific stuff can be added later if we figure out how to do it on platform ", and as such, moving inside #ifdef TARGET_LINUX is not a good approach.

To the best of my knowledge the code can easily be extended when someone figures out how to do so on different platforms.

The rationale behind the use of the current ifdef is, that the option now only is shown on Linux, as now it's only supported on Linux. But that ifdef can easily be changed later.

What I initially referred to was https://lists.freebsd.org/pipermail/freebsd-net/2012-April/032064.html which talks about IP_SENDIF, which according to https://wiki.freebsd.org/Networking seems to still exist. But as I said I have no FreeBSD (experience) and would rely on soeone who does, here.

As the initial code shows it should be rather easy to add a branch for FreeBSD here.

Max

@lukastribus

This comment has been minimized.

Copy link

lukastribus commented Nov 8, 2017

td;lr SO_BINDTODEVICE is not equivalent to "VRF selection", let's not imply that one way or the other; also VRF support and its APIs may never be portable.

SO_BINDTODEVICE is a linux-specific socket option supported since decades.
The VRF concept in linux was introduced in linux 4.3 - barely 2 years ago.

I want to emphasize that the SO_BINDTODEVICE option's primary use-case is NOT to assign sockets to VRF's. That works in 4.3 now too, but the primary use-case is to force an application to a specific interface (for DHCP for example).

So when BSD folks talk about implementing the SO_BINDTODEVICE option, we cannot assume they also mean VRF selection, just because that's the shortcut used in Linux. In fact, I don't even know if FreeBSD supports VRF's. It supports multiple FIBs and jails, just like Linux supported multiple FIBs and network namespaces long before VRF support. But whether FreeBSD supports VRF's just like Linux, I do not know.

What we know for sure is how to use VRF's in Linux, but another OS may implement a completely different API (based on a VRF name or id, instead of a interface name).

OpenBSD's ntpd.conf for example looks like this: listen on address [rtable table-id] [1].

How are we going to abstract that in openvpn? We can't, in my opinion.

So my suggestion is to not make this looks like a portable VRF selection feature. Let's call it what it is: an option to bind to a specific interface (currently supported on Linux).

If required for a commit, we can move all the logic out of the #ifdef TARGET_LINUX, and guard only the actual socket call with #ifdef TARGET_LINUX or SO_BINDTODEVICE, but we have to at least mention the fact that this currently only works in Linux (in the help text).

lukas

[1] https://man.openbsd.org/ntpd.conf

@bao7uo

This comment has been minimized.

Copy link

bao7uo commented Jan 29, 2018

Really hope this feature can be merged :)

@dfawcus

This comment has been minimized.

Copy link

dfawcus commented Feb 1, 2018

Yes it would be useful addition.

@dsommers

This comment has been minimized.

Copy link
Member

dsommers commented Apr 11, 2018

@bao7uo, @dfawcus Which feature do you expect SO_BINDTODEVICE or VRF binding? As I understand the quite well written comment from @lukastribus, using SO_BINDTODEVICE for VRF binding is the wrong approach - it works now, but there is no guarantee for the future. If the VRF binding is the expected outcome, then we need a different patch.

@dfawcus

This comment has been minimized.

Copy link

dfawcus commented Apr 11, 2018

@craig

This comment has been minimized.

Copy link

craig commented Jan 11, 2019

Please merge, we can add this feature for BSD when it becomes available there.

@lukastribus

This comment has been minimized.

Copy link

lukastribus commented Jan 11, 2019

@bao7uo, @dfawcus Which feature do you expect SO_BINDTODEVICE or VRF binding? As I understand the quite well written comment from @lukastribus, using SO_BINDTODEVICE for VRF binding is the wrong approach - it works now, but there is no guarantee for the future.

I'm suggesting: just implement SO_BINDTODEVICE in openvpn, by advertising it exactly what the API is for: binding to a device (not binding to a VRF).

It's perfectly fine for people to then use it under Linux to select it for VRFs. It's not like the Linux behavior is going to change. However it is not and may never be portable across different OS.

@schwabe

This comment has been minimized.

Copy link
Contributor

schwabe commented Jan 11, 2019

So this also went up on the mailing list. The strlen+1 is off by one that needs to be fixed. And I am unsure how to test this feature or it does not work. Binding openvpn to eth0 and not having redirect-gateway enabled should make a working VPN connection but it doesn't.

@dfawcus

This comment has been minimized.

Copy link

dfawcus commented Jan 18, 2019

As to testing, on Linux one can set up an ECMP route to a target such that it will point to two interfaces.

Packets sent to that destination will experience some behaviour (possibly round-robin?)

Using a socket which has been bound to the specific interface will then ensure that packets to that destination from the socket are sent out of the desired interface, rather than experiencing the default kernel behaviour.

$ ip -d r sh
unicast 8.8.8.8 proto 11 scope global
        nexthop via 10.1.2.2 dev eth0 weight 1
        nexthop via 10.2.0.2 dev eth1 weight 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment