Now creating session on receiving NDP adverts even if no one has specifically asked for one yet thus ensuring the routes are created and that the latecy on proxy solicitation is kept much lower
This commit is contained in:
parent
f6ef3fe494
commit
89130bf099
20
src/iface.cc
20
src/iface.cc
@ -599,6 +599,7 @@ int iface::poll_all()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
for (std::list<weak_ptr<session> >::iterator s_it = ifa->_sessions.begin();
|
for (std::list<weak_ptr<session> >::iterator s_it = ifa->_sessions.begin();
|
||||||
s_it != ifa->_sessions.end(); s_it++) {
|
s_it != ifa->_sessions.end(); s_it++) {
|
||||||
assert(!s_it->is_null());
|
assert(!s_it->is_null());
|
||||||
@ -607,9 +608,18 @@ int iface::poll_all()
|
|||||||
|
|
||||||
if ((sess->taddr() == taddr) && (sess->status() == session::WAITING || sess->status() == session::RENEWING)) {
|
if ((sess->taddr() == taddr) && (sess->status() == session::WAITING || sess->status() == session::RENEWING)) {
|
||||||
sess->handle_advert(ifa);
|
sess->handle_advert(ifa);
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (found == false) {
|
||||||
|
if (ifa->owner()) {
|
||||||
|
ifa->owner()->handle_advert(saddr, taddr, ifa);
|
||||||
|
} else {
|
||||||
|
logger::debug() << "iface::poll_all - ignoring advert on proxy iface=" << ifa->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,4 +719,14 @@ const ptr<proxy>& iface::pr() const
|
|||||||
return _pr;
|
return _pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iface::owner(const ptr<proxy>& pr)
|
||||||
|
{
|
||||||
|
_owner = pr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ptr<proxy>& iface::owner() const
|
||||||
|
{
|
||||||
|
return _owner;
|
||||||
|
}
|
||||||
|
|
||||||
NDPPD_NS_END
|
NDPPD_NS_END
|
||||||
|
@ -67,8 +67,12 @@ public:
|
|||||||
void remove_session(const ptr<session>& se);
|
void remove_session(const ptr<session>& se);
|
||||||
|
|
||||||
void pr(const ptr<proxy>& pr);
|
void pr(const ptr<proxy>& pr);
|
||||||
|
|
||||||
const ptr<proxy>& pr() const;
|
const ptr<proxy>& pr() const;
|
||||||
|
|
||||||
|
void owner(const ptr<proxy>& pr);
|
||||||
|
|
||||||
|
const ptr<proxy>& owner() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::map<std::string, weak_ptr<iface> > _map;
|
static std::map<std::string, weak_ptr<iface> > _map;
|
||||||
@ -108,6 +112,8 @@ private:
|
|||||||
std::list<weak_ptr<session> > _sessions;
|
std::list<weak_ptr<session> > _sessions;
|
||||||
|
|
||||||
weak_ptr<proxy> _pr;
|
weak_ptr<proxy> _pr;
|
||||||
|
|
||||||
|
weak_ptr<proxy> _owner;
|
||||||
|
|
||||||
// The link-layer address of this interface.
|
// The link-layer address of this interface.
|
||||||
struct ether_addr hwaddr;
|
struct ether_addr hwaddr;
|
||||||
|
@ -204,6 +204,7 @@ static bool configure(ptr<conf>& cf)
|
|||||||
if (!ifa || ifa.is_null() == true) {
|
if (!ifa || ifa.is_null() == true) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
ifa->owner(pr);
|
||||||
|
|
||||||
pr->add_rule(addr, ifa);
|
pr->add_rule(addr, ifa);
|
||||||
} else if (ru_cf->find("auto")) {
|
} else if (ru_cf->find("auto")) {
|
||||||
|
86
src/proxy.cc
86
src/proxy.cc
@ -26,7 +26,9 @@
|
|||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
NDPPD_NS_BEGIN
|
NDPPD_NS_BEGIN
|
||||||
|
|
||||||
|
static address all_nodes = address("ff02::1");
|
||||||
|
|
||||||
std::list<ptr<proxy> > proxy::_list;
|
std::list<ptr<proxy> > proxy::_list;
|
||||||
|
|
||||||
proxy::proxy() :
|
proxy::proxy() :
|
||||||
@ -61,14 +63,8 @@ ptr<proxy> proxy::open(const std::string& ifname, bool promiscuous)
|
|||||||
return create(ifa, promiscuous);
|
return create(ifa, promiscuous);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proxy::handle_solicit(const address& saddr, const address& daddr,
|
ptr<session> proxy::find_or_create_session(const address& saddr, const address& daddr, const address& taddr, const ptr<iface>& receiver)
|
||||||
const address& taddr)
|
|
||||||
{
|
{
|
||||||
logger::debug()
|
|
||||||
<< "proxy::handle_solicit() ifa=" << ((_ifa) ? _ifa->name() : "null")
|
|
||||||
<< ", saddr=" << saddr.to_string()
|
|
||||||
<< ", taddr=" << taddr.to_string();
|
|
||||||
|
|
||||||
// Let's check this proxy's list of sessions to see if we can
|
// Let's check this proxy's list of sessions to see if we can
|
||||||
// find one with the same target address.
|
// find one with the same target address.
|
||||||
|
|
||||||
@ -76,43 +72,32 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
|
|||||||
sit != _sessions.end(); sit++) {
|
sit != _sessions.end(); sit++) {
|
||||||
|
|
||||||
if ((*sit)->taddr() == taddr)
|
if ((*sit)->taddr() == taddr)
|
||||||
{
|
return (*sit);
|
||||||
(*sit)->touch();
|
|
||||||
|
|
||||||
switch ((*sit)->status()) {
|
|
||||||
case session::WAITING:
|
|
||||||
case session::INVALID:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case session::VALID:
|
|
||||||
case session::RENEWING:
|
|
||||||
(*sit)->send_advert();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since we couldn't find a session that matched, we'll try to find
|
// Since we couldn't find a session that matched, we'll try to find
|
||||||
// a matching rule instead, and then set up a new session.
|
// a matching rule instead, and then set up a new session.
|
||||||
|
|
||||||
ptr<session> se;
|
ptr<session> se;
|
||||||
|
|
||||||
for (std::list<ptr<rule> >::iterator it = _rules.begin();
|
for (std::list<ptr<rule> >::iterator it = _rules.begin();
|
||||||
it != _rules.end(); it++) {
|
it != _rules.end(); it++) {
|
||||||
ptr<rule> ru = *it;
|
ptr<rule> ru = *it;
|
||||||
|
|
||||||
logger::debug() << "checking " << ru->addr() << " against " << taddr;
|
logger::debug() << "checking " << ru->addr() << " against " << taddr;
|
||||||
|
|
||||||
if (!daddr.is_multicast() && ru->addr() != daddr) {
|
if (!daddr.is_multicast() && ru->addr() != daddr && daddr != taddr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (receiver && ru->ifa() && receiver->name() != ru->ifa()->name())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (ru->addr() == taddr) {
|
if (ru->addr() == taddr) {
|
||||||
if (!se) {
|
if (!se) {
|
||||||
se = session::create(_ptr, saddr, daddr, taddr, _autowire);
|
se = session::create(_ptr, saddr, daddr, taddr, _autowire);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ru->is_auto()) {
|
if (ru->is_auto()) {
|
||||||
ptr<route> rt = route::find(taddr);
|
ptr<route> rt = route::find(taddr);
|
||||||
|
|
||||||
@ -129,23 +114,60 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
|
|||||||
// This rule doesn't have an interface, and thus we'll consider
|
// This rule doesn't have an interface, and thus we'll consider
|
||||||
// it "static" and immediately send the response.
|
// it "static" and immediately send the response.
|
||||||
se->handle_advert();
|
se->handle_advert();
|
||||||
return;
|
return se;
|
||||||
} else {
|
} else {
|
||||||
se->add_iface((*it)->ifa());
|
se->add_iface((*it)->ifa());
|
||||||
#ifdef WITH_ND_NETLINK
|
#ifdef WITH_ND_NETLINK
|
||||||
if (if_addr_find((*it)->ifa()->name(), &taddr.const_addr())) {
|
if (if_addr_find((*it)->ifa()->name(), &taddr.const_addr())) {
|
||||||
logger::debug() << "Sending NA out " << (*it)->ifa()->name();
|
logger::debug() << "Sending NA out " << (*it)->ifa()->name();
|
||||||
se->add_iface(_ifa);
|
se->add_iface(_ifa);
|
||||||
se->handle_advert(_ifa);
|
se->handle_advert();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (se) {
|
if (se) {
|
||||||
_sessions.push_back(se);
|
_sessions.push_back(se);
|
||||||
se->send_solicit();
|
}
|
||||||
|
|
||||||
|
return se;
|
||||||
|
}
|
||||||
|
|
||||||
|
void proxy::handle_advert(const address& saddr, const address& taddr, const ptr<iface>& receiver)
|
||||||
|
{
|
||||||
|
logger::debug()
|
||||||
|
<< "proxy::handle_advert() proxy=" << (ifa() ? ifa()->name() : "null") << ", receiver=" << (receiver ? receiver->name() : "null")
|
||||||
|
<< ", saddr=" << saddr.to_string()
|
||||||
|
<< ", taddr=" << taddr.to_string();
|
||||||
|
|
||||||
|
ptr<session> se = find_or_create_session(saddr, all_nodes, taddr, receiver);
|
||||||
|
if (!se) return;
|
||||||
|
|
||||||
|
se->handle_advert(receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proxy::handle_solicit(const address& saddr, const address& daddr, const address& taddr)
|
||||||
|
{
|
||||||
|
logger::debug()
|
||||||
|
<< "proxy::handle_solicit() ifa=" << ((_ifa) ? _ifa->name() : "null")
|
||||||
|
<< ", saddr=" << saddr.to_string()
|
||||||
|
<< ", taddr=" << taddr.to_string();
|
||||||
|
|
||||||
|
ptr<session> se = find_or_create_session(saddr, daddr, taddr, ptr<iface>());
|
||||||
|
if (!se) return;
|
||||||
|
|
||||||
|
se->touch();
|
||||||
|
|
||||||
|
switch (se->status()) {
|
||||||
|
case session::WAITING:
|
||||||
|
case session::INVALID:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case session::VALID:
|
||||||
|
case session::RENEWING:
|
||||||
|
se->send_advert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,12 @@ public:
|
|||||||
static ptr<proxy> create(const ptr<iface>& ifa, bool promiscuous);
|
static ptr<proxy> create(const ptr<iface>& ifa, bool promiscuous);
|
||||||
|
|
||||||
static ptr<proxy> open(const std::string& ifn, bool promiscuous);
|
static ptr<proxy> open(const std::string& ifn, bool promiscuous);
|
||||||
|
|
||||||
|
ptr<session> find_or_create_session(const address& saddr, const address& daddr, const address& taddr, const ptr<iface>& receiver);
|
||||||
|
|
||||||
|
void handle_advert(const address& saddr, const address& taddr, const ptr<iface>& receiver);
|
||||||
|
|
||||||
void handle_solicit(const address& saddr, const address& daddr,
|
void handle_solicit(const address& saddr, const address& daddr, const address& taddr);
|
||||||
const address& taddr);
|
|
||||||
|
|
||||||
void remove_session(const ptr<session>& se);
|
void remove_session(const ptr<session>& se);
|
||||||
|
|
||||||
|
@ -104,14 +104,14 @@ ptr<session> session::create(const ptr<proxy>& pr, const address& saddr,
|
|||||||
se->_taddr = taddr;
|
se->_taddr = taddr;
|
||||||
se->_daddr = daddr;
|
se->_daddr = daddr;
|
||||||
se->_autowire = auto_wire;
|
se->_autowire = auto_wire;
|
||||||
se->_wired = false;
|
se->_wired = false;
|
||||||
se->_ttl = pr->timeout();
|
se->_ttl = pr->timeout();
|
||||||
se->_touched = true;
|
se->_touched = false;
|
||||||
|
|
||||||
_sessions.push_back(se);
|
_sessions.push_back(se);
|
||||||
|
|
||||||
logger::debug()
|
logger::debug()
|
||||||
<< "session::create() pr=" << logger::format("%x", (proxy* )pr) << ", slave=" << ((pr->ifa()) ? pr->ifa()->name() : "null") << ", saddr=" << saddr
|
<< "session::create() pr=" << logger::format("%x", (proxy* )pr) << ", proxy=" << ((pr->ifa()) ? pr->ifa()->name() : "null") << ", saddr=" << saddr
|
||||||
<< ", daddr=" << daddr << ", taddr=" << taddr << ", autowire=" << (auto_wire == true ? "yes" : "no") << " =" << logger::format("%x", (session* )se);
|
<< ", daddr=" << daddr << ", taddr=" << taddr << ", autowire=" << (auto_wire == true ? "yes" : "no") << " =" << logger::format("%x", (session* )se);
|
||||||
|
|
||||||
return se;
|
return se;
|
||||||
@ -139,7 +139,13 @@ void session::send_solicit()
|
|||||||
|
|
||||||
void session::touch()
|
void session::touch()
|
||||||
{
|
{
|
||||||
_touched = true;
|
if (_touched == false)
|
||||||
|
{
|
||||||
|
_touched = true;
|
||||||
|
|
||||||
|
if (status() == session::WAITING || status() == session::INVALID)
|
||||||
|
send_solicit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void session::send_advert()
|
void session::send_advert()
|
||||||
@ -193,13 +199,14 @@ void session::handle_auto_unwire(const ptr<iface>& ifa)
|
|||||||
|
|
||||||
void session::handle_advert(const ptr<iface>& ifa)
|
void session::handle_advert(const ptr<iface>& ifa)
|
||||||
{
|
{
|
||||||
if (_autowire == true) {
|
if (_autowire == true && _status == WAITING) {
|
||||||
handle_auto_wire(ifa);
|
handle_auto_wire(ifa);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_advert();
|
handle_advert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void session::handle_advert()
|
void session::handle_advert()
|
||||||
{
|
{
|
||||||
logger::debug()
|
logger::debug()
|
||||||
|
@ -84,9 +84,9 @@ public:
|
|||||||
int status() const;
|
int status() const;
|
||||||
|
|
||||||
void status(int val);
|
void status(int val);
|
||||||
|
|
||||||
void handle_advert();
|
|
||||||
|
|
||||||
|
void handle_advert();
|
||||||
|
|
||||||
void handle_advert(const ptr<iface>& ifa);
|
void handle_advert(const ptr<iface>& ifa);
|
||||||
|
|
||||||
void handle_auto_wire(const ptr<iface>& ifa);
|
void handle_auto_wire(const ptr<iface>& ifa);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user