Added a promiscuous mode that allows the proxy interface to also respond to queries send from the gateway (for instance when it needs to route to a WAN address thats local)

This commit is contained in:
John Sharratt 2017-07-02 10:27:47 +02:00
parent 4316aa58dd
commit 890d1a7821
7 changed files with 64 additions and 11 deletions

View File

@ -24,12 +24,20 @@ proxy eth0 {
timeout 500
# autowire <yes|no|true|false>
# Controls whether whether ndppd will automatically create host entries
# Controls whether ndppd will automatically create host entries
# in the routing tables when it receives Neighbor Advertisements on a
# listening interface. The the default value is no.
autowire no
# promiscuous <yes|no|true|false>
# Controls whether ndppd will put the proxy listening interface into promiscuous
# mode and hence will react to inbound and outbound NDP commands. This is
# required for machines behind the gateway to talk to each other in more
# complex topology scenarios. The the default value is no.
promiscuous no
# ttl <integer>
# Controls how long a valid or invalid entry remains in the cache, in
# milliseconds. Default value is '30000' (30 seconds).

View File

@ -54,6 +54,14 @@ Controls whether
will automatically create host entries in the routing tables when
.B ndppd receives Neighbor Advertisements on a listening interface.
The default value is no.
.IP "promiscuous <yes|no>"
Controls whether
.B ndppd
will put the proxy listening interface into promiscuous mode and
hence will react to inbound and outbound NDP commands. This is
required for machines behind the gateway to talk to each other in
more complex topology scenarios.
The the default value is no.
.IP "timeout <value>"
Controls how long
.B ndppd

View File

@ -71,7 +71,7 @@ iface::~iface()
_map_dirty = true;
}
ptr<iface> iface::open_pfd(const std::string& name)
ptr<iface> iface::open_pfd(const std::string& name, bool promiscuous)
{
int fd = 0;
@ -119,6 +119,27 @@ ptr<iface> iface::open_pfd(const std::string& name)
return ptr<iface>();
}
// Switch on promiscuous mode (if instructed)
if (promiscuous == true)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ);
if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
close(fd);
logger::error() << "Failed invoking ioctl(SIOCGIFFLAGS) while setting promiscuous mode on interface '" << name << "'";
return ptr<iface>();
}
if (!(ifr.ifr_flags & IFF_PROMISC)) {
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
close(fd);
logger::error() << "Failed invoking ioctl(SIOCSIFFLAGS) while setting promiscuous mode on interface '" << name << "'";
return ptr<iface>();
}
}
}
// Switch to non-blocking mode.
int on = 1;

View File

@ -38,7 +38,7 @@ public:
static ptr<iface> open_ifd(const std::string& name);
static ptr<iface> open_pfd(const std::string& name);
static ptr<iface> open_pfd(const std::string& name, bool promiscuous);
static int poll_all();

View File

@ -149,7 +149,13 @@ static bool configure(ptr<conf>& cf)
return false;
}
ptr<proxy> pr = proxy::open(*pr_cf);
bool promiscuous = false;
if (!(x_cf = pr_cf->find("promiscuous")))
promiscuous = false;
else
promiscuous = *x_cf;
ptr<proxy> pr = proxy::open(*pr_cf, promiscuous);
if (!pr || pr.is_null() == true) {
return false;
}

View File

@ -30,15 +30,16 @@ NDPPD_NS_BEGIN
std::list<ptr<proxy> > proxy::_list;
proxy::proxy() :
_router(true), _ttl(30000), _deadtime(3000), _timeout(500), _autowire(false)
_router(true), _ttl(30000), _deadtime(3000), _timeout(500), _autowire(false), _promiscuous(false)
{
}
ptr<proxy> proxy::create(const ptr<iface>& ifa)
ptr<proxy> proxy::create(const ptr<iface>& ifa, bool promiscuous)
{
ptr<proxy> pr(new proxy());
pr->_ptr = pr;
pr->_ifa = ifa;
pr->_promiscuous = promiscuous;
_list.push_back(pr);
@ -49,15 +50,15 @@ ptr<proxy> proxy::create(const ptr<iface>& ifa)
return pr;
}
ptr<proxy> proxy::open(const std::string& ifname)
ptr<proxy> proxy::open(const std::string& ifname, bool promiscuous)
{
ptr<iface> ifa = iface::open_pfd(ifname);
ptr<iface> ifa = iface::open_pfd(ifname, promiscuous);
if (!ifa) {
return ptr<proxy>();
}
return create(ifa);
return create(ifa, promiscuous);
}
void proxy::handle_solicit(const address& saddr, const address& daddr,
@ -170,6 +171,11 @@ const ptr<iface>& proxy::ifa() const
return _ifa;
}
bool proxy::promiscuous() const
{
return _promiscuous;
}
bool proxy::router() const
{
return _router;

View File

@ -30,9 +30,9 @@ class rule;
class proxy {
public:
static ptr<proxy> create(const ptr<iface>& ifa);
static ptr<proxy> create(const ptr<iface>& ifa, bool promiscuous);
static ptr<proxy> open(const std::string& ifn);
static ptr<proxy> open(const std::string& ifn, bool promiscuous);
void handle_solicit(const address& saddr, const address& daddr,
const address& taddr);
@ -45,6 +45,8 @@ public:
const ptr<iface>& ifa() const;
bool promiscuous() const;
bool router() const;
void router(bool val);
@ -76,6 +78,8 @@ private:
std::list<ptr<session> > _sessions;
bool _promiscuous;
bool _router;
bool _autowire;