Skip to content

Commit f71a446

Browse files
committed
RSVP-TE: derive peers automatically from the TED (peers="auto")
RSVP-TE required its neighbours to be listed by hand in the "peers" parameter (interface names), per router -- tedious and error-prone for anything but tiny topologies. But RSVP's neighbours are exactly the directly-connected routers that run the same TE control plane, and the TED already discovers them: for every local interface it records the neighbour's router id and address. Add a "peers" value "auto" (now the default) that derives the peer set from the TED instead of a manual list: - RsvpTe::setupHello() iterates the TED's local links (advrouter == our routerId) and sets up a HELLO with each directly-connected neighbour that runs RSVP (RsvpTe), skipping hosts (no router id) and non-RSVP routers. - LinkStateRouting does the same for the interfaces it floods TE link-state on, filtering to neighbours that run link-state routing. (The two filters differ on purpose: an LDP-TE router is a link-state peer but not an RSVP HELLO peer.) - MplsRouterBase.ned / RsvpTe.ned default peers to "auto". An explicit space-separated interface-name list still works as before (override). Ordering: TED (base submodule) initializes before RsvpTe/LinkStateRouting, and all three run at INITSTAGE_ROUTING_PROTOCOLS, so the TED is populated before the peers are derived. Examples that set "peers" explicitly are unaffected (byte-identical fingerprints).
1 parent 9071f8c commit f71a446

5 files changed

Lines changed: 109 additions & 31 deletions

File tree

src/inet/networklayer/rsvpte/RsvpTe.cc

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -301,44 +301,87 @@ std::vector<RsvpTe::traffic_path_t>::iterator RsvpTe::findPath(traffic_session_t
301301
return it;
302302
}
303303

304+
// Recursively tests whether a network node contains an RSVP-TE module.
305+
static bool moduleContainsRsvp(cModule *module)
306+
{
307+
for (cModule::SubmoduleIterator it(module); !it.end(); ++it) {
308+
cModule *submodule = *it;
309+
if (dynamic_cast<RsvpTe *>(submodule) != nullptr)
310+
return true;
311+
if (moduleContainsRsvp(submodule))
312+
return true;
313+
}
314+
return false;
315+
}
316+
317+
bool RsvpTe::peerRunsRsvp(Ipv4Address peerInterface)
318+
{
319+
cModule *peerNode = L3AddressResolver().findHostWithAddress(L3Address(peerInterface));
320+
return peerNode != nullptr && moduleContainsRsvp(peerNode);
321+
}
322+
304323
void RsvpTe::setupHello()
305324
{
306325
routerId = rt->getRouterId();
307326

308327
helloInterval = par("helloInterval");
309328
helloTimeout = par("helloTimeout");
310329

311-
cStringTokenizer tokenizer(par("peers"));
312-
const char *token;
313-
while ((token = tokenizer.nextToken()) != nullptr) {
314-
Ipv4Address peer = tedmod->getPeerByLocalAddress(CHK(ift->findInterfaceByName(token))->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
330+
const char *peers = par("peers");
331+
if (!strcmp(peers, "auto")) {
332+
// Derive the RSVP peers automatically from the Traffic Engineering
333+
// Database (TED), which has already discovered every directly-connected
334+
// neighbour by walking the topology -- analogous to how a real RSVP-TE
335+
// speaker learns its adjacencies from the IGP-TE. Set up a HELLO with each
336+
// directly-connected neighbour that actually runs RSVP (this skips plain
337+
// IP routers and end hosts, which would never answer a HELLO).
338+
for (auto& link : tedmod->ted) {
339+
if (link.advrouter != routerId) // not one of our local links
340+
continue;
341+
if (link.linkid.isUnspecified()) // neighbour has no router id (e.g. a host)
342+
continue;
343+
if (!peerRunsRsvp(link.remote)) // neighbour does not speak RSVP
344+
continue;
345+
addHelloPeer(link.linkid);
346+
}
347+
}
348+
else {
349+
cStringTokenizer tokenizer(peers);
350+
const char *token;
351+
while ((token = tokenizer.nextToken()) != nullptr) {
352+
Ipv4Address peer = tedmod->getPeerByLocalAddress(CHK(ift->findInterfaceByName(token))->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
353+
addHelloPeer(peer);
354+
}
355+
}
356+
}
315357

316-
HelloState h;
358+
void RsvpTe::addHelloPeer(Ipv4Address peer)
359+
{
360+
HelloState h;
317361

318-
h.timer = new HelloTimerMsg("hello timer");
319-
h.timer->setPeer(peer);
362+
h.timer = new HelloTimerMsg("hello timer");
363+
h.timer->setPeer(peer);
320364

321-
h.timeout = new HelloTimeoutMsg("hello timeout");
322-
h.timeout->setPeer(peer);
365+
h.timeout = new HelloTimeoutMsg("hello timeout");
366+
h.timeout->setPeer(peer);
323367

324-
h.peer = peer;
368+
h.peer = peer;
325369

326-
if (helloInterval > 0.0) {
327-
// peer is down until we know he is ok
370+
if (helloInterval > 0.0) {
371+
// peer is down until we know he is ok
328372

329-
h.ok = false;
330-
}
331-
else {
332-
// don't use HELLO at all, consider all peers running all the time
373+
h.ok = false;
374+
}
375+
else {
376+
// don't use HELLO at all, consider all peers running all the time
333377

334-
h.ok = true;
335-
}
378+
h.ok = true;
379+
}
336380

337-
HelloList.push_back(h);
381+
HelloList.push_back(h);
338382

339-
if (helloInterval > 0.0) {
340-
startHello(peer, exponential(helloInterval));
341-
}
383+
if (helloInterval > 0.0) {
384+
startHello(peer, exponential(helloInterval));
342385
}
343386
}
344387

src/inet/networklayer/rsvpte/RsvpTe.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ class INET_API RsvpTe : public RoutingProtocolBase, public IScriptable
218218
virtual void sendPathNotify(int handler, const SessionObj& session, const SenderTemplateObj& sender, int status, simtime_t delay);
219219

220220
virtual void setupHello();
221+
virtual void addHelloPeer(Ipv4Address peer);
222+
// True if the node owning peerInterface runs RSVP (used to auto-derive peers).
223+
virtual bool peerRunsRsvp(Ipv4Address peerInterface);
221224
virtual void startHello(Ipv4Address peer, simtime_t delay);
222225
virtual void removeHello(HelloState *h);
223226

src/inet/networklayer/rsvpte/RsvpTe.ned

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ simple RsvpTe extends SimpleModule
9191
string tedModule;
9292
string classifierModule; // The path to the module which implements the IIngressClassifier C++ interface
9393
xml traffic = default(xml("<sessions/>")); // Specifies paths to set up
94-
string peers; // Names of the interfaces towards RSVP peers
94+
string peers = default("auto"); // "auto" (default) derives the RSVP peers from the TED (every directly-connected RSVP-speaking neighbour); otherwise a space-separated list of the interface names towards the RSVP peers
9595
double helloInterval @unit(s);
9696
double helloTimeout @unit(s);
9797
@display("i=block/control");

src/inet/networklayer/ted/LinkStateRouting.cc

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "inet/common/ProtocolTag_m.h"
1414
#include "inet/common/Simsignals.h"
1515
#include "inet/common/stlutils.h"
16+
#include "inet/networklayer/common/L3AddressResolver.h"
1617
#include "inet/networklayer/common/L3AddressTag_m.h"
1718
#include "inet/networklayer/contract/IInterfaceTable.h"
1819
#include "inet/networklayer/ipv4/IIpv4RoutingTable.h"
@@ -32,6 +33,20 @@ LinkStateRouting::~LinkStateRouting()
3233
cancelAndDelete(announceMsg);
3334
}
3435

36+
// Recursively tests whether a network node runs link-state routing (i.e. is an
37+
// RSVP-TE peer we should flood our TE link-state to).
38+
static bool moduleContainsLinkStateRouting(cModule *module)
39+
{
40+
for (cModule::SubmoduleIterator it(module); !it.end(); ++it) {
41+
cModule *submodule = *it;
42+
if (dynamic_cast<LinkStateRouting *>(submodule) != nullptr)
43+
return true;
44+
if (moduleContainsLinkStateRouting(submodule))
45+
return true;
46+
}
47+
return false;
48+
}
49+
3550
void LinkStateRouting::initialize(int stage)
3651
{
3752
SimpleModule::initialize(stage);
@@ -46,13 +61,30 @@ void LinkStateRouting::initialize(int stage)
4661
cModule *host = getContainingNode(this);
4762
host->subscribe(tedChangedSignal, this);
4863

49-
// peers are given as interface names in the "peers" module parameter;
50-
// store corresponding interface addresses in peerIfAddrs[]
51-
cStringTokenizer tokenizer(par("peers"));
52-
IInterfaceTable *ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
53-
const char *token;
54-
while ((token = tokenizer.nextToken()) != nullptr) {
55-
peerIfAddrs.push_back(CHK(ift->findInterfaceByName(token))->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
64+
// Determine the local interfaces facing our RSVP-TE peers, and store their
65+
// addresses in peerIfAddrs[]. With peers="auto" (the default) they are
66+
// derived from the TED -- every directly-connected neighbour that also runs
67+
// link-state routing (skipping hosts and non-TE routers); otherwise "peers"
68+
// is a space-separated list of the peer-facing interface names.
69+
const char *peers = par("peers");
70+
if (!strcmp(peers, "auto")) {
71+
for (auto& link : tedmod->ted) {
72+
if (link.advrouter != routerId) // not one of our local links
73+
continue;
74+
if (link.linkid.isUnspecified()) // neighbour has no router id (e.g. a host)
75+
continue;
76+
cModule *peerNode = L3AddressResolver().findHostWithAddress(L3Address(link.remote));
77+
if (peerNode != nullptr && moduleContainsLinkStateRouting(peerNode))
78+
peerIfAddrs.push_back(link.local);
79+
}
80+
}
81+
else {
82+
cStringTokenizer tokenizer(peers);
83+
IInterfaceTable *ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
84+
const char *token;
85+
while ((token = tokenizer.nextToken()) != nullptr) {
86+
peerIfAddrs.push_back(CHK(ift->findInterfaceByName(token))->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
87+
}
5688
}
5789

5890
// schedule start of flooding link state info

src/inet/node/mpls/MplsRouterBase.ned

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module MplsRouterBase extends Router
3131
{
3232
parameters:
3333
@display("i=abstract/router");
34-
string peers;
34+
string peers = default("auto"); // RSVP peers; "auto" derives them from the TED (see ~RsvpTe)
3535
string routerId = default("auto");
3636
*.routingTable.routerId = this.routerId;
3737
*.tedModule = default(absPath(".ted"));

0 commit comments

Comments
 (0)