INET Framework for OMNeT++/OMNEST
inet::LDP Class Reference

LDP (rfc 3036) protocol implementation. More...

#include <LDP.h>

Inheritance diagram for inet::LDP:
inet::TCPSocket::CallbackInterface inet::IClassifier inet::ILifecycle

Classes

struct  fec_bind_t
 
struct  fec_t
 
struct  peer_info
 
struct  pending_req_t
 

Public Types

typedef std::vector< fec_tFecVector
 
typedef std::vector< fec_bind_tFecBindVector
 
typedef std::vector< pending_req_tPendingVector
 
typedef std::vector< peer_infoPeerVector
 

Public Member Functions

 LDP ()
 
virtual ~LDP ()
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
- Public Member Functions inherited from inet::TCPSocket::CallbackInterface
virtual ~CallbackInterface ()
 
virtual void socketDeleted (int connId, void *yourPtr)
 
- Public Member Functions inherited from inet::IClassifier
virtual ~IClassifier ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Member Functions

virtual IPv4Address locateNextHop (IPv4Address dest)
 This method finds next peer in upstream direction. More...
 
virtual IPv4Address findPeerAddrFromInterface (std::string interfaceName)
 This method maps the peerIP with the interface name in routing table. More...
 
std::string findInterfaceFromPeerAddr (IPv4Address peerIP)
 
virtual int findPeer (IPv4Address peerAddr)
 Utility: return peer's index in myPeers table, or -1 if not found. More...
 
virtual TCPSocketgetPeerSocket (IPv4Address peerAddr)
 Utility: return socket for given peer. More...
 
virtual TCPSocketfindPeerSocket (IPv4Address peerAddr)
 Utility: return socket for given peer, and nullptr if session doesn't exist. More...
 
virtual void sendToPeer (IPv4Address dest, cMessage *msg)
 
FecVector::iterator findFecEntry (FecVector &fecs, IPv4Address addr, int length)
 
FecBindVector::iterator findFecEntry (FecBindVector &fecs, int fecid, IPv4Address peer)
 
virtual void sendMappingRequest (IPv4Address dest, IPv4Address addr, int length)
 
virtual void sendMapping (int type, IPv4Address dest, int label, IPv4Address addr, int length)
 
virtual void sendNotify (int status, IPv4Address dest, IPv4Address addr, int length)
 
virtual void rebuildFecList ()
 
virtual void updateFecList (IPv4Address nextHop)
 
virtual void updateFecListEntry (fec_t oldItem)
 
virtual void announceLinkChange (int tedlinkindex)
 
virtual bool isNodeUp ()
 
virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void sendHelloTo (IPv4Address dest)
 
virtual void openTCPConnectionToPeer (int peerIndex)
 
virtual void processLDPHello (LDPHello *msg)
 
virtual void processHelloTimeout (cMessage *msg)
 
virtual void processMessageFromTCP (cMessage *msg)
 
virtual void processLDPPacketFromTCP (LDPPacket *ldpPacket)
 
virtual void processLABEL_MAPPING (LDPLabelMapping *packet)
 
virtual void processLABEL_REQUEST (LDPLabelRequest *packet)
 
virtual void processLABEL_RELEASE (LDPLabelMapping *packet)
 
virtual void processLABEL_WITHDRAW (LDPLabelMapping *packet)
 
virtual void processNOTIFICATION (LDPNotify *packet)
 
virtual bool lookupLabel (IPv4Datagram *ipdatagram, LabelOpVector &outLabel, std::string &outInterface, int &color) override
 The ipdatagram argument is an input parameter, the rest (outLabel, outInterface, color) are output parameters only. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
TCPSocket::CallbackInterface callback methods
virtual void socketEstablished (int connId, void *yourPtr) override
 
virtual void socketDataArrived (int connId, void *yourPtr, cPacket *msg, bool urgent) override
 
virtual void socketPeerClosed (int connId, void *yourPtr) override
 
virtual void socketClosed (int connId, void *yourPtr) override
 
virtual void socketFailure (int connId, void *yourPtr, int code) override
 
virtual void socketStatusArrived (int connId, void *yourPtr, TCPStatusInfo *status) override
 

Protected Attributes

simtime_t holdTime
 
simtime_t helloInterval
 
FecVector fecList
 
FecBindVector fecUp
 
FecBindVector fecDown
 
PendingVector pending
 
PeerVector myPeers
 
NodeStatusnodeStatus = nullptr
 
IInterfaceTableift = nullptr
 
IIPv4RoutingTablert = nullptr
 
LIBTablelt = nullptr
 
TEDtedmod = nullptr
 
UDPSocket udpSocket
 
std::vector< UDPSocketudpSockets
 
TCPSocket serverSocket
 
TCPSocketMap socketMap
 
cMessage * sendHelloMsg = nullptr
 
int maxFecid = 0
 

Detailed Description

LDP (rfc 3036) protocol implementation.

Member Typedef Documentation

typedef std::vector<fec_bind_t> inet::LDP::FecBindVector
typedef std::vector<fec_t> inet::LDP::FecVector
typedef std::vector<peer_info> inet::LDP::PeerVector

Constructor & Destructor Documentation

inet::LDP::LDP ( )
89 {
90 }
inet::LDP::~LDP ( )
virtual
93 {
94  for (auto & elem : myPeers)
95  cancelAndDelete(elem.timeout);
96 
97  cancelAndDelete(sendHelloMsg);
98  //this causes segfault at the end of simulation -- Vojta
99  //socketMap.deleteSockets();
100 }
PeerVector myPeers
Definition: LDP.h:110
cMessage * sendHelloMsg
Definition: LDP.h:127

Member Function Documentation

void inet::LDP::announceLinkChange ( int  tedlinkindex)
protectedvirtual

Referenced by processHelloTimeout(), and processLDPHello().

1232 {
1233  TEDChangeInfo d;
1234  d.setTedLinkIndicesArraySize(1);
1235  d.setTedLinkIndices(0, tedlinkindex);
1236  emit(NF_TED_CHANGED, &d);
1237 }
simsignal_t NF_TED_CHANGED
Definition: NotifierConsts.cc:55
LDP::FecVector::iterator inet::LDP::findFecEntry ( FecVector fecs,
IPv4Address  addr,
int  length 
)
protected

Referenced by lookupLabel(), processLABEL_MAPPING(), processLABEL_RELEASE(), processLABEL_REQUEST(), processLABEL_WITHDRAW(), processNOTIFICATION(), rebuildFecList(), and updateFecListEntry().

818 {
819  auto it = fecs.begin();
820  for ( ; it != fecs.end(); it++) {
821  if ((it->length == length) && (it->addr == addr)) // XXX compare only relevant part (?)
822  break;
823  }
824  return it;
825 }
LDP::FecBindVector::iterator inet::LDP::findFecEntry ( FecBindVector fecs,
int  fecid,
IPv4Address  peer 
)
protected
808 {
809  auto it = fecs.begin();
810  for (; it != fecs.end(); it++) {
811  if ((it->fecid == fecid) && (it->peer == peer))
812  break;
813  }
814  return it;
815 }
std::string inet::LDP::findInterfaceFromPeerAddr ( IPv4Address  peerIP)
protected

Referenced by lookupLabel(), processLABEL_MAPPING(), processLABEL_REQUEST(), and updateFecListEntry().

780 {
781 /*
782  int i;
783  for (unsigned int i=0;i<myPeers.size();i++)
784  {
785  if (myPeers[i].peerIP == peerIP)
786  return string(myPeers[i].linkInterface);
787  }
788  return string("X");
789  */
790 // Rely on port index to find the interface name
791 
792  // this function is a misnomer, we must recognize our own address too
793  if (rt->isLocalAddress(peerIP))
794  return "lo0";
795 
796  InterfaceEntry *ie = rt->getInterfaceForDestAddr(peerIP);
797  if (!ie)
798  throw cRuntimeError("findInterfaceFromPeerAddr(): %s is not routable", peerIP.str().c_str());
799  return ie->getName();
800 }
virtual InterfaceEntry * getInterfaceForDestAddr(const IPv4Address &dest) const =0
Convenience function based on findBestMatchingRoute().
IIPv4RoutingTable * rt
Definition: LDP.h:117
virtual bool isLocalAddress(const IPv4Address &dest) const =0
Checks if the address is a local one, i.e.
int inet::LDP::findPeer ( IPv4Address  peerAddr)
protectedvirtual

Utility: return peer's index in myPeers table, or -1 if not found.

Referenced by findPeerSocket(), processLDPHello(), and processMessageFromTCP().

1148 {
1149  for (auto i = myPeers.begin(); i != myPeers.end(); ++i)
1150  if (i->peerIP == peerAddr)
1151  return i - myPeers.begin();
1152 
1153  return -1;
1154 }
PeerVector myPeers
Definition: LDP.h:110
IPv4Address inet::LDP::findPeerAddrFromInterface ( std::string  interfaceName)
protectedvirtual

This method maps the peerIP with the interface name in routing table.

It is expected that for MPLS host, entries linked to MPLS peers are available. In case no corresponding peerIP found, a peerIP (not deterministic) will be returned.

Referenced by locateNextHop().

746 {
747  int i = 0;
748  int k = 0;
749  InterfaceEntry *ie = ift->getInterfaceByName(interfaceName.c_str());
750 
751  const IPv4Route *anEntry;
752 
753  for (i = 0; i < rt->getNumRoutes(); i++) {
754  for (k = 0; k < (int)myPeers.size(); k++) {
755  anEntry = rt->getRoute(i);
756  if (anEntry->getDestination() == myPeers[k].peerIP && anEntry->getInterface() == ie) {
757  return myPeers[k].peerIP;
758  }
759  // addresses->push_back(peerIP[k]);
760  }
761  }
762 
763  // Return any IP which has default route - not in routing table entries
764  for (i = 0; i < (int)myPeers.size(); i++) {
765  for (k = 0; k < rt->getNumRoutes(); k++) {
766  anEntry = rt->getRoute(i);
767  if (anEntry->getDestination() == myPeers[i].peerIP)
768  break;
769  }
770  if (k == rt->getNumRoutes())
771  break;
772  }
773 
774  // return the peer's address if found, unspecified address otherwise
775  return i == (int)myPeers.size() ? IPv4Address() : myPeers[i].peerIP;
776 }
virtual IPv4Route * getRoute(int k) const override=0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
virtual InterfaceEntry * getInterfaceByName(const char *name) const =0
Returns an interface given by its name.
IInterfaceTable * ift
Definition: LDP.h:116
IIPv4RoutingTable * rt
Definition: LDP.h:117
PeerVector myPeers
Definition: LDP.h:110
const double k
Definition: QAM16Modulation.cc:24
TCPSocket * inet::LDP::findPeerSocket ( IPv4Address  peerAddr)
protectedvirtual

Utility: return socket for given peer, and nullptr if session doesn't exist.

Referenced by getPeerSocket(), processLABEL_REQUEST(), and updateFecListEntry().

1157 {
1158  // find peer in table and return its socket
1159  int i = findPeer(peerAddr);
1160  if (i == -1 || !(myPeers[i].socket) || myPeers[i].socket->getState() != TCPSocket::CONNECTED)
1161  return nullptr; // we don't have an LDP session to this peer
1162  return myPeers[i].socket;
1163 }
Definition: TCPSocket.h:148
PeerVector myPeers
Definition: LDP.h:110
virtual int findPeer(IPv4Address peerAddr)
Utility: return peer&#39;s index in myPeers table, or -1 if not found.
Definition: LDP.cc:1147
TCPSocket * inet::LDP::getPeerSocket ( IPv4Address  peerAddr)
protectedvirtual

Utility: return socket for given peer.

Throws error if there's no TCP connection

Referenced by sendToPeer().

1166 {
1167  TCPSocket *sock = findPeerSocket(peerAddr);
1168  ASSERT(sock);
1169  if (!sock)
1170  throw cRuntimeError("No LDP session to peer %s yet", peerAddr.str().c_str());
1171  return sock;
1172 }
virtual TCPSocket * findPeerSocket(IPv4Address peerAddr)
Utility: return socket for given peer, and nullptr if session doesn&#39;t exist.
Definition: LDP.cc:1156
void inet::LDP::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
165 {
166  if (!isNodeUp())
167  throw cRuntimeError("LDP is not running");
168  EV_INFO << "Received: (" << msg->getClassName() << ")" << msg->getName() << "\n";
169  if (msg == sendHelloMsg) {
170  // every LDP capable router periodically sends HELLO messages to the
171  // "all routers in the sub-network" multicast address
172  EV_INFO << "Multicasting LDP Hello to neighboring routers\n";
174 
175  // schedule next hello
176  scheduleAt(simTime() + helloInterval, sendHelloMsg);
177  }
178  else if (msg->isSelfMessage()) {
179  EV_INFO << "Timer " << msg->getName() << " expired\n";
180  if (!strcmp(msg->getName(), "HelloTimeout")) {
181  processHelloTimeout(msg);
182  }
183  else {
184  processNOTIFICATION(check_and_cast<LDPNotify *>(msg));
185  }
186  }
187  else if (!strcmp(msg->getArrivalGate()->getName(), "udpIn")) {
188  // we can only receive LDP Hello from UDP (everything else goes over TCP)
189  processLDPHello(check_and_cast<LDPHello *>(msg));
190  }
191  else if (!strcmp(msg->getArrivalGate()->getName(), "tcpIn")) {
193  }
194 }
simtime_t helloInterval
Definition: LDP.h:98
virtual void processHelloTimeout(cMessage *msg)
Definition: LDP.cc:441
virtual bool isNodeUp()
Definition: LDP.cc:220
virtual void processMessageFromTCP(cMessage *msg)
Definition: LDP.cc:578
virtual void processNOTIFICATION(LDPNotify *packet)
Definition: LDP.cc:865
virtual void processLDPHello(LDPHello *msg)
Definition: LDP.cc:509
virtual void sendHelloTo(IPv4Address dest)
Definition: LDP.cc:419
cMessage * sendHelloMsg
Definition: LDP.h:127
static const IPv4Address ALL_ROUTERS_MCAST
224.0.0.2 All routers on a subnet
Definition: IPv4Address.h:108
bool inet::LDP::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overridevirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

197 {
198  Enter_Method_Silent();
199  if (dynamic_cast<NodeStartOperation *>(operation)) {
201  scheduleAt(simTime() + exponential(0.1), sendHelloMsg);
202  }
203  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
205  for (auto & elem : myPeers)
206  cancelAndDelete(elem.timeout);
207  myPeers.clear();
208  cancelEvent(sendHelloMsg);
209  }
210  }
211  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
213  }
214  }
215  else
216  throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
217  return true;
218 }
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
PeerVector myPeers
Definition: LDP.h:110
Stage
Definition: NodeOperations.h:46
cMessage * sendHelloMsg
Definition: LDP.h:127
Definition: NodeOperations.h:127
void inet::LDP::initialize ( int  stage)
overrideprotectedvirtual
103 {
104  cSimpleModule::initialize(stage);
105 
106  //FIXME move bind() and listen() calls to a new startModule() function, and call it from initialize() and from handleOperationStage()
107  //FIXME register to InterfaceEntry changes, for detecting the interface add/delete, and detecting multicast config changes:
108  // should be refresh the udpSockets vector when interface added/deleted, or isMulticast() value changed.
109 
110  if (stage == INITSTAGE_LOCAL) {
111  holdTime = par("holdTime").doubleValue();
112  helloInterval = par("helloInterval").doubleValue();
113 
114  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
115  rt = getModuleFromPar<IIPv4RoutingTable>(par("routingTableModule"), this);
116  lt = getModuleFromPar<LIBTable>(par("libTableModule"), this);
117  tedmod = getModuleFromPar<TED>(par("tedModule"), this);
118 
119  WATCH_VECTOR(myPeers);
120  WATCH_VECTOR(fecUp);
121  WATCH_VECTOR(fecDown);
122  WATCH_VECTOR(fecList);
123  WATCH_VECTOR(pending);
124 
125  maxFecid = 0;
126  }
127  else if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
128  // schedule first hello
129  sendHelloMsg = new cMessage("LDPSendHello");
130  nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
131  if (isNodeUp())
132  scheduleAt(simTime() + exponential(0.1), sendHelloMsg);
133 
134  // bind UDP socket
135  udpSocket.setOutputGate(gate("udpOut"));
137  for (int i = 0; i < ift->getNumInterfaces(); ++i) {
138  InterfaceEntry *ie = ift->getInterface(i);
139  if (ie->isMulticast()) {
140  udpSockets.push_back(UDPSocket());
141  udpSockets.back().setOutputGate(gate("udpOut"));
142  udpSockets.back().setMulticastLoop(false);
143  udpSockets.back().setMulticastOutputInterface(ie->getInterfaceId());
144  }
145  }
146 
147  // start listening for incoming TCP conns
148  EV_INFO << "Starting to listen on port " << LDP_PORT << " for incoming LDP sessions\n";
149  serverSocket.setOutputGate(gate("tcpOut"));
151  serverSocket.bind(LDP_PORT);
153 
154  // build list of recognized FECs
155  rebuildFecList();
156 
157  // listen for routing table modifications
158  cModule *host = getContainingNode(this);
159  host->subscribe(NF_ROUTE_ADDED, this);
160  host->subscribe(NF_ROUTE_DELETED, this);
161  }
162 }
simsignal_t NF_ROUTE_DELETED
Definition: NotifierConsts.cc:58
simtime_t helloInterval
Definition: LDP.h:98
UDPSocket udpSocket
Definition: LDP.h:121
virtual bool isNodeUp()
Definition: LDP.cc:220
IInterfaceTable * ift
Definition: LDP.h:116
std::vector< UDPSocket > udpSockets
Definition: LDP.h:122
simtime_t holdTime
Definition: LDP.h:97
Initialization of routing protocols.
Definition: InitStages.h:101
IIPv4RoutingTable * rt
Definition: LDP.h:117
void setOutputGate(cGate *toUdp)
Sets the gate on which to send to UDP.
Definition: UDPSocket.h:110
TED * tedmod
Definition: LDP.h:119
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
void bind(int localPort)
Bind the socket to a local port number.
Definition: TCPSocket.cc:101
Local initializations.
Definition: InitStages.h:35
NodeStatus * nodeStatus
Definition: LDP.h:115
virtual void rebuildFecList()
Definition: LDP.cc:301
PeerVector myPeers
Definition: LDP.h:110
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:65
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
PendingVector pending
Definition: LDP.h:107
TCPSocket serverSocket
Definition: LDP.h:123
simsignal_t NF_ROUTE_ADDED
Definition: NotifierConsts.cc:57
FecBindVector fecDown
Definition: LDP.h:105
int maxFecid
Definition: LDP.h:129
#define LDP_PORT
Definition: LDP.h:35
void listen(bool fork)
Definition: TCPSocket.cc:127
void setOutputGate(cGate *toTcp)
Sets the gate on which to send to TCP.
Definition: TCPSocket.h:228
void readDataTransferModePar(cComponent &component)
Read "dataTransferMode" parameter from ini/ned, and set dataTransferMode member value.
Definition: TCPSocket.cc:355
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
FecVector fecList
Definition: LDP.h:101
cMessage * sendHelloMsg
Definition: LDP.h:127
void bind(int localPort)
Bind the socket to a local port number.
Definition: UDPSocket.cc:53
bool inet::LDP::isNodeUp ( )
protectedvirtual

Referenced by handleMessage(), and initialize().

221 {
222  return !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
223 }
NodeStatus * nodeStatus
Definition: LDP.h:115
virtual State getState() const
Definition: NodeStatus.h:48
Definition: NodeStatus.h:40
IPv4Address inet::LDP::locateNextHop ( IPv4Address  dest)
protectedvirtual

This method finds next peer in upstream direction.

712 {
713  // Mapping L3 IP-host of next hop to L2 peer address.
714 
715  // Lookup the routing table, rfc3036
716  // "When the FEC for which a label is requested is a Prefix FEC Element or
717  // a Host Address FEC Element, the receiving LSR uses its routing table to determine
718  // its response. Unless its routing table includes an entry that exactly matches
719  // the requested Prefix or Host Address, the LSR must respond with a
720  // No Route Notification message."
721  //
722  // FIXME the code below (though seems like that's what the RFC refers to) doesn't work
723  // -- we can't reasonably expect the destination host to be exaplicitly in an
724  // LSR's routing table!!! Use simple IP routing instead. --Andras
725  //
726  // Wrong code:
727  //int i;
728  //for (i=0; i < rt->getNumRoutes(); i++)
729  // if (rt->getRoute(i)->host == dest)
730  // break;
731  //
732  //if (i == rt->getNumRoutes())
733  // return IPv4Address(); // Signal an NOTIFICATION of NO ROUTE
734  //
735  InterfaceEntry *ie = rt->getInterfaceForDestAddr(dest);
736  if (!ie)
737  return IPv4Address(); // no route
738 
739  std::string iName = ie->getName(); // FIXME why use name for lookup?
740  return findPeerAddrFromInterface(iName);
741 }
virtual InterfaceEntry * getInterfaceForDestAddr(const IPv4Address &dest) const =0
Convenience function based on findBestMatchingRoute().
virtual IPv4Address findPeerAddrFromInterface(std::string interfaceName)
This method maps the peerIP with the interface name in routing table.
Definition: LDP.cc:745
IIPv4RoutingTable * rt
Definition: LDP.h:117
bool inet::LDP::lookupLabel ( IPv4Datagram ipdatagram,
LabelOpVector outLabel,
std::string &  outInterface,
int &  color 
)
overrideprotectedvirtual

The ipdatagram argument is an input parameter, the rest (outLabel, outInterface, color) are output parameters only.

In subclasses, this function should be implemented to determine the forwarding equivalence class for the IPv4 datagram passed, and map it to an outLabel and outInterface.

The color parameter (which can be set to an arbitrary value) will only be used for the NAM trace if one will be recorded.

Implements inet::IClassifier.

1175 {
1176  IPv4Address destAddr = ipdatagram->getDestAddress();
1177  int protocol = ipdatagram->getTransportProtocol();
1178 
1179  // never match and always route via L3 if:
1180 
1181  // OSPF traffic (TED)
1182  if (protocol == IP_PROT_OSPF)
1183  return false;
1184 
1185  // LDP traffic (both discovery...
1186  if (protocol == IP_PROT_UDP && check_and_cast<UDPPacket *>(ipdatagram->getEncapsulatedPacket())->getDestinationPort() == LDP_PORT)
1187  return false;
1188 
1189  // ...and session)
1190  if (protocol == IP_PROT_TCP && check_and_cast<tcp::TCPSegment *>(ipdatagram->getEncapsulatedPacket())->getDestPort() == LDP_PORT)
1191  return false;
1192  if (protocol == IP_PROT_TCP && check_and_cast<tcp::TCPSegment *>(ipdatagram->getEncapsulatedPacket())->getSrcPort() == LDP_PORT)
1193  return false;
1194 
1195  // regular traffic, classify, label etc.
1196 
1197  for (auto & elem : fecList) {
1198  if (!destAddr.prefixMatches(elem.addr, elem.length))
1199  continue;
1200 
1201  EV_DETAIL << "FEC matched: " << elem << endl;
1202 
1203  auto dit = findFecEntry(fecDown, elem.fecid, elem.nextHop);
1204  if (dit != fecDown.end()) {
1205  outLabel = LIBTable::pushLabel(dit->label);
1206  outInterface = findInterfaceFromPeerAddr(elem.nextHop);
1207  color = LDP_USER_TRAFFIC;
1208  EV_DETAIL << "mapping found, outLabel=" << outLabel << ", outInterface=" << outInterface << endl;
1209  return true;
1210  }
1211  else {
1212  EV_DETAIL << "no mapping for this FEC exists" << endl;
1213  return false;
1214  }
1215  }
1216  return false;
1217 }
#define LDP_USER_TRAFFIC
Definition: LDP.h:39
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
uint8_t protocol
Definition: TCP_NSC.cc:88
Definition: IPProtocolId_m.h:89
std::string findInterfaceFromPeerAddr(IPv4Address peerIP)
Definition: LDP.cc:779
FecBindVector fecDown
Definition: LDP.h:105
Definition: IPProtocolId_m.h:80
#define LDP_PORT
Definition: LDP.h:35
Definition: IPProtocolId_m.h:83
FecVector fecList
Definition: LDP.h:101
static LabelOpVector pushLabel(int label)
Definition: LIBTable.cc:163
virtual int inet::LDP::numInitStages ( ) const
inlineoverrideprotectedvirtual
183 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::LDP::openTCPConnectionToPeer ( int  peerIndex)
protectedvirtual

Referenced by processLDPHello().

566 {
567  TCPSocket *socket = new TCPSocket();
568  socket->setOutputGate(gate("tcpOut"));
569  socket->setCallbackObject(this, (void *)((intptr_t)peerIndex));
570  socket->readDataTransferModePar(*this);
571  socket->bind(rt->getRouterId(), 0);
572  socketMap.addSocket(socket);
573  myPeers[peerIndex].socket = socket;
574 
575  socket->connect(myPeers[peerIndex].peerIP, LDP_PORT);
576 }
IIPv4RoutingTable * rt
Definition: LDP.h:117
TCPSocketMap socketMap
Definition: LDP.h:124
virtual IPv4Address getRouterId() const =0
Returns routerId.
PeerVector myPeers
Definition: LDP.h:110
void addSocket(TCPSocket *socket)
Registers the given socket.
Definition: TCPSocketMap.cc:36
#define LDP_PORT
Definition: LDP.h:35
void inet::LDP::processHelloTimeout ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

442 {
443  // peer is gone
444 
445  unsigned int i;
446  for (i = 0; i < myPeers.size(); i++)
447  if (myPeers[i].timeout == msg)
448  break;
449 
450  ASSERT(i < myPeers.size());
451 
452  IPv4Address peerIP = myPeers[i].peerIP;
453 
454  EV_INFO << "peer=" << peerIP << " is gone, removing adjacency" << endl;
455 
456  ASSERT(!myPeers[i].timeout->isScheduled());
457  delete myPeers[i].timeout;
458  ASSERT(myPeers[i].socket);
459  myPeers[i].socket->abort(); // should we only close?
460  delete myPeers[i].socket;
461  myPeers.erase(myPeers.begin() + i);
462 
463  EV_INFO << "removing (stale) bindings from fecDown for peer=" << peerIP << endl;
464 
465  for (auto dit = fecDown.begin(); dit != fecDown.end(); ) {
466  if (dit->peer != peerIP) {
467  dit++;
468  continue;
469  }
470 
471  EV_DETAIL << "label=" << dit->label << endl;
472 
473  // send release message just in case (?)
474  // what happens if peer is not really down and
475  // hello messages just disappeared?
476  // does the protocol recover on its own (XXX check this)
477 
478  dit = fecDown.erase(dit);
479  }
480 
481  EV_INFO << "removing bindings from sent to peer=" << peerIP << " from fecUp" << endl;
482 
483  for (auto uit = fecUp.begin(); uit != fecUp.end(); ) {
484  if (uit->peer != peerIP) {
485  uit++;
486  continue;
487  }
488 
489  EV_DETAIL << "label=" << uit->label << endl;
490 
491  // send withdraw message just in case (?)
492  // see comment above...
493 
494  uit = fecUp.erase(uit);
495  }
496 
497  EV_INFO << "updating fecList" << endl;
498 
499  updateFecList(peerIP);
500 
501  // update TED and routing table
502 
503  unsigned int index = tedmod->linkIndex(rt->getRouterId(), peerIP);
504  tedmod->ted[index].state = false;
505  announceLinkChange(index);
507 }
virtual unsigned int linkIndex(IPv4Address localInf)
Definition: TED.cc:429
virtual void rebuildRoutingTable()
Definition: TED.cc:230
IIPv4RoutingTable * rt
Definition: LDP.h:117
TED * tedmod
Definition: LDP.h:119
FecBindVector fecUp
Definition: LDP.h:103
virtual IPv4Address getRouterId() const =0
Returns routerId.
PeerVector myPeers
Definition: LDP.h:110
virtual void updateFecList(IPv4Address nextHop)
Definition: LDP.cc:409
FecBindVector fecDown
Definition: LDP.h:105
TELinkStateInfoVector ted
The link state database.
Definition: TED.h:64
virtual void announceLinkChange(int tedlinkindex)
Definition: LDP.cc:1231
void inet::LDP::processLABEL_MAPPING ( LDPLabelMapping packet)
protectedvirtual

Referenced by processLDPPacketFromTCP().

1090 {
1091  FEC_TLV fec = packet->getFec();
1092  int label = packet->getLabel();
1093  IPv4Address fromIP = packet->getSenderAddress();
1094 
1095  EV_INFO << "Label mapping label=" << label << " received for fec=" << fec << " from " << fromIP << endl;
1096 
1097  ASSERT(label > 0);
1098 
1099  auto it = findFecEntry(fecList, fec.addr, fec.length);
1100  if (it == fecList.end())
1101  throw cRuntimeError("Model error: fec not in fecList");
1102 
1103  auto dit = findFecEntry(fecDown, it->fecid, fromIP);
1104  if (dit != fecDown.end())
1105  throw cRuntimeError("Model error: found in fecDown");
1106 
1107  // insert among received mappings
1108 
1109  fec_bind_t newItem;
1110  newItem.fecid = it->fecid;
1111  newItem.peer = fromIP;
1112  newItem.label = label;
1113  fecDown.push_back(newItem);
1114 
1115  // respond to pending requests
1116 
1117  for (auto pit = pending.begin(); pit != pending.end(); ) {
1118  if (pit->fecid != it->fecid) {
1119  pit++;
1120  continue;
1121  }
1122 
1123  EV_DETAIL << "there's pending request for this FEC from " << pit->peer << ", sending mapping" << endl;
1124 
1125  std::string inInterface = findInterfaceFromPeerAddr(pit->peer);
1126  std::string outInterface = findInterfaceFromPeerAddr(fromIP);
1127  LabelOpVector outLabel = LIBTable::swapLabel(label);
1128 
1129  fec_bind_t newItem;
1130  newItem.fecid = it->fecid;
1131  newItem.peer = pit->peer;
1132  newItem.label = lt->installLibEntry(-1, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
1133  fecUp.push_back(newItem);
1134 
1135  EV_DETAIL << "installed LIB entry inLabel=" << newItem.label << " inInterface=" << inInterface
1136  << " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
1137 
1138  sendMapping(LABEL_MAPPING, pit->peer, newItem.label, it->addr, it->length);
1139 
1140  // remove request from the list
1141  pit = pending.erase(pit);
1142  }
1143 
1144  delete packet;
1145 }
virtual void sendMapping(int type, IPv4Address dest, int label, IPv4Address addr, int length)
Definition: LDP.cc:846
#define LDP_USER_TRAFFIC
Definition: LDP.h:39
std::vector< LabelOp > LabelOpVector
Definition: LIBTable.h:44
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
Definition: LDPPacket_m.h:74
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
std::string findInterfaceFromPeerAddr(IPv4Address peerIP)
Definition: LDP.cc:779
static LabelOpVector swapLabel(int label)
Definition: LIBTable.cc:173
PendingVector pending
Definition: LDP.h:107
FecBindVector fecDown
Definition: LDP.h:105
virtual int installLibEntry(int inLabel, std::string inInterface, const LabelOpVector &outLabel, std::string outInterface, int color)
Definition: LIBTable.cc:64
FecVector fecList
Definition: LDP.h:101
void inet::LDP::processLABEL_RELEASE ( LDPLabelMapping packet)
protectedvirtual

Referenced by processLDPPacketFromTCP().

1010 {
1011  FEC_TLV fec = packet->getFec();
1012  int label = packet->getLabel();
1013  IPv4Address fromIP = packet->getSenderAddress();
1014 
1015  EV_INFO << "Mapping release received for label=" << label << " fec=" << fec << " from " << fromIP << endl;
1016 
1017  ASSERT(label > 0);
1018 
1019  // remove label from fecUp
1020 
1021  auto it = findFecEntry(fecList, fec.addr, fec.length);
1022  if (it == fecList.end()) {
1023  EV_INFO << "FEC no longer recognized here, ignoring" << endl;
1024  delete packet;
1025  return;
1026  }
1027 
1028  auto uit = findFecEntry(fecUp, it->fecid, fromIP);
1029  if (uit == fecUp.end() || label != uit->label) {
1030  // this is ok and may happen; e.g. we removed the mapping because downstream
1031  // neighbour withdrew its mapping. we sent withdraw upstream as well and
1032  // this is upstream's response
1033  EV_INFO << "mapping not found among sent mappings, ignoring" << endl;
1034  delete packet;
1035  return;
1036  }
1037 
1038  EV_DETAIL << "removing from LIB table label=" << uit->label << endl;
1039  lt->removeLibEntry(uit->label);
1040 
1041  EV_DETAIL << "removing label from list of sent mappings" << endl;
1042  fecUp.erase(uit);
1043 
1044  delete packet;
1045 }
virtual void removeLibEntry(int inLabel)
Definition: LIBTable.cc:93
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
FecVector fecList
Definition: LDP.h:101
void inet::LDP::processLABEL_REQUEST ( LDPLabelRequest packet)
protectedvirtual

Referenced by processLDPPacketFromTCP().

920 {
921  FEC_TLV fec = packet->getFec();
922  IPv4Address srcAddr = packet->getSenderAddress();
923 
924  EV_INFO << "Label Request from LSR " << srcAddr << " for FEC " << fec << endl;
925 
926  auto it = findFecEntry(fecList, fec.addr, fec.length);
927  if (it == fecList.end()) {
928  EV_DETAIL << "FEC not recognized, sending back No route message" << endl;
929 
930  sendNotify(NO_ROUTE, srcAddr, fec.addr, fec.length);
931 
932  delete packet;
933  return;
934  }
935 
936  // do we already have mapping for this fec from our downstream peer?
937 
938  //
939  // XXX this code duplicates rebuildFecList
940  //
941 
942  // does upstream have mapping from us?
943  auto uit = findFecEntry(fecUp, it->fecid, srcAddr);
944 
945  // shouldn't!
946  ASSERT(uit == fecUp.end());
947 
948  // do we have mapping from downstream?
949  auto dit = findFecEntry(fecDown, it->fecid, it->nextHop);
950 
951  // is next hop our LDP peer?
952  bool ER = !findPeerSocket(it->nextHop);
953 
954  ASSERT(!(ER && dit != fecDown.end())); // can't be egress and have mapping at the same time
955 
956  if (ER || dit != fecDown.end()) {
957  fec_bind_t newItem;
958  newItem.fecid = it->fecid;
959  newItem.label = -1;
960  newItem.peer = srcAddr;
961  fecUp.push_back(newItem);
962  uit = fecUp.end() - 1;
963  }
964 
965  std::string inInterface = findInterfaceFromPeerAddr(srcAddr);
966  std::string outInterface = findInterfaceFromPeerAddr(it->nextHop);
967 
968  if (ER) {
969  // we are egress, that's easy:
970  LabelOpVector outLabel = LIBTable::popLabel();
971 
972  uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, 0);
973 
974  EV_DETAIL << "installed (egress) LIB entry inLabel=" << uit->label << " inInterface=" << inInterface
975  << " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
976 
977  // We are egress, let our upstream peer know
978  // about it by sending back a Label Mapping message
979 
980  sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
981  }
982  else if (dit != fecDown.end()) {
983  // we have mapping from DS, that's easy
984  LabelOpVector outLabel = LIBTable::swapLabel(dit->label);
985  uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
986 
987  EV_DETAIL << "installed LIB entry inLabel=" << uit->label << " inInterface=" << inInterface
988  << " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
989 
990  // We already have a mapping for this FEC, let our upstream peer know
991  // about it by sending back a Label Mapping message
992 
993  sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
994  }
995  else {
996  // no mapping from DS, mark as pending
997 
998  EV_DETAIL << "no mapping for this FEC from the downstream router, marking as pending" << endl;
999 
1000  pending_req_t newItem;
1001  newItem.fecid = it->fecid;
1002  newItem.peer = srcAddr;
1003  pending.push_back(newItem);
1004  }
1005 
1006  delete packet;
1007 }
virtual void sendMapping(int type, IPv4Address dest, int label, IPv4Address addr, int length)
Definition: LDP.cc:846
#define LDP_USER_TRAFFIC
Definition: LDP.h:39
std::vector< LabelOp > LabelOpVector
Definition: LIBTable.h:44
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
Definition: LDPPacket_m.h:74
static LabelOpVector popLabel()
Definition: LIBTable.cc:183
Definition: LDPPacket_m.h:92
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
std::string findInterfaceFromPeerAddr(IPv4Address peerIP)
Definition: LDP.cc:779
static LabelOpVector swapLabel(int label)
Definition: LIBTable.cc:173
PendingVector pending
Definition: LDP.h:107
virtual TCPSocket * findPeerSocket(IPv4Address peerAddr)
Utility: return socket for given peer, and nullptr if session doesn&#39;t exist.
Definition: LDP.cc:1156
FecBindVector fecDown
Definition: LDP.h:105
virtual void sendNotify(int status, IPv4Address dest, IPv4Address addr, int length)
Definition: LDP.cc:827
virtual int installLibEntry(int inLabel, std::string inInterface, const LabelOpVector &outLabel, std::string outInterface, int color)
Definition: LIBTable.cc:64
FecVector fecList
Definition: LDP.h:101
void inet::LDP::processLABEL_WITHDRAW ( LDPLabelMapping packet)
protectedvirtual

Referenced by processLDPPacketFromTCP().

1048 {
1049  FEC_TLV fec = packet->getFec();
1050  int label = packet->getLabel();
1051  IPv4Address fromIP = packet->getSenderAddress();
1052 
1053  EV_INFO << "Mapping withdraw received for label=" << label << " fec=" << fec << " from " << fromIP << endl;
1054 
1055  ASSERT(label > 0);
1056 
1057  // remove label from fecDown
1058 
1059  auto it = findFecEntry(fecList, fec.addr, fec.length);
1060  if (it == fecList.end()) {
1061  EV_INFO << "matching FEC not found, ignoring withdraw message" << endl;
1062  delete packet;
1063  return;
1064  }
1065 
1066  auto dit = findFecEntry(fecDown, it->fecid, fromIP);
1067 
1068  if (dit == fecDown.end() || label != dit->label) {
1069  EV_INFO << "matching mapping not found, ignoring withdraw message" << endl;
1070  delete packet;
1071  return;
1072  }
1073 
1074  ASSERT(dit != fecDown.end());
1075  ASSERT(label == dit->label);
1076 
1077  EV_INFO << "removing label from list of received mappings" << endl;
1078  fecDown.erase(dit);
1079 
1080  EV_INFO << "sending back relase message" << endl;
1081  packet->setType(LABEL_RELEASE);
1082 
1083  // send msg to peer over TCP
1084  sendToPeer(fromIP, packet);
1085 
1086  updateFecListEntry(*it);
1087 }
virtual void updateFecListEntry(fec_t oldItem)
Definition: LDP.cc:247
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
Definition: LDPPacket_m.h:77
virtual void sendToPeer(IPv4Address dest, cMessage *msg)
Definition: LDP.cc:225
FecBindVector fecDown
Definition: LDP.h:105
FecVector fecList
Definition: LDP.h:101
void inet::LDP::processLDPHello ( LDPHello msg)
protectedvirtual

Referenced by handleMessage().

510 {
511  UDPDataIndication *controlInfo = check_and_cast<UDPDataIndication *>(msg->getControlInfo());
512  //IPv4Address peerAddr = controlInfo->getSrcAddr().toIPv4();
513  IPv4Address peerAddr = msg->getSenderAddress();
514  int interfaceId = controlInfo->getInterfaceId();
515  delete msg;
516 
517  EV_INFO << "Received LDP Hello from " << peerAddr << ", ";
518 
519  if (peerAddr.isUnspecified() || peerAddr == rt->getRouterId()) {
520  // must be ourselves (we're also in the all-routers multicast group), ignore
521  EV_INFO << "that's myself, ignore\n";
522  return;
523  }
524 
525  // mark link as working if it was failed, and rebuild table
526  unsigned int index = tedmod->linkIndex(rt->getRouterId(), peerAddr);
527  if (!tedmod->ted[index].state) {
528  tedmod->ted[index].state = true;
530  announceLinkChange(index);
531  }
532 
533  // peer already in table?
534  int i = findPeer(peerAddr);
535  if (i != -1) {
536  EV_DETAIL << "already in my peer table, rescheduling timeout" << endl;
537  ASSERT(myPeers[i].timeout);
538  cancelEvent(myPeers[i].timeout);
539  scheduleAt(simTime() + holdTime, myPeers[i].timeout);
540  return;
541  }
542 
543  // not in table, add it
544  peer_info info;
545  info.peerIP = peerAddr;
546  info.linkInterface = ift->getInterfaceById(interfaceId)->getName();
547  info.activeRole = peerAddr.getInt() > rt->getRouterId().getInt();
548  info.socket = nullptr;
549  info.timeout = new cMessage("HelloTimeout");
550  scheduleAt(simTime() + holdTime, info.timeout);
551  myPeers.push_back(info);
552  int peerIndex = myPeers.size() - 1;
553 
554  EV_INFO << "added to peer table\n";
555  EV_INFO << "We'll be " << (info.activeRole ? "ACTIVE" : "PASSIVE") << " in this session\n";
556 
557  // introduce ourselves with a Hello, then connect if we're in ACTIVE role
558  sendHelloTo(peerAddr);
559  if (info.activeRole) {
560  EV_INFO << "Establishing session with it\n";
561  openTCPConnectionToPeer(peerIndex);
562  }
563 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual unsigned int linkIndex(IPv4Address localInf)
Definition: TED.cc:429
virtual void rebuildRoutingTable()
Definition: TED.cc:230
IInterfaceTable * ift
Definition: LDP.h:116
simtime_t holdTime
Definition: LDP.h:97
IIPv4RoutingTable * rt
Definition: LDP.h:117
TED * tedmod
Definition: LDP.h:119
virtual void openTCPConnectionToPeer(int peerIndex)
Definition: LDP.cc:565
virtual IPv4Address getRouterId() const =0
Returns routerId.
PeerVector myPeers
Definition: LDP.h:110
uint32 getInt() const
Returns the address as an int.
Definition: IPv4Address.h:197
TELinkStateInfoVector ted
The link state database.
Definition: TED.h:64
virtual int findPeer(IPv4Address peerAddr)
Utility: return peer&#39;s index in myPeers table, or -1 if not found.
Definition: LDP.cc:1147
virtual void sendHelloTo(IPv4Address dest)
Definition: LDP.cc:419
virtual void announceLinkChange(int tedlinkindex)
Definition: LDP.cc:1231
void inet::LDP::processLDPPacketFromTCP ( LDPPacket ldpPacket)
protectedvirtual

Referenced by socketDataArrived().

669 {
670  switch (ldpPacket->getType()) {
671  case HELLO:
672  throw cRuntimeError("Received LDP HELLO over TCP (should arrive over UDP)");
673  break;
674 
675  case ADDRESS:
676  // processADDRESS(ldpPacket);
677  throw cRuntimeError("Received LDP ADDRESS message, unsupported in this version");
678  break;
679 
680  case ADDRESS_WITHDRAW:
681  // processADDRESS_WITHDRAW(ldpPacket);
682  throw cRuntimeError("LDP PROC DEBUG: Received LDP ADDRESS_WITHDRAW message, unsupported in this version");
683  break;
684 
685  case LABEL_MAPPING:
686  processLABEL_MAPPING(check_and_cast<LDPLabelMapping *>(ldpPacket));
687  break;
688 
689  case LABEL_REQUEST:
690  processLABEL_REQUEST(check_and_cast<LDPLabelRequest *>(ldpPacket));
691  break;
692 
693  case LABEL_WITHDRAW:
694  processLABEL_WITHDRAW(check_and_cast<LDPLabelMapping *>(ldpPacket));
695  break;
696 
697  case LABEL_RELEASE:
698  processLABEL_RELEASE(check_and_cast<LDPLabelMapping *>(ldpPacket));
699  break;
700 
701  case NOTIFICATION:
702  processNOTIFICATION(check_and_cast<LDPNotify *>(ldpPacket));
703  break;
704 
705  default:
706  throw cRuntimeError("LDP PROC DEBUG: Unrecognized LDP Message Type, type is %d", ldpPacket->getType());
707  break;
708  }
709 }
Definition: LDPPacket_m.h:76
Definition: LDPPacket_m.h:74
Definition: LDPPacket_m.h:68
virtual void processLABEL_REQUEST(LDPLabelRequest *packet)
Definition: LDP.cc:919
Definition: LDPPacket_m.h:77
virtual void processLABEL_WITHDRAW(LDPLabelMapping *packet)
Definition: LDP.cc:1047
Definition: LDPPacket_m.h:75
Definition: LDPPacket_m.h:73
virtual void processLABEL_MAPPING(LDPLabelMapping *packet)
Definition: LDP.cc:1089
virtual void processLABEL_RELEASE(LDPLabelMapping *packet)
Definition: LDP.cc:1009
virtual void processNOTIFICATION(LDPNotify *packet)
Definition: LDP.cc:865
Definition: LDPPacket_m.h:72
Definition: LDPPacket_m.h:69
void inet::LDP::processMessageFromTCP ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

579 {
580  TCPSocket *socket = socketMap.findSocketFor(msg);
581  if (!socket) {
582  // not yet in socketMap, must be new incoming connection.
583  // find which peer it is and register connection
584  socket = new TCPSocket(msg);
585  socket->setOutputGate(gate("tcpOut"));
586  socket->readDataTransferModePar(*this);
587 
588  // FIXME there seems to be some confusion here. Is it sure that
589  // routerIds we use as peerAddrs are the same as IP addresses
590  // the routing is based on? --Andras
591  IPv4Address peerAddr = socket->getRemoteAddress().toIPv4();
592 
593  int i = findPeer(peerAddr);
594  if (i == -1 || myPeers[i].socket) {
595  // nothing known about this guy, or already connected: refuse
596  socket->close(); // reset()?
597  delete socket;
598  delete msg;
599  return;
600  }
601  myPeers[i].socket = socket;
602  socket->setCallbackObject(this, (void *)((intptr_t)i));
603  socketMap.addSocket(socket);
604  }
605 
606  // dispatch to socketEstablished(), socketDataArrived(), socketPeerClosed()
607  // or socketFailure()
608  socket->processMessage(msg);
609 }
TCPSocketMap socketMap
Definition: LDP.h:124
PeerVector myPeers
Definition: LDP.h:110
void addSocket(TCPSocket *socket)
Registers the given socket.
Definition: TCPSocketMap.cc:36
virtual int findPeer(IPv4Address peerAddr)
Utility: return peer&#39;s index in myPeers table, or -1 if not found.
Definition: LDP.cc:1147
TCPSocket * findSocketFor(cMessage *msg)
Finds the socket (by connId) for the given message.
Definition: TCPSocketMap.cc:24
void inet::LDP::processNOTIFICATION ( LDPNotify packet)
protectedvirtual

Referenced by handleMessage(), and processLDPPacketFromTCP().

866 {
867  FEC_TLV fec = packet->getFec();
868  IPv4Address srcAddr = packet->getSenderAddress();
869  int status = packet->getStatus();
870 
871  // XXX FIXME NO_ROUTE processing should probably be split into two functions,
872  // this is not the cleanest thing I ever wrote :) --Vojta
873 
874  if (packet->isSelfMessage()) {
875  // re-scheduled by ourselves
876  EV_INFO << "notification retry for peer=" << srcAddr << " fec=" << fec << " status=" << status << endl;
877  }
878  else {
879  // received via network
880  EV_INFO << "notification received from=" << srcAddr << " fec=" << fec << " status=" << status << endl;
881  }
882 
883  switch (status) {
884  case NO_ROUTE: {
885  EV_INFO << "route does not exit on that peer" << endl;
886 
887  auto it = findFecEntry(fecList, fec.addr, fec.length);
888  if (it != fecList.end()) {
889  if (it->nextHop == srcAddr) {
890  if (!packet->isSelfMessage()) {
891  EV_DETAIL << "we are still interesed in this mapping, we will retry later" << endl;
892 
893  scheduleAt(simTime() + 1.0 /* XXX FIXME */, packet);
894  return;
895  }
896  else {
897  EV_DETAIL << "reissuing request" << endl;
898 
899  sendMappingRequest(srcAddr, fec.addr, fec.length);
900  }
901  }
902  else
903  EV_DETAIL << "and we still recognize this FEC, but we use different next hop, forget it" << endl;
904  }
905  else
906  EV_DETAIL << "and we do not recognize this any longer, forget it" << endl;
907 
908  break;
909  }
910 
911  default:
912  ASSERT(false);
913  break;
914  }
915 
916  delete packet;
917 }
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
virtual void sendMappingRequest(IPv4Address dest, IPv4Address addr, int length)
Definition: LDP.cc:230
Definition: LDPPacket_m.h:92
FecVector fecList
Definition: LDP.h:101
void inet::LDP::rebuildFecList ( )
protectedvirtual

Referenced by initialize(), and receiveSignal().

302 {
303  EV_INFO << "make list of recognized FECs" << endl;
304 
305  FecVector oldList = fecList;
306  fecList.clear();
307 
308  for (int i = 0; i < rt->getNumRoutes(); i++) {
309  // every entry in the routing table
310 
311  const IPv4Route *re = rt->getRoute(i);
312 
313  // ignore multicast routes
314  if (re->getDestination().isMulticast())
315  continue;
316 
317  // find out current next hop according to routing table
318  IPv4Address nextHop = (re->getGateway().isUnspecified()) ? re->getDestination() : re->getGateway();
319  ASSERT(!nextHop.isUnspecified());
320 
321  EV_INFO << "nextHop <-- " << nextHop << endl;
322 
323  auto it = findFecEntry(oldList, re->getDestination(), re->getNetmask().getNetmaskLength());
324 
325  if (it == oldList.end()) {
326  // fec didn't exist, it was just created
327  fec_t newItem;
328  newItem.fecid = ++maxFecid;
329  newItem.addr = re->getDestination();
330  newItem.length = re->getNetmask().getNetmaskLength();
331  newItem.nextHop = nextHop;
332  updateFecListEntry(newItem);
333  fecList.push_back(newItem);
334  }
335  else if (it->nextHop != nextHop) {
336  // next hop for this FEC changed,
337  it->nextHop = nextHop;
338  updateFecListEntry(*it);
339  fecList.push_back(*it);
340  oldList.erase(it);
341  }
342  else {
343  // FEC didn't change, reusing old values
344  fecList.push_back(*it);
345  oldList.erase(it);
346  continue;
347  }
348  }
349 
350  // our own addresses (XXX is it needed?)
351 
352  for (int i = 0; i < ift->getNumInterfaces(); ++i) {
353  InterfaceEntry *ie = ift->getInterface(i);
354  if (ie->getNetworkLayerGateIndex() < 0)
355  continue;
356  if (!ie->ipv4Data())
357  continue;
358 
359  auto it = findFecEntry(oldList, ie->ipv4Data()->getIPAddress(), 32);
360  if (it == oldList.end()) {
361  fec_t newItem;
362  newItem.fecid = ++maxFecid;
363  newItem.addr = ie->ipv4Data()->getIPAddress();
364  newItem.length = 32;
365  newItem.nextHop = ie->ipv4Data()->getIPAddress();
366  fecList.push_back(newItem);
367  }
368  else {
369  fecList.push_back(*it);
370  oldList.erase(it);
371  }
372  }
373 
374  if (oldList.size() > 0) {
375  EV_INFO << "there are " << oldList.size() << " deprecated FECs, removing them" << endl;
376 
377  for (auto & elem : oldList) {
378  EV_DETAIL << "removing FEC= " << elem << endl;
379 
380  for (auto & _dit : fecDown) {
381  if (_dit.fecid != elem.fecid)
382  continue;
383 
384  EV_DETAIL << "sending release label=" << _dit.label << " downstream to " << _dit.peer << endl;
385 
386  sendMapping(LABEL_RELEASE, _dit.peer, _dit.label, elem.addr, elem.length);
387  }
388 
389  for (auto & _uit : fecUp) {
390  if (_uit.fecid != elem.fecid)
391  continue;
392 
393  EV_DETAIL << "sending withdraw label=" << _uit.label << " upstream to " << _uit.peer << endl;
394 
395  sendMapping(LABEL_WITHDRAW, _uit.peer, _uit.label, elem.addr, elem.length);
396 
397  EV_DETAIL << "removing entry inLabel=" << _uit.label << " from LIB" << endl;
398 
399  lt->removeLibEntry(_uit.label);
400  }
401  }
402  }
403 
404  // we must keep this list sorted for matching to work correctly
405  // this is probably slower than it must be
406  std::stable_sort(fecList.begin(), fecList.end(), fecPrefixCompare);
407 }
virtual void sendMapping(int type, IPv4Address dest, int label, IPv4Address addr, int length)
Definition: LDP.cc:846
virtual void updateFecListEntry(fec_t oldItem)
Definition: LDP.cc:247
virtual IPv4Route * getRoute(int k) const override=0
Returns the kth route.
Definition: LDPPacket_m.h:76
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
virtual void removeLibEntry(int inLabel)
Definition: LIBTable.cc:93
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
std::vector< fec_t > FecVector
Definition: LDP.h:67
IInterfaceTable * ift
Definition: LDP.h:116
bool fecPrefixCompare(const LDP::fec_t &a, const LDP::fec_t &b)
Definition: LDP.cc:47
Definition: LDPPacket_m.h:77
IIPv4RoutingTable * rt
Definition: LDP.h:117
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
FecBindVector fecDown
Definition: LDP.h:105
int maxFecid
Definition: LDP.h:129
IPv4Address getDestination() const
Destination address prefix to match.
Definition: IPv4Route.h:105
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
FecVector fecList
Definition: LDP.h:101
void inet::LDP::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual
1220 {
1221  Enter_Method_Silent();
1222  printNotificationBanner(signalID, obj);
1223 
1224  ASSERT(signalID == NF_ROUTE_ADDED || signalID == NF_ROUTE_DELETED);
1225 
1226  EV_INFO << "routing table changed, rebuild list of known FEC" << endl;
1227 
1228  rebuildFecList();
1229 }
simsignal_t NF_ROUTE_DELETED
Definition: NotifierConsts.cc:58
virtual void rebuildFecList()
Definition: LDP.cc:301
simsignal_t NF_ROUTE_ADDED
Definition: NotifierConsts.cc:57
void printNotificationBanner(simsignal_t signalID, const cObject *obj)
Utility function.
Definition: NotifierConsts.cc:109
void inet::LDP::sendHelloTo ( IPv4Address  dest)
protectedvirtual

Referenced by handleMessage(), and processLDPHello().

420 {
421  LDPHello *hello = new LDPHello("LDP-Hello");
422  hello->setByteLength(LDP_HEADER_BYTES);
423  hello->setType(HELLO);
424  hello->setSenderAddress(rt->getRouterId());
425  //hello->setReceiverAddress(...);
426  hello->setHoldTime(SIMTIME_DBL(holdTime));
427  //hello->setRbit(...);
428  //hello->setTbit(...);
429  hello->addPar("color") = LDP_HELLO_TRAFFIC;
430 
431  if (dest.isMulticast()) {
432  for (int i = 0; i < (int)udpSockets.size(); ++i) {
433  LDPHello *msg = i == (int)udpSockets.size() - 1 ? hello : hello->dup();
434  udpSockets[i].sendTo(msg, dest, LDP_PORT);
435  }
436  }
437  else
438  udpSocket.sendTo(hello, dest, LDP_PORT);
439 }
UDPSocket udpSocket
Definition: LDP.h:121
void sendTo(cPacket *msg, L3Address destAddr, int destPort, const SendOptions *options=nullptr)
Sends a data packet to the given address and port.
Definition: UDPSocket.cc:88
std::vector< UDPSocket > udpSockets
Definition: LDP.h:122
simtime_t holdTime
Definition: LDP.h:97
IIPv4RoutingTable * rt
Definition: LDP.h:117
virtual IPv4Address getRouterId() const =0
Returns routerId.
#define LDP_PORT
Definition: LDP.h:35
#define LDP_HELLO_TRAFFIC
Definition: LDP.h:38
#define LDP_HEADER_BYTES
Definition: LDPPacket_m.h:38
Definition: LDPPacket_m.h:69
void inet::LDP::sendMapping ( int  type,
IPv4Address  dest,
int  label,
IPv4Address  addr,
int  length 
)
protectedvirtual

Referenced by processLABEL_MAPPING(), processLABEL_REQUEST(), rebuildFecList(), and updateFecListEntry().

847 {
848  // Send LABEL MAPPING downstream
849  LDPLabelMapping *lmMessage = new LDPLabelMapping("Lb-Mapping");
850  lmMessage->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
851  lmMessage->setType(type);
852  lmMessage->setReceiverAddress(dest);
853  lmMessage->setSenderAddress(rt->getRouterId());
854  lmMessage->setLabel(label);
855 
856  FEC_TLV fec;
857  fec.addr = addr;
858  fec.length = length;
859 
860  lmMessage->setFec(fec);
861 
862  sendToPeer(dest, lmMessage);
863 }
IIPv4RoutingTable * rt
Definition: LDP.h:117
virtual void sendToPeer(IPv4Address dest, cMessage *msg)
Definition: LDP.cc:225
virtual IPv4Address getRouterId() const =0
Returns routerId.
#define LDP_HEADER_BYTES
Definition: LDPPacket_m.h:38
void inet::LDP::sendMappingRequest ( IPv4Address  dest,
IPv4Address  addr,
int  length 
)
protectedvirtual

Referenced by processNOTIFICATION(), and updateFecListEntry().

231 {
232  LDPLabelRequest *requestMsg = new LDPLabelRequest("Lb-Req");
233  requestMsg->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
234  requestMsg->setType(LABEL_REQUEST);
235 
236  FEC_TLV fec;
237  fec.addr = addr;
238  fec.length = length;
239  requestMsg->setFec(fec);
240 
241  requestMsg->setReceiverAddress(dest);
242  requestMsg->setSenderAddress(rt->getRouterId());
243 
244  sendToPeer(dest, requestMsg);
245 }
IIPv4RoutingTable * rt
Definition: LDP.h:117
Definition: LDPPacket_m.h:75
virtual void sendToPeer(IPv4Address dest, cMessage *msg)
Definition: LDP.cc:225
virtual IPv4Address getRouterId() const =0
Returns routerId.
#define LDP_HEADER_BYTES
Definition: LDPPacket_m.h:38
void inet::LDP::sendNotify ( int  status,
IPv4Address  dest,
IPv4Address  addr,
int  length 
)
protectedvirtual

Referenced by processLABEL_REQUEST().

828 {
829  // Send NOTIFY message
830  LDPNotify *lnMessage = new LDPNotify("Lb-Notify");
831  lnMessage->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
832  lnMessage->setType(NOTIFICATION);
833  lnMessage->setStatus(NO_ROUTE);
834  lnMessage->setReceiverAddress(dest);
835  lnMessage->setSenderAddress(rt->getRouterId());
836 
837  FEC_TLV fec;
838  fec.addr = addr;
839  fec.length = length;
840 
841  lnMessage->setFec(fec);
842 
843  sendToPeer(dest, lnMessage);
844 }
Definition: LDPPacket_m.h:68
IIPv4RoutingTable * rt
Definition: LDP.h:117
Definition: LDPPacket_m.h:92
virtual void sendToPeer(IPv4Address dest, cMessage *msg)
Definition: LDP.cc:225
virtual IPv4Address getRouterId() const =0
Returns routerId.
#define LDP_HEADER_BYTES
Definition: LDPPacket_m.h:38
void inet::LDP::sendToPeer ( IPv4Address  dest,
cMessage *  msg 
)
protectedvirtual

Referenced by processLABEL_WITHDRAW(), sendMapping(), sendMappingRequest(), and sendNotify().

226 {
227  getPeerSocket(dest)->send(msg);
228 }
void send(cMessage *msg)
Sends data packet.
Definition: TCPSocket.cc:175
virtual TCPSocket * getPeerSocket(IPv4Address peerAddr)
Utility: return socket for given peer.
Definition: LDP.cc:1165
void inet::LDP::socketClosed ( int  connId,
void *  yourPtr 
)
overrideprotectedvirtual

Reimplemented from inet::TCPSocket::CallbackInterface.

649 {
650  peer_info& peer = myPeers[(uintptr_t)yourPtr];
651  EV_INFO << "TCP connection to peer " << peer.peerIP << " closed\n";
652 
653  ASSERT(false);
654 
655  // FIXME what now? reconnect after a delay?
656 }
PeerVector myPeers
Definition: LDP.h:110
void inet::LDP::socketDataArrived ( int  connId,
void *  yourPtr,
cPacket *  msg,
bool  urgent 
)
overrideprotectedvirtual

Implements inet::TCPSocket::CallbackInterface.

623 {
624  peer_info& peer = myPeers[(uintptr_t)yourPtr];
625  EV_INFO << "Message arrived over TCP from peer " << peer.peerIP << "\n";
626 
627  delete msg->removeControlInfo();
628  processLDPPacketFromTCP(check_and_cast<LDPPacket *>(msg));
629 }
virtual void processLDPPacketFromTCP(LDPPacket *ldpPacket)
Definition: LDP.cc:668
PeerVector myPeers
Definition: LDP.h:110
void inet::LDP::socketEstablished ( int  connId,
void *  yourPtr 
)
overrideprotectedvirtual

Reimplemented from inet::TCPSocket::CallbackInterface.

612 {
613  peer_info& peer = myPeers[(uintptr_t)yourPtr];
614  EV_INFO << "TCP connection established with peer " << peer.peerIP << "\n";
615 
616  // we must update all entries with nextHop == peerIP
617  updateFecList(peer.peerIP);
618 
619  // FIXME start LDP session setup (if we're on the active side?)
620 }
PeerVector myPeers
Definition: LDP.h:110
virtual void updateFecList(IPv4Address nextHop)
Definition: LDP.cc:409
void inet::LDP::socketFailure ( int  connId,
void *  yourPtr,
int  code 
)
overrideprotectedvirtual

Reimplemented from inet::TCPSocket::CallbackInterface.

659 {
660  peer_info& peer = myPeers[(uintptr_t)yourPtr];
661  EV_INFO << "TCP connection to peer " << peer.peerIP << " broken\n";
662 
663  ASSERT(false);
664 
665  // FIXME what now? reconnect after a delay?
666 }
PeerVector myPeers
Definition: LDP.h:110
void inet::LDP::socketPeerClosed ( int  connId,
void *  yourPtr 
)
overrideprotectedvirtual

Reimplemented from inet::TCPSocket::CallbackInterface.

632 {
633  peer_info& peer = myPeers[(uintptr_t)yourPtr];
634  EV_INFO << "Peer " << peer.peerIP << " closed TCP connection\n";
635 
636  ASSERT(false);
637 
638 /*
639  // close the connection (if not already closed)
640  if (socket.getState()==TCPSocket::PEER_CLOSED)
641  {
642  EV << "remote TCP closed, closing here as well\n";
643  close();
644  }
645  */
646 }
PeerVector myPeers
Definition: LDP.h:110
virtual void inet::LDP::socketStatusArrived ( int  connId,
void *  yourPtr,
TCPStatusInfo status 
)
inlineoverrideprotectedvirtual

Reimplemented from inet::TCPSocket::CallbackInterface.

208 { delete status; }
void inet::LDP::updateFecList ( IPv4Address  nextHop)
protectedvirtual

Referenced by processHelloTimeout(), and socketEstablished().

410 {
411  for (auto & elem : fecList) {
412  if (elem.nextHop != nextHop)
413  continue;
414 
415  updateFecListEntry(elem);
416  }
417 }
virtual void updateFecListEntry(fec_t oldItem)
Definition: LDP.cc:247
FecVector fecList
Definition: LDP.h:101
void inet::LDP::updateFecListEntry ( LDP::fec_t  oldItem)
protectedvirtual

Referenced by processLABEL_WITHDRAW(), rebuildFecList(), and updateFecList().

248 {
249  // do we have mapping from downstream?
250  auto dit = findFecEntry(fecDown, oldItem.fecid, oldItem.nextHop);
251 
252  // is next hop our LDP peer?
253  bool ER = findPeerSocket(oldItem.nextHop) == nullptr;
254 
255  ASSERT(!(ER && dit != fecDown.end())); // can't be egress and have mapping at the same time
256 
257  // adjust upstream mappings
258  for (auto uit = fecUp.begin(); uit != fecUp.end(); ) {
259  if (uit->fecid != oldItem.fecid) {
260  uit++;
261  continue;
262  }
263 
264  std::string inInterface = findInterfaceFromPeerAddr(uit->peer);
265  std::string outInterface = findInterfaceFromPeerAddr(oldItem.nextHop);
266  if (ER) {
267  // we are egress, that's easy:
268  LabelOpVector outLabel = LIBTable::popLabel();
269  uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
270 
271  EV_DETAIL << "installed (egress) LIB entry inLabel=" << uit->label << " inInterface=" << inInterface
272  << " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
273  uit++;
274  }
275  else if (dit != fecDown.end()) {
276  // we have mapping from DS, that's easy
277  LabelOpVector outLabel = LIBTable::swapLabel(dit->label);
278  uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
279 
280  EV_DETAIL << "installed LIB entry inLabel=" << uit->label << " inInterface=" << inInterface
281  << " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
282  uit++;
283  }
284  else {
285  // no mapping from DS, withdraw mapping US
286  EV_INFO << "sending withdraw message upstream" << endl;
287  sendMapping(LABEL_WITHDRAW, uit->peer, uit->label, oldItem.addr, oldItem.length);
288 
289  // remove from US mappings
290  uit = fecUp.erase(uit);
291  }
292  }
293 
294  if (!ER && dit == fecDown.end()) {
295  // and ask DS for mapping
296  EV_INFO << "sending request message downstream" << endl;
297  sendMappingRequest(oldItem.nextHop, oldItem.addr, oldItem.length);
298  }
299 }
virtual void sendMapping(int type, IPv4Address dest, int label, IPv4Address addr, int length)
Definition: LDP.cc:846
#define LDP_USER_TRAFFIC
Definition: LDP.h:39
std::vector< LabelOp > LabelOpVector
Definition: LIBTable.h:44
Definition: LDPPacket_m.h:76
FecVector::iterator findFecEntry(FecVector &fecs, IPv4Address addr, int length)
Definition: LDP.cc:817
virtual void sendMappingRequest(IPv4Address dest, IPv4Address addr, int length)
Definition: LDP.cc:230
static LabelOpVector popLabel()
Definition: LIBTable.cc:183
FecBindVector fecUp
Definition: LDP.h:103
LIBTable * lt
Definition: LDP.h:118
std::string findInterfaceFromPeerAddr(IPv4Address peerIP)
Definition: LDP.cc:779
static LabelOpVector swapLabel(int label)
Definition: LIBTable.cc:173
virtual TCPSocket * findPeerSocket(IPv4Address peerAddr)
Utility: return socket for given peer, and nullptr if session doesn&#39;t exist.
Definition: LDP.cc:1156
FecBindVector fecDown
Definition: LDP.h:105
virtual int installLibEntry(int inLabel, std::string inInterface, const LabelOpVector &outLabel, std::string outInterface, int color)
Definition: LIBTable.cc:64

Member Data Documentation

simtime_t inet::LDP::helloInterval
protected

Referenced by handleMessage(), and initialize().

simtime_t inet::LDP::holdTime
protected
IInterfaceTable* inet::LDP::ift = nullptr
protected
int inet::LDP::maxFecid = 0
protected

Referenced by initialize(), and rebuildFecList().

NodeStatus* inet::LDP::nodeStatus = nullptr
protected

Referenced by initialize(), and isNodeUp().

PendingVector inet::LDP::pending
protected
cMessage* inet::LDP::sendHelloMsg = nullptr
protected
TCPSocket inet::LDP::serverSocket
protected

Referenced by initialize().

TCPSocketMap inet::LDP::socketMap
protected
TED* inet::LDP::tedmod = nullptr
protected
UDPSocket inet::LDP::udpSocket
protected

Referenced by initialize(), and sendHelloTo().

std::vector<UDPSocket> inet::LDP::udpSockets
protected

Referenced by initialize(), and sendHelloTo().


The documentation for this class was generated from the following files: