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,11 +24,19 @@ proxy eth0 {
timeout 500 timeout 500
# autowire <yes|no|true|false> # 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 # in the routing tables when it receives Neighbor Advertisements on a
# listening interface. The the default value is no. # listening interface. The the default value is no.
autowire 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> # ttl <integer>
# Controls how long a valid or invalid entry remains in the cache, in # Controls how long a valid or invalid entry remains in the cache, in

View File

@ -54,6 +54,14 @@ Controls whether
will automatically create host entries in the routing tables when will automatically create host entries in the routing tables when
.B ndppd receives Neighbor Advertisements on a listening interface. .B ndppd receives Neighbor Advertisements on a listening interface.
The default value is no. 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>" .IP "timeout <value>"
Controls how long Controls how long
.B ndppd .B ndppd

View File

@ -71,7 +71,7 @@ iface::~iface()
_map_dirty = true; _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; int fd = 0;
@ -118,6 +118,27 @@ ptr<iface> iface::open_pfd(const std::string& name)
logger::error() << "Failed to bind to interface '" << name << "'"; logger::error() << "Failed to bind to interface '" << name << "'";
return ptr<iface>(); 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. // Switch to non-blocking mode.

View File

@ -38,7 +38,7 @@ public:
static ptr<iface> open_ifd(const std::string& name); 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(); static int poll_all();

View File

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

View File

@ -30,15 +30,16 @@ NDPPD_NS_BEGIN
std::list<ptr<proxy> > proxy::_list; std::list<ptr<proxy> > proxy::_list;
proxy::proxy() : 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()); ptr<proxy> pr(new proxy());
pr->_ptr = pr; pr->_ptr = pr;
pr->_ifa = ifa; pr->_ifa = ifa;
pr->_promiscuous = promiscuous;
_list.push_back(pr); _list.push_back(pr);
@ -49,15 +50,15 @@ ptr<proxy> proxy::create(const ptr<iface>& ifa)
return pr; 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) { if (!ifa) {
return ptr<proxy>(); return ptr<proxy>();
} }
return create(ifa); return create(ifa, promiscuous);
} }
void proxy::handle_solicit(const address& saddr, const address& daddr, void proxy::handle_solicit(const address& saddr, const address& daddr,
@ -170,6 +171,11 @@ const ptr<iface>& proxy::ifa() const
return _ifa; return _ifa;
} }
bool proxy::promiscuous() const
{
return _promiscuous;
}
bool proxy::router() const bool proxy::router() const
{ {
return _router; return _router;

View File

@ -30,9 +30,9 @@ class rule;
class proxy { class proxy {
public: 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, void handle_solicit(const address& saddr, const address& daddr,
const address& taddr); const address& taddr);
@ -44,6 +44,8 @@ public:
ptr<rule> add_rule(const address& addr, bool aut = false); ptr<rule> add_rule(const address& addr, bool aut = false);
const ptr<iface>& ifa() const; const ptr<iface>& ifa() const;
bool promiscuous() const;
bool router() const; bool router() const;
@ -75,6 +77,8 @@ private:
std::list<ptr<rule> > _rules; std::list<ptr<rule> > _rules;
std::list<ptr<session> > _sessions; std::list<ptr<session> > _sessions;
bool _promiscuous;
bool _router; bool _router;