From fc19cb8e6884ae9f1d4be09fbb2aacbe2169ec1a Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Fri, 19 Jun 2026 10:54:01 +0200 Subject: [PATCH 1/5] Make BGP supports lifecycle operations --- src/inet/routing/bgpv4/Bgp.cc | 79 +++++++++++++++++++++-------------- src/inet/routing/bgpv4/Bgp.h | 14 ++++--- 2 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/inet/routing/bgpv4/Bgp.cc b/src/inet/routing/bgpv4/Bgp.cc index 528ba51e731..5e6ef1ca4d4 100644 --- a/src/inet/routing/bgpv4/Bgp.cc +++ b/src/inet/routing/bgpv4/Bgp.cc @@ -7,7 +7,6 @@ #include "inet/routing/bgpv4/Bgp.h" #include "inet/common/ModuleAccess.h" -#include "inet/common/lifecycle/NodeStatus.h" #include "inet/routing/bgpv4/BgpConfigReader.h" #include "inet/routing/bgpv4/BgpSession.h" @@ -28,33 +27,19 @@ Bgp::~Bgp() void Bgp::initialize(int stage) { - SimpleModule::initialize(stage); + RoutingProtocolBase::initialize(stage); if (stage == INITSTAGE_LOCAL) { ift.reference(this, "interfaceTableModule", true); rt.reference(this, "routingTableModule", true); startupTimer = new cMessage("BGP-startup"); - - WATCH(isUp); - } - else if (stage == INITSTAGE_ROUTING_PROTOCOLS) { // interfaces and static routes are already initialized - cModule *node = findContainingNode(this); - NodeStatus *nodeStatus = node ? check_and_cast_nullable(node->getSubmodule("status")) : nullptr; - isUp = !nodeStatus || nodeStatus->getState() == NodeStatus::UP; - if (isUp) { - simtime_t startupTime = par("startupTime"); - if (startupTime == 0) - createBgpRouter(); - else - scheduleAfter(startupTime, startupTimer); - } } } void Bgp::finish() { - if (!isUp) { + if (!bgpRouter) { EV_ERROR << "Protocol is turned off. \n"; return; } @@ -62,28 +47,61 @@ void Bgp::finish() bgpRouter->recordStatistics(); } -void Bgp::handleMessage(cMessage *msg) +void Bgp::handleMessageWhenUp(cMessage *msg) { - if (!isUp) { - if (msg->isSelfMessage()) - throw cRuntimeError("Model error: self msg '%s' received when protocol is down", msg->getName()); - EV_ERROR << "Protocol is turned off, dropping '" << msg->getName() << "' message\n"; - delete msg; - return; + if (msg == startupTimer) + createBgpRouter(); + else { + if (!bgpRouter) { + if (msg->isSelfMessage()) + throw cRuntimeError("Model error: self msg '%s' received before BGP startup", msg->getName()); + EV_WARN << "BGP has not started yet, dropping '" << msg->getName() << "' message\n"; + delete msg; + } + else if (msg->isSelfMessage()) // BGP level + handleTimer(msg); + else if (!strcmp(msg->getArrivalGate()->getName(), "socketIn")) // TCP level + bgpRouter->processMessageFromTCP(msg); + else + delete msg; } +} - if (msg == startupTimer) +void Bgp::handleStartOperation(LifecycleOperation *operation) +{ + startBgp(); +} + +void Bgp::handleStopOperation(LifecycleOperation *operation) +{ + stopBgp(); +} + +void Bgp::handleCrashOperation(LifecycleOperation *operation) +{ + stopBgp(); +} + +void Bgp::startBgp() +{ + ASSERT(bgpRouter == nullptr); + simtime_t startupTime = par("startupTime"); + if (startupTime == 0) createBgpRouter(); - else if (msg->isSelfMessage()) // BGP level - handleTimer(msg); - else if (!strcmp(msg->getArrivalGate()->getName(), "socketIn")) // TCP level - bgpRouter->processMessageFromTCP(msg); else - delete msg; + scheduleAfter(startupTime, startupTimer); +} + +void Bgp::stopBgp() +{ + cancelEvent(startupTimer); + delete bgpRouter; + bgpRouter = nullptr; } void Bgp::createBgpRouter() { + ASSERT(bgpRouter == nullptr); bgpRouter = new BgpRouter(this, ift, rt); // read BGP configuration @@ -128,4 +146,3 @@ void Bgp::handleTimer(cMessage *timer) } // namespace bgp } // namespace inet - diff --git a/src/inet/routing/bgpv4/Bgp.h b/src/inet/routing/bgpv4/Bgp.h index 435d85a7da5..51101f517b8 100644 --- a/src/inet/routing/bgpv4/Bgp.h +++ b/src/inet/routing/bgpv4/Bgp.h @@ -7,10 +7,9 @@ #ifndef __INET_BGP_H #define __INET_BGP_H -#include "inet/common/SimpleModule.h" -#include "inet/common/lifecycle/LifecycleUnsupported.h" #include "inet/networklayer/contract/ipv4/Ipv4Address.h" #include "inet/networklayer/ipv4/Ipv4InterfaceData.h" +#include "inet/routing/base/RoutingProtocolBase.h" #include "inet/routing/bgpv4/BgpCommon.h" #include "inet/routing/bgpv4/BgpRouter.h" #include "inet/routing/bgpv4/bgpmessage/BgpHeader_m.h" @@ -19,12 +18,11 @@ namespace inet { namespace bgp { -class INET_API Bgp : public SimpleModule, protected cListener, public LifecycleUnsupported +class INET_API Bgp : public RoutingProtocolBase, protected cListener { private: ModuleRefByPar rt; ModuleRefByPar ift; - bool isUp = false; BgpRouter *bgpRouter = nullptr; // data structure to fill in cMessage *startupTimer = nullptr; // timer for delayed startup @@ -35,7 +33,12 @@ class INET_API Bgp : public SimpleModule, protected cListener, public LifecycleU protected: virtual int numInitStages() const override { return NUM_INIT_STAGES; } virtual void initialize(int stage) override; - virtual void handleMessage(cMessage *msg) override; + virtual void handleMessageWhenUp(cMessage *msg) override; + virtual void handleStartOperation(LifecycleOperation *operation) override; + virtual void handleStopOperation(LifecycleOperation *operation) override; + virtual void handleCrashOperation(LifecycleOperation *operation) override; + void startBgp(); + void stopBgp(); void createBgpRouter(); void handleTimer(cMessage *timer); virtual void finish() override; @@ -46,4 +49,3 @@ class INET_API Bgp : public SimpleModule, protected cListener, public LifecycleU } // namespace inet #endif - From a27887a1991447a7a9761129bf3df5295a7fcab6 Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Fri, 19 Jun 2026 11:19:58 +0200 Subject: [PATCH 2/5] Remove BGP routes at shutdown/crash --- src/inet/routing/bgpv4/Bgp.cc | 12 ++++++++++++ src/inet/routing/bgpv4/Bgp.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/inet/routing/bgpv4/Bgp.cc b/src/inet/routing/bgpv4/Bgp.cc index 5e6ef1ca4d4..566f5b2651b 100644 --- a/src/inet/routing/bgpv4/Bgp.cc +++ b/src/inet/routing/bgpv4/Bgp.cc @@ -95,10 +95,22 @@ void Bgp::startBgp() void Bgp::stopBgp() { cancelEvent(startupTimer); + removeBgpRoutes(); delete bgpRouter; bgpRouter = nullptr; } +void Bgp::removeBgpRoutes() +{ + for (int i = rt->getNumRoutes() - 1; i >= 0; i--) { + Ipv4Route *route = rt->getRoute(i); + if (route->getSourceType() == IRoute::BGP) { + EV_INFO << "Removing BGP route " << route->str() << endl; + rt->deleteRoute(route); + } + } +} + void Bgp::createBgpRouter() { ASSERT(bgpRouter == nullptr); diff --git a/src/inet/routing/bgpv4/Bgp.h b/src/inet/routing/bgpv4/Bgp.h index 51101f517b8..f206c801685 100644 --- a/src/inet/routing/bgpv4/Bgp.h +++ b/src/inet/routing/bgpv4/Bgp.h @@ -39,6 +39,7 @@ class INET_API Bgp : public RoutingProtocolBase, protected cListener virtual void handleCrashOperation(LifecycleOperation *operation) override; void startBgp(); void stopBgp(); + void removeBgpRoutes(); void createBgpRouter(); void handleTimer(cMessage *timer); virtual void finish() override; From abe21ddd9dd084eb989728a07ee1bc61f228846c Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Fri, 19 Jun 2026 12:26:22 +0200 Subject: [PATCH 3/5] Restart and reestablish BGP sessions at node restart - Restart now creates fresh BGP sessions and uses normal start events after lifecycle-related connection loss. - Added lifecycle-scoped restart scheduling for BGP FSM loss paths, gated to nodes with a status submodule so existing BGP examples keep their current fingerprint behavior. --- src/inet/routing/bgpv4/Bgp.cc | 8 +++++--- src/inet/routing/bgpv4/Bgp.h | 2 +- src/inet/routing/bgpv4/BgpFsm.cc | 16 ++++++++++++++++ src/inet/routing/bgpv4/BgpRouter.cc | 26 +++++++++++++++++++++++++- src/inet/routing/bgpv4/BgpRouter.h | 5 +++-- src/inet/routing/bgpv4/BgpSession.cc | 13 +++++-------- src/inet/routing/bgpv4/BgpSession.h | 2 +- 7 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/inet/routing/bgpv4/Bgp.cc b/src/inet/routing/bgpv4/Bgp.cc index 566f5b2651b..3ddba9206d3 100644 --- a/src/inet/routing/bgpv4/Bgp.cc +++ b/src/inet/routing/bgpv4/Bgp.cc @@ -74,12 +74,12 @@ void Bgp::handleStartOperation(LifecycleOperation *operation) void Bgp::handleStopOperation(LifecycleOperation *operation) { - stopBgp(); + stopBgp(false); } void Bgp::handleCrashOperation(LifecycleOperation *operation) { - stopBgp(); + stopBgp(true); } void Bgp::startBgp() @@ -92,10 +92,12 @@ void Bgp::startBgp() scheduleAfter(startupTime, startupTimer); } -void Bgp::stopBgp() +void Bgp::stopBgp(bool abort) { cancelEvent(startupTimer); removeBgpRoutes(); + if (bgpRouter) + bgpRouter->closeSessions(abort); delete bgpRouter; bgpRouter = nullptr; } diff --git a/src/inet/routing/bgpv4/Bgp.h b/src/inet/routing/bgpv4/Bgp.h index f206c801685..3b960075d51 100644 --- a/src/inet/routing/bgpv4/Bgp.h +++ b/src/inet/routing/bgpv4/Bgp.h @@ -38,7 +38,7 @@ class INET_API Bgp : public RoutingProtocolBase, protected cListener virtual void handleStopOperation(LifecycleOperation *operation) override; virtual void handleCrashOperation(LifecycleOperation *operation) override; void startBgp(); - void stopBgp(); + void stopBgp(bool abort); void removeBgpRoutes(); void createBgpRouter(); void handleTimer(cMessage *timer); diff --git a/src/inet/routing/bgpv4/BgpFsm.cc b/src/inet/routing/bgpv4/BgpFsm.cc index 31701aca05d..d404e6e7215 100644 --- a/src/inet/routing/bgpv4/BgpFsm.cc +++ b/src/inet/routing/bgpv4/BgpFsm.cc @@ -78,6 +78,8 @@ void Connect::HoldTimer_Expires() // - changes its state to Idle. session._info.sessionEstablished = false; setState(); + if (session.isLifecycleNode()) + session.startConnection(); } void Connect::KeepaliveTimer_Expires() @@ -156,6 +158,8 @@ void Active::HoldTimer_Expires() // - changes its state to Idle. session._info.sessionEstablished = false; setState(); + if (session.isLifecycleNode()) + session.startConnection(); } void Active::KeepaliveTimer_Expires() @@ -444,6 +448,8 @@ void Established::ConnectRetryTimer_Expires() // - changes its state to Idle. session._info.sessionEstablished = false; setState(); + if (session.isLifecycleNode()) + session.startConnection(); } void Established::HoldTimer_Expires() @@ -461,6 +467,8 @@ void Established::HoldTimer_Expires() // - changes its state to Idle. session._info.sessionEstablished = false; setState(); + if (session.isLifecycleNode()) + session.startConnection(); } void Established::KeepaliveTimer_Expires() @@ -479,6 +487,14 @@ void Established::KeepaliveTimer_Expires() void Established::TcpConnectionFails() { EV_TRACE << "Processing Established::TcpConnectionFails" << std::endl; + BgpSession& session = TopState::box().getModule(); + session.restartsConnectRetryTimer(false); + session._info.socket->abort(); + ++session._connectRetryCounter; + session._info.sessionEstablished = false; + setState(); + if (session.isLifecycleNode()) + session.startConnection(); } void Established::OpenMsgEvent() diff --git a/src/inet/routing/bgpv4/BgpRouter.cc b/src/inet/routing/bgpv4/BgpRouter.cc index 901441fe9d2..254e7b22aa5 100644 --- a/src/inet/routing/bgpv4/BgpRouter.cc +++ b/src/inet/routing/bgpv4/BgpRouter.cc @@ -78,6 +78,22 @@ void BgpRouter::recordStatistics() bgpModule->recordScalar("UpdateMsgRcv", statTab[5]); } +void BgpRouter::closeSessions(bool abort) +{ + for (auto& elem : _BGPSessions) { + TcpSocket *socket = elem.second->getSocket(); + if (socket) { + _socketMap.removeSocket(socket); + abort ? socket->abort() : socket->close(); + } + TcpSocket *socketListen = elem.second->getSocketListen(); + if (socketListen) { + _socketMap.removeSocket(socketListen); + abort ? socketListen->abort() : socketListen->close(); + } + } +} + SessionId BgpRouter::createIbgpSession(const char *peerAddr) { SessionInfo info; @@ -415,6 +431,15 @@ void BgpRouter::socketFailure(TcpSocket *socket, int code) } } +void BgpRouter::socketPeerClosed(TcpSocket *socket) +{ + socket->close(); + int connId = socket->getSocketId(); + _currSessionId = findIdFromSocketConnId(_BGPSessions, connId); + if (_currSessionId != static_cast(-1)) + _BGPSessions[_currSessionId]->getFSM()->TcpConnectionFails(); +} + void BgpRouter::socketDataArrived(TcpSocket *socket) { auto queue = socket->getReadBuffer(); @@ -1099,4 +1124,3 @@ bool BgpRouter::isReachable(const Ipv4Address addr) const } // namespace bgp } // namespace inet - diff --git a/src/inet/routing/bgpv4/BgpRouter.h b/src/inet/routing/bgpv4/BgpRouter.h index 73776578fb3..48d83a86c49 100644 --- a/src/inet/routing/bgpv4/BgpRouter.h +++ b/src/inet/routing/bgpv4/BgpRouter.h @@ -80,6 +80,7 @@ class INET_API BgpRouter : public TcpSocket::BufferingCallback void printSessionSummary(); void addWatches(); void recordStatistics(); + void closeSessions(bool abort); SessionId createEbgpSession(const char *peerAddr, SessionInfo& externalInfo); SessionId createIbgpSession(const char *peerAddr); @@ -105,7 +106,7 @@ class INET_API BgpRouter : public TcpSocket::BufferingCallback virtual void socketDataArrived(TcpSocket *socket, Packet *packet, bool urgent) override; virtual void socketAvailable(TcpSocket *socket, TcpAvailableInfo *availableInfo) override { socket->accept(availableInfo->getNewSocketId()); } // TODO virtual void socketEstablished(TcpSocket *socket) override; - virtual void socketPeerClosed(TcpSocket *socket) override {} + virtual void socketPeerClosed(TcpSocket *socket) override; virtual void socketClosed(TcpSocket *socket) override {} virtual void socketFailure(TcpSocket *socket, int code) override; virtual void socketStatusArrived(TcpSocket *socket, TcpStatusInfo *status) override {} @@ -119,6 +120,7 @@ class INET_API BgpRouter : public TcpSocket::BufferingCallback cMessage *getCancelEvent(cMessage *msg) { return bgpModule->cancelEvent(msg); } IIpv4RoutingTable *getIPRoutingTable() { return rt; } std::vector getBGPRoutingTable() { return bgpRoutingTable; } + bool isLifecycleNode() const { return bgpModule->getParentModule()->getSubmodule("status") != nullptr; } /** * \brief active listenSocket for a given session (used by fsm) @@ -181,4 +183,3 @@ class INET_API BgpRouter : public TcpSocket::BufferingCallback } // namespace inet #endif - diff --git a/src/inet/routing/bgpv4/BgpSession.cc b/src/inet/routing/bgpv4/BgpSession.cc index c5df42604c0..5f809337394 100644 --- a/src/inet/routing/bgpv4/BgpSession.cc +++ b/src/inet/routing/bgpv4/BgpSession.cc @@ -77,13 +77,11 @@ void BgpSession::startConnection() if (_ptrStartEvent == nullptr) _ptrStartEvent = new cMessage("BGP Start", START_EVENT_KIND); - if (_info.sessionType == IGP) { - if (simTime() > _StartEventTime) - _StartEventTime = simTime(); - if (!_ptrStartEvent->isScheduled()) - bgpRouter.getScheduleAt(_StartEventTime, _ptrStartEvent); - _ptrStartEvent->setContextPointer(this); - } + if (simTime() > _StartEventTime) + _StartEventTime = simTime(); + if (!_ptrStartEvent->isScheduled()) + bgpRouter.getScheduleAt(_StartEventTime, _ptrStartEvent); + _ptrStartEvent->setContextPointer(this); } void BgpSession::restartsHoldTimer() @@ -232,4 +230,3 @@ std::ostream& operator<<(std::ostream& out, const BgpSession& entry) } // namespace bgp } // namespace inet - diff --git a/src/inet/routing/bgpv4/BgpSession.h b/src/inet/routing/bgpv4/BgpSession.h index b85eedda29a..d5a458c6b0a 100644 --- a/src/inet/routing/bgpv4/BgpSession.h +++ b/src/inet/routing/bgpv4/BgpSession.h @@ -101,6 +101,7 @@ class INET_API BgpSession : public cObject static const std::string getTypeString(BgpSessionType sessionType); NetworkInterface *getLinkIntf() const { return _info.linkIntf; } bool getCheckConnection() const { return _info.checkConnection; } + bool isLifecycleNode() const { return bgpRouter.isLifecycleNode(); } Ipv4Address getPeerAddr() const { return _info.peerAddr; } bool getNextHopSelf() const { return _info.nextHopSelf; } int getLocalPreference() const { return _info.localPreference; } @@ -120,4 +121,3 @@ std::ostream& operator<<(std::ostream& out, const BgpSession& entry); } // namespace inet #endif - From abb2114f88b8652d7796d375f55d471161a2f8e1 Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Fri, 19 Jun 2026 12:26:49 +0200 Subject: [PATCH 4/5] Add BgpLifecycle simulation example to be used as smoke test --- examples/bgpv4/BgpLifecycle/BGPConfig.xml | 27 ++++++++ examples/bgpv4/BgpLifecycle/IPv4Config.xml | 10 +++ examples/bgpv4/BgpLifecycle/Network.ned | 70 +++++++++++++++++++++ examples/bgpv4/BgpLifecycle/OSPFConfig.xml | 22 +++++++ examples/bgpv4/BgpLifecycle/network.jpg | Bin 0 -> 7395 bytes examples/bgpv4/BgpLifecycle/omnetpp.ini | 53 ++++++++++++++++ 6 files changed, 182 insertions(+) create mode 100644 examples/bgpv4/BgpLifecycle/BGPConfig.xml create mode 100644 examples/bgpv4/BgpLifecycle/IPv4Config.xml create mode 100644 examples/bgpv4/BgpLifecycle/Network.ned create mode 100644 examples/bgpv4/BgpLifecycle/OSPFConfig.xml create mode 100644 examples/bgpv4/BgpLifecycle/network.jpg create mode 100644 examples/bgpv4/BgpLifecycle/omnetpp.ini diff --git a/examples/bgpv4/BgpLifecycle/BGPConfig.xml b/examples/bgpv4/BgpLifecycle/BGPConfig.xml new file mode 100644 index 00000000000..92f6331a1ed --- /dev/null +++ b/examples/bgpv4/BgpLifecycle/BGPConfig.xml @@ -0,0 +1,27 @@ + + + + + 120 + 180 + 60 + 2 + + + + + + + + + + + + + + + + + + + diff --git a/examples/bgpv4/BgpLifecycle/IPv4Config.xml b/examples/bgpv4/BgpLifecycle/IPv4Config.xml new file mode 100644 index 00000000000..9ec7919a1af --- /dev/null +++ b/examples/bgpv4/BgpLifecycle/IPv4Config.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/examples/bgpv4/BgpLifecycle/Network.ned b/examples/bgpv4/BgpLifecycle/Network.ned new file mode 100644 index 00000000000..f849685abe8 --- /dev/null +++ b/examples/bgpv4/BgpLifecycle/Network.ned @@ -0,0 +1,70 @@ +package inet.examples.bgpv4.BgpLifecycle; + +import inet.common.misc.ThruputMeteringChannel; +import inet.common.scenario.ScenarioManager; +import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; +import inet.node.bgp.BgpRouter; +import inet.node.inet.StandardHost; +import inet.visualizer.canvas.integrated.IntegratedCanvasVisualizer; + +network BgpNetwork +{ + types: + channel LINK_100 extends ThruputMeteringChannel + { + parameters: + delay = 50us; + datarate = 100Mbps; + displayAsTooltip = true; + thruputDisplayFormat = "#N"; + } + submodules: + visualizer: IntegratedCanvasVisualizer { + parameters: + @display("p=100,100;is=s"); + } + configurator: Ipv4NetworkConfigurator { + parameters: + @display("p=100,200;is=s"); + config = xmldoc("IPv4Config.xml"); + addStaticRoutes = false; + addDefaultRoutes = false; + addSubnetRoutes = false; + } + scenarioManager: ScenarioManager { + parameters: + @display("p=100,300;is=s"); + } + A: BgpRouter { + parameters: + hasStatus = true; + @display("p=400,100"); + gates: + pppg[1]; + ethg[1]; + } + B: BgpRouter { + parameters: + hasStatus = true; + @display("p=550,100"); + gates: + pppg[1]; + ethg[1]; + } + H1: StandardHost { + parameters: + @display("p=250,100;i=device/laptop"); + gates: + ethg[1]; + } + H2: StandardHost { + parameters: + @display("p=700,100;i=device/laptop"); + gates: + ethg[1]; + } + connections: + H1.ethg[0] <--> LINK_100 <--> A.ethg[0]; + A.pppg[0] <--> LINK_100 <--> B.pppg[0]; + B.ethg[0] <--> LINK_100 <--> H2.ethg[0]; +} diff --git a/examples/bgpv4/BgpLifecycle/OSPFConfig.xml b/examples/bgpv4/BgpLifecycle/OSPFConfig.xml new file mode 100644 index 00000000000..cf898770919 --- /dev/null +++ b/examples/bgpv4/BgpLifecycle/OSPFConfig.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/bgpv4/BgpLifecycle/network.jpg b/examples/bgpv4/BgpLifecycle/network.jpg new file mode 100644 index 0000000000000000000000000000000000000000..54518d865cf2a15092c3a690343ad3b8b0e8c6f4 GIT binary patch literal 7395 zcmeHLXHb*tw*DYA=^g1{sM16QL@5G>5E1FU2m;bOp(8~_igW=1300{9(S(llE+8#n zP>|lFBOP+%J~QXsyZ62``|f*wo^NLT_~w0P&3aaQ-?eZPxbFb%T~(MWKtMnM{Py7{ z0TqCRh?sD_05<>-5aX@=r@{DtLJ;0wQnCx=6nFrd79b=5fe48}#Kc5I_|stgIY2~5OwTK+ zM8cqLMS97D@oHFNE*V(4vV}=!Xp8UKL(lLFZXk=_+ZDae$&fdY%%Ny?F>*pWvVAV zO=pYgq2~}eGvDg*o@P|jY-7n;lKT#G3c}kihBvRRnd1CM(gnR7s!|+q;ZQ^~>{0y|<_U+3s21of zldi9Ojg6Y6{%XAQZig`rc*@fHU{Aze@lfJ94u~qZHrhgt{hX@JVwUC2n5BrK`~W^f zTi3?v()OHvm+ZXFK)jP44Zg1Na<2qfQk)^)N;@OR(wtMw;DA~CKWK}K{txIsF8EIt zl>dnfoJhOQDYqIc!sK8cE;EhHtg|DoHgRe{9vZ09Nm7!Th11AZD3yE7LQj*M7;(VF zejDHXVgHo{{*tcl~ z4#^M~ug5!&7L86@DD5*}J?rk{0(zPU{5z?U9tgQ{?lzOSY$SwyU|-sIx9nbrN=hV$ zjdu>Yf(T|@DQOWi-5FcFiaEG~mCkmta~0U-zo8{_h1?L5sQ{E z{&;y2iCNA!4H=r)ndchA<>Icqi0zGww?|5(w>~`&-AT*k$`Jl z(@hfIaOS%$4vz1m&o5u#_jGSdaCi4WTnlS7V`&r9M%N?N^^znRrc5RVtVwy*mG57h zM*5;di5azT|84QgrdPxVq42!L@WC;EDLx4QmM|Hh8>{OOJM8{4J$6Fj9;nzjZ9Wj9 zNi@>$=g)q?xZKxdLe6R?TTUWH5Sx3eQ-y)q=bYCx-rAf=Z|wS{yulC>&Te1s(nIwg z(oN(I{v5A;n@a+ocbMPuz(E>=IjA!py*Dz*=)&JWk-lR?*Lmd`2?1a^7b;D1-w}WPlhpSRgnjnwa9#2%uniK@ECf#lI_onQ@37daV&Av05Tj?Z_))#hWLh!nF@l6?=C z?SDjsGH^{tt{i8L^`m3EGNr15#wPlz>HAo8NFMv~bA?rh`R$B+}&PX8}P(se#a zH{TM+XzcJ5=Y#ut(K>*AhRBT#KJQ3>PtK2)kB$;4ZQc%FP)LCQev^t(e0p6 z&Yk!CC_DceBDDymQ&|PAq6U_H$F;oWDxJ5;La2DIqxdJ@887nX%2JXWy%n#*E_{#R zU~(thCl>+@I4h#Z^@iz}PW+!58cJ`6H3%l9>6F}(>}}dGxH1(YUdAQ33nE>DlfnB1 zo9j3c*<47w;I|GBY9(6&eMT&bcxOczp6VMyu(mV|qE9R*3KfR%K4{4BsVCkj!mNZ? zJ4g+k+*@&S|6z6FS~Ta_+9P6%_ska5#=j@O&y(e~*N2HXfN!%yai6>n2MmebCjDKa z;1O=W5Utbu#(#f_sfDD9}_0q&JVSl{b)qn}d4BFqP}^Ac z9pk)c;eT8_+Gc}PNK`e;)hjv~<(n5DK#mn-$J`Gt^g5s|5Pu)Bd(Weq0fX#AZp(_5f z-xS7u(>Yr}#pE?-8irNd`(an8_(u~|?@vq4JTg1BRVrsO1WBS&(*#;|7a{u*vwkhh zYP^v+zzGCS&@>s?2Cv@yVo;AkCHV_3M@(q17DqO}ftf!FpSDh=ZZ#-i3$yL77= z9L7@*VAH+s9llMbBc57Q^-E zp?uD)=4#!RP$IekdqUmNH?K;H=09)%@-R69y@k;qv{_c zUfF$@foaZRev_`3dV4a{fhaq(Jdgle#%JQJ6(wzM42@6EYkWw`VX58#KQ<^~Gk=}j zehU>BvD;A>T)uhrRye5+lgDvJh0EMJp(UGoG0%&vkJhc9YWI4dn2DE@SUZS`YdkId z6thm%zWwBLf(qR^h6KukKxfTDN8#_0zDNhYEuE2d>KIxcOF}K4E)XkTnH_^f*(en4 zfQ^kSbQKt>5Zg#@dN~t)?7DZ%PvM43+G>Mlz0jU)@lZ)>bfxu#)ZFxR*MM8J=zrxX!F4 zdXMNsx2nI^GwAAU-Q`8pipF@%!i{G1`-$L#8ZZvHEj2ve|1hNl75^q*++Luyb})*2 z=l-cK4zMh(IHMmM8kgM$pTnl3Lw+#9aX_9)ZNJLzo|o`}AQ>ExM>EJ3Eql&LMAV}?Q|HTMhnCi$gRiPKEnYjXOB~oWy0iSiaKqFqwo0P0G-K~+#aLBR~1sm?_Mnw54hJ` z0M?O1GYti_?y2P>U9D;?n!to1g*&A;v%aR81b(?>wQ;wl<@{)Jn&|uM?G>{-2zEAu zysFu`b^7YB5nN{3k8f1m+p2yhZtW-j)8ClVnM*`J=ovV{=-`;<9PO>iZJ5&OycqXD z`Kr!S7wf>P5$6@LgtD;{%5ZJz8}Si=!#vP77Db6?u0z?Sc)aSGZI%h0-^+uZVpjkf5+%;I8%gDoWN-eBks9g$@v z7UVt@iY#Fs%n>}&X8UXoLvU%@Bjn3k z6J6a{k)dCJlN@NcsOz&vZ~3Ff=8QXxJL2C<38TB*&mMs zz~fK|Y}6}zE8a0=?}pR#!D1KwoxP0Trv&0_Gq=qG2Q*15p2nMVG7|KxTCg`I->-u; zs8?8Y4&6joBo=1N(R#iLbT5=wct|Su+AuRn_z*UmO+(>Sy2)(5qGtXkSh_iiG4%yy zZBSPO7ftuv!bR7ofk;Mz-RT&N>4T`cjP%7+JtM|XhcvvjsuY|#l!!whkbF;(Dj7~+ zcEZ8EnfLBA61<1pWcIt;*DfFuK}e-chZfX67*~X!-Cm{99$CqL;~q%LW9M?`q^}gtUJC#wsCLU+e#7q0eOrpwYa$o8_y74y_&(!2u1>J*Ksr z5l9FAq8GQGgL0KcqDE1Du^PSDT<2rLkQ6#3@o4(Y{C?CN_LDI43>zR{x-7I8_|2}x zrwYTia2_jS3gb?9tbCo?OuHm#vHWM)&fp*qR&`+!EH3%;T}E)>Z)uy%|ti`~`XTqH5qr*!HgYRWhEqrn|I^ zQX%vX0s612Wf;=IvA!}15oW)S7Pex zPt09=1<089If4&w8|wvALl-h;$M0+{7VUJET2;hwxiUg7y~Y84)`Ansd*!c&V?I3L z|M;TftrHu(Ti3Su4s7{-*7F^=?eb{szEQJi$=WE>=3Zw=mS;e9+nTA`RNyUiwAB1j z7ZA8qxO{o=sW-*sKE>NKBj|K}PzjAKCk_~Js$UyhS&=z@eYNl1@R;&c#$#xXpD2{JrfXO`REhjc2-0>V{UG@9H3_ciT^U=&nMdPZC+Ni9nh>+GGSU6&6fL`ty@Q@ z6&=0IG!Ufr>uQ_LJ|Q*_SxzmF`~Ce${8yjyQe)<<<|-nTw5m!>eXCO!M%)BWAc@JE z^`w{7s7ZpyPbJOu{h?16$EMW|P135QX(wnzdNSC%k__>&c0Tb{eW+E-Do8mY=Y`2| zaVGVjX`(W+m*oDyo3wxfFlMm6+RZ_$_0u)iT1CPy9fhl0qE%sqek1z#SeN|2F7}S@ zY^ZZJ4szZ!G*);2vyu3UoN2j6{-kLPyMu(p8!w*f=xg9t*6fRxIZv{lJVYRD5leIl;i_6w?zi7M~b>NND;AhCOVWjCOMiECcf=HcV<7I6hER~Xui|U<)G0l z&FGo{_O0W8jeQ(zW$We3|6?Ds-NyeZ{oA$6p=R^RNvZ*eMh)r7uM{Y42oL$cYrj!4 zG=YUO6=-9d6Ti&;=&lUqX?@8~x^-Gm!5PJQxu21MQA>p~Sx#Fu{@PK}`yvumEQ=S{ zl4DWN4`5vfKfV7NbpOA?#GpiB_NEQOinwk+teo#z$|Rce6G+j42ImjI$qT&-r=eO7 zcU(2 f^g<8yk1fF8nCh4R=HltEF0B4%0P$W7!F~BJ55mks literal 0 HcmV?d00001 diff --git a/examples/bgpv4/BgpLifecycle/omnetpp.ini b/examples/bgpv4/BgpLifecycle/omnetpp.ini new file mode 100644 index 00000000000..71f51353ff7 --- /dev/null +++ b/examples/bgpv4/BgpLifecycle/omnetpp.ini @@ -0,0 +1,53 @@ +[General] +description = "BGP lifecycle operations" +network = BgpNetwork +sim-time-limit = 900s +output-scalar-file = results.sca +output-scalar-precision = 5 + +**.app[0].**.scalar-recording = true +**.bgp.**.scalar-recording = true +**.scalar-recording = false +**.vector-recording = false + +# NIC configuration +**.eth[*].queue.packetCapacity = 100 + +#tcp settings +**.tcp.typename = "Tcp" +**.tcp.mss = 1024 +**.tcp.advertisedWindow = 14336 +**.tcp.tcpAlgorithmClass = "TcpReno" + +# OSPF configuration +**.ospfConfig = xmldoc("OSPFConfig.xml") + +# bgp settings +**.bgpConfig = xmldoc("BGPConfig.xml") +**.redistributeOspf = "O IA" + +# Visualizer settings +*.visualizer.interfaceTableVisualizer.displayInterfaceTables = true + +# UDPApp parameters +*.H*.numApps = 1 +**.app[0].messageLength = 32 bytes +**.app[0].sendInterval = 10s +**.app[0].startTime = 80s +**.app[0].destPort = 5678 + +**.H1.app[0].typename = "UdpBasicApp" +**.H1.app[0].localPort = 1234 +**.H1.app[0].destAddresses = "192.168.2.1" + +**.H2.app[0].typename="UdpSink" +**.H2.app[0].localPort = 5678 + +# Lifecycle operations: allow BGP sessions to establish, stop router A +# gracefully, restart it, then crash it later in the run. +*.scenarioManager.script = xml( \ + "") From bd5f2ec7145dbdb257dc2a55588bb4dcec385663 Mon Sep 17 00:00:00 2001 From: Giovanni Nardini Date: Mon, 22 Jun 2026 10:12:49 +0200 Subject: [PATCH 5/5] Add BGP lifecycle fingerprint coverage Register the BgpLifecycle example in the fingerprint suite so node shutdown, crash, and restart behavior stays covered by the BGP example tests. The new row records the full 900s lifecycle scenario fingerprint and tags it with lifecycle alongside the existing BGP/OSPF coverage. --- tests/fingerprint/examples.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fingerprint/examples.csv b/tests/fingerprint/examples.csv index 565090dcef5..7de4817851b 100644 --- a/tests/fingerprint/examples.csv +++ b/tests/fingerprint/examples.csv @@ -26,6 +26,7 @@ /examples/bgpv4/Bgp2RoutersInAS/, -f omnetpp.ini -c General -r 0, 1000s, 096d-ba3e/tplx;c504-7297/~tNl;c40f-3bef/~tND;21c2-3739/tyf, PASS, ospf EthernetMac Ipv4 /examples/bgpv4/Bgp3Routers/, -f omnetpp.ini -c General -r 0, 1000s, 0743-0419/tplx;2c93-b913/~tNl;abc7-4ccf/~tND;4ae7-55e4/tyf, PASS, ospf EthernetMac Ipv4 /examples/bgpv4/BgpCompleteTest/, -f omnetpp.ini -c General -r 0, 1000s, 1b55-5b10/tplx;a62e-572b/~tNl;ed1b-2f1f/~tND;06a0-ffe5/tyf, PASS, ospf EthernetMac Ipv4 +/examples/bgpv4/BgpLifecycle/, -f omnetpp.ini -c General -r 0, 900s, 66c3-9aef/tplx;ba07-f473/~tNl;39cb-270d/~tND;443b-48cc/tyf, PASS, ospf EthernetMac Ipv4 lifecycle /examples/bgpv4/BgpOpen/, -f omnetpp.ini -c General -r 0, 62s, f559-6038/tplx;9dce-698e/~tNl;400e-d43e/~tND;0f2b-99dc/tyf, PASS, ospf Ipv4 /examples/bgpv4/BgpUpdate/, -f omnetpp.ini -c General -r 0, 30s, c6af-84d3/tplx;3a06-a4f0/~tNl;3967-7b00/~tND;5cdf-d2f9/tyf, PASS, ospf EthernetMac Ipv4 /examples/bgpv4/BgpAndOspf/, -f omnetpp.ini -c General -r 0, 1000s, 136d-4446/tplx;7a5d-2469/~tNl;263a-e848/~tND;a746-abf9/tyf, PASS, ospf EthernetMac Ipv4