From 890d1a7821f67769c44c1d5d0269ab464b64a936 Mon Sep 17 00:00:00 2001 From: John Sharratt Date: Sun, 2 Jul 2017 10:27:47 +0200 Subject: [PATCH] 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) --- ndppd.conf-dist | 10 +++++++++- ndppd.conf.5 | 8 ++++++++ src/iface.cc | 23 ++++++++++++++++++++++- src/iface.h | 2 +- src/ndppd.cc | 8 +++++++- src/proxy.cc | 16 +++++++++++----- src/proxy.h | 8 ++++++-- 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/ndppd.conf-dist b/ndppd.conf-dist index 58d3bcb..d3986e2 100644 --- a/ndppd.conf-dist +++ b/ndppd.conf-dist @@ -24,11 +24,19 @@ proxy eth0 { timeout 500 # autowire - # 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 + # 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 # Controls how long a valid or invalid entry remains in the cache, in diff --git a/ndppd.conf.5 b/ndppd.conf.5 index 3e3e66d..21dd024 100644 --- a/ndppd.conf.5 +++ b/ndppd.conf.5 @@ -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 " +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 " Controls how long .B ndppd diff --git a/src/iface.cc b/src/iface.cc index ff88fde..6cd3f57 100644 --- a/src/iface.cc +++ b/src/iface.cc @@ -71,7 +71,7 @@ iface::~iface() _map_dirty = true; } -ptr iface::open_pfd(const std::string& name) +ptr iface::open_pfd(const std::string& name, bool promiscuous) { int fd = 0; @@ -118,6 +118,27 @@ ptr iface::open_pfd(const std::string& name) logger::error() << "Failed to bind to interface '" << name << "'"; return ptr(); } + + // 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(); + } + 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(); + } + } + } // Switch to non-blocking mode. diff --git a/src/iface.h b/src/iface.h index efdd1ac..20d0590 100644 --- a/src/iface.h +++ b/src/iface.h @@ -38,7 +38,7 @@ public: static ptr open_ifd(const std::string& name); - static ptr open_pfd(const std::string& name); + static ptr open_pfd(const std::string& name, bool promiscuous); static int poll_all(); diff --git a/src/ndppd.cc b/src/ndppd.cc index b176501..f42d4b6 100644 --- a/src/ndppd.cc +++ b/src/ndppd.cc @@ -148,8 +148,14 @@ static bool configure(ptr& cf) if (pr_cf->empty()) { return false; } + + bool promiscuous = false; + if (!(x_cf = pr_cf->find("promiscuous"))) + promiscuous = false; + else + promiscuous = *x_cf; - ptr pr = proxy::open(*pr_cf); + ptr pr = proxy::open(*pr_cf, promiscuous); if (!pr || pr.is_null() == true) { return false; } diff --git a/src/proxy.cc b/src/proxy.cc index ad709a6..91a7162 100644 --- a/src/proxy.cc +++ b/src/proxy.cc @@ -30,15 +30,16 @@ NDPPD_NS_BEGIN std::list > 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::create(const ptr& ifa) +ptr proxy::create(const ptr& ifa, bool promiscuous) { ptr pr(new proxy()); pr->_ptr = pr; pr->_ifa = ifa; + pr->_promiscuous = promiscuous; _list.push_back(pr); @@ -49,15 +50,15 @@ ptr proxy::create(const ptr& ifa) return pr; } -ptr proxy::open(const std::string& ifname) +ptr proxy::open(const std::string& ifname, bool promiscuous) { - ptr ifa = iface::open_pfd(ifname); + ptr ifa = iface::open_pfd(ifname, promiscuous); if (!ifa) { return ptr(); } - return create(ifa); + return create(ifa, promiscuous); } void proxy::handle_solicit(const address& saddr, const address& daddr, @@ -170,6 +171,11 @@ const ptr& proxy::ifa() const return _ifa; } +bool proxy::promiscuous() const +{ + return _promiscuous; +} + bool proxy::router() const { return _router; diff --git a/src/proxy.h b/src/proxy.h index 829321c..c19ea60 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -30,9 +30,9 @@ class rule; class proxy { public: - static ptr create(const ptr& ifa); + static ptr create(const ptr& ifa, bool promiscuous); - static ptr open(const std::string& ifn); + static ptr open(const std::string& ifn, bool promiscuous); void handle_solicit(const address& saddr, const address& daddr, const address& taddr); @@ -44,6 +44,8 @@ public: ptr add_rule(const address& addr, bool aut = false); const ptr& ifa() const; + + bool promiscuous() const; bool router() const; @@ -75,6 +77,8 @@ private: std::list > _rules; std::list > _sessions; + + bool _promiscuous; bool _router;