Add socket option BINDTODEVICE

Linux now supports Virtual Routing and Forwarding (VRF) as per:

https://www.kernel.org/doc/Documentation/networking/vrf.txt

In order for an application to bind or connect to a socket with an
address in a VRF, they need to first bind the socket to the VRF device:

    setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1);

Note "dev" is the VRF device, eg. VRF "blue", rather than an interface
enslaved to the VRF.

Add a new socket option, ZMQ_BINDTODEVICE, to bind a socket to a device.
In general, if a socket is bound to a device, eg. an interface, only
packets received from that particular device are processed by the socket.

If device is a VRF device, then subsequent binds/connects to that socket
use addresses in the VRF routing table.
This commit is contained in:
Brian Russell
2017-07-28 14:35:09 +01:00
parent 4a37ce9aeb
commit b963542e8f
17 changed files with 189 additions and 0 deletions

View File

@@ -34,6 +34,16 @@
#include "err.hpp"
#include "macros.hpp"
#ifndef ZMQ_HAVE_WINDOWS
#include <net/if.h>
#endif
#if defined IFNAMSIZ
#define BINDDEVSIZ IFNAMSIZ
#else
#define BINDDEVSIZ 16
#endif
zmq::options_t::options_t () :
sndhwm (1000),
rcvhwm (1000),
@@ -605,6 +615,19 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
}
break;
case ZMQ_BINDTODEVICE:
if (optval_ == NULL && optvallen_ == 0) {
bound_device.clear ();
return 0;
}
else
if (optval_ != NULL && optvallen_ > 0 && optvallen_ <= BINDDEVSIZ) {
bound_device =
std::string ((const char *) optval_, optvallen_);
return 0;
}
break;
default:
#if defined (ZMQ_ACT_MILITANT)
// There are valid scenarios for probing with unknown socket option
@@ -1021,6 +1044,14 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
}
break;
case ZMQ_BINDTODEVICE:
if (*optvallen_ >= bound_device.size () + 1) {
memcpy (optval_, bound_device.c_str (), bound_device.size () + 1);
*optvallen_ = bound_device.size () + 1;
return 0;
}
break;
default:
#if defined (ZMQ_ACT_MILITANT)
malformed = false;