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

Implements the MPLS protocol; see the NED file for more info. More...

#include <Mpls.h>

Inheritance diagram for inet::Mpls:
inet::DefaultProtocolRegistrationListener inet::IInterfaceRegistrationListener inet::IProtocolRegistrationListener

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void processPacketFromL3 (Packet *msg)
 
virtual void processPacketFromL2 (Packet *msg)
 
virtual void processMplsPacketFromL2 (Packet *mplsPacket)
 
virtual bool tryLabelAndForwardIpv4Datagram (Packet *ipdatagram)
 
virtual void labelAndForwardIpv4Datagram (Packet *ipdatagram)
 
virtual void sendToL2 (Packet *msg)
 
virtual void sendToL3 (Packet *msg)
 
void pushLabel (Packet *packet, Ptr< MplsHeader > &newMplsHeader)
 
void swapLabel (Packet *packet, Ptr< MplsHeader > &newMplsHeader)
 
void popLabel (Packet *packet)
 
virtual void doStackOps (Packet *packet, const LabelOpVector &outLabel)
 
virtual void handleRegisterInterface (const NetworkInterface &interface, cGate *in, cGate *out) override
 
virtual void handleRegisterService (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterProtocol (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override
 

Protected Attributes

simtime_t delay1
 
ModuleRefByPar< LibTablelt
 
ModuleRefByPar< IInterfaceTableift
 
ModuleRefByPar< IIngressClassifierpct
 

Additional Inherited Members

- Public Member Functions inherited from inet::DefaultProtocolRegistrationListener
virtual void handleRegisterServiceGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterProtocolGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterAnyService (cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterAnyProtocol (cGate *gate, ServicePrimitive servicePrimitive) override
 

Detailed Description

Implements the MPLS protocol; see the NED file for more info.

Member Function Documentation

◆ doStackOps()

void inet::Mpls::doStackOps ( Packet packet,
const LabelOpVector outLabel 
)
protectedvirtual
161 {
162  unsigned int n = outLabel.size();
163 
164  EV_INFO << "doStackOps: " << outLabel << endl;
165 
166  for (unsigned int i = 0; i < n; i++) {
167  switch (outLabel[i].optcode) {
168  case PUSH_OPER: {
169  auto mplsHeader = makeShared<MplsHeader>();
170  mplsHeader->setLabel(outLabel[i].label);
171  pushLabel(packet, mplsHeader);
172  break;
173  }
174  case SWAP_OPER: {
175  auto mplsHeader = makeShared<MplsHeader>();
176  mplsHeader->setLabel(outLabel[i].label);
177  swapLabel(packet, mplsHeader);
178  break;
179  }
180  case POP_OPER:
181  popLabel(packet);
182  break;
183 
184  default:
185  throw cRuntimeError("Unknown MPLS OptCode %d", outLabel[i].optcode);
186  break;
187  }
188  }
189 }

Referenced by processMplsPacketFromL2(), and tryLabelAndForwardIpv4Datagram().

◆ handleMessage()

void inet::Mpls::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
45 {
46  Packet *pk = check_and_cast<Packet *>(msg);
47  if (msg->getArrivalGate()->isName("ifIn")) {
48  EV_INFO << "Processing message from L2: " << pk << endl;
50  }
51  else if (msg->getArrivalGate()->isName("netwIn")) {
52  EV_INFO << "Processing message from L3: " << pk << endl;
54  }
55  else {
56  throw cRuntimeError("unexpected message: %s", msg->getName());
57  }
58 }

◆ handleRegisterInterface()

void inet::Mpls::handleRegisterInterface ( const NetworkInterface interface,
cGate *  in,
cGate *  out 
)
overrideprotectedvirtual

Implements inet::IInterfaceRegistrationListener.

297 {
298  if (!strcmp("ifIn", in->getBaseName()))
299  registerInterface(interface, gate("netwIn"), gate("netwOut"));
300 }

◆ handleRegisterProtocol()

void inet::Mpls::handleRegisterProtocol ( const Protocol protocol,
cGate *  gate,
ServicePrimitive  servicePrimitive 
)
overrideprotectedvirtual

Reimplemented from inet::DefaultProtocolRegistrationListener.

318 {
319  Enter_Method("handleRegisterProtocol");
320  if (!strcmp("ifIn", g->getName()))
321  registerProtocol(protocol, gate("netwOut"), servicePrimitive);
322  else if (!strcmp("ifOut", g->getName()))
323  ;
324  else if (!strcmp("netwOut", g->getName()))
325  registerProtocol(protocol, gate("ifIn"), servicePrimitive);
326  else if (!strcmp("netwIn", g->getName()))
327  ; // void
328  else
329  throw cRuntimeError("Unknown gate: %s", g->getName());
330 }

◆ handleRegisterService()

void inet::Mpls::handleRegisterService ( const Protocol protocol,
cGate *  gate,
ServicePrimitive  servicePrimitive 
)
overrideprotectedvirtual

Reimplemented from inet::DefaultProtocolRegistrationListener.

303 {
304  Enter_Method("handleRegisterService");
305  if (!strcmp("ifOut", g->getName()))
306  registerService(protocol, gate("netwIn"), servicePrimitive);
307  else if (!strcmp("ifIn", g->getName()))
308  ;
309  else if (!strcmp("netwOut", g->getName()))
310  registerService(protocol, gate("ifIn"), servicePrimitive);
311  else if (!strcmp("netwIn", g->getName()))
312  ;
313  else
314  throw cRuntimeError("Unknown gate: %s", g->getName());
315 }

◆ initialize()

void inet::Mpls::initialize ( int  stage)
overrideprotectedvirtual
28 {
29  cSimpleModule::initialize(stage);
30 
31  if (stage == INITSTAGE_LOCAL) {
32  // interfaceTable must be initialized
33 
34  lt.reference(this, "libTableModule", true);
35  ift.reference(this, "interfaceTableModule", true);
36  pct.reference(this, "classifierModule", true);
37  }
38  else if (stage == INITSTAGE_NETWORK_LAYER) {
39  registerService(Protocol::mpls, gate("netwIn"), gate("netwOut"));
40  registerProtocol(Protocol::mpls, gate("ifOut"), gate("ifIn"));
41  }
42 }

◆ labelAndForwardIpv4Datagram()

void inet::Mpls::labelAndForwardIpv4Datagram ( Packet ipdatagram)
protectedvirtual
122 {
123  if (tryLabelAndForwardIpv4Datagram(ipdatagram))
124  return;
125 
126  // handling our outgoing Ipv4 traffic that didn't match any FEC/LSP
127  // do not use labelAndForwardIPv4Datagram for packets arriving to ingress!
128 
129  EV_INFO << "FEC not resolved, doing regular L3 routing" << endl;
130 
131  sendToL2(ipdatagram);
132 }

Referenced by processPacketFromL3().

◆ numInitStages()

virtual int inet::Mpls::numInitStages ( ) const
inlineoverrideprotectedvirtual
43 { return NUM_INIT_STAGES; }

◆ popLabel()

void inet::Mpls::popLabel ( Packet packet)
protected
152 {
153  ASSERT(packet->getTag<PacketProtocolTag>()->getProtocol()->getId() == Protocol::mpls.getId());
154  auto oldMplsHeader = packet->popAtFront<MplsHeader>();
155  if (oldMplsHeader->getS()) {
156  packet->getTagForUpdate<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
157  }
158 }

Referenced by doStackOps().

◆ processMplsPacketFromL2()

void inet::Mpls::processMplsPacketFromL2 ( Packet mplsPacket)
protectedvirtual
213 {
214  int incomingInterfaceId = packet->getTag<InterfaceInd>()->getInterfaceId();
215  NetworkInterface *ie = ift->getInterfaceById(incomingInterfaceId);
216  std::string incomingInterfaceName = ie->getInterfaceName();
217  const auto& mplsHeader = packet->peekAtFront<MplsHeader>();
218 
219  EV_INFO << "Received " << packet << " from L2, label=" << mplsHeader->getLabel() << " inInterface=" << incomingInterfaceName << endl;
220 
221  if (mplsHeader->getLabel() == (uint32_t)-1) { // FIXME
222  // This is a Ipv4 native packet (RSVP/TED traffic)
223  // Decapsulate the message and pass up to L3
224  EV_INFO << ": decapsulating and sending up\n";
225  packet->popAtFront<MplsHeader>();
226  packet->getTagForUpdate<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
227  sendToL3(packet);
228  return;
229  }
230 
231  LabelOpVector outLabel;
232  std::string outInterface;
233  int color;
234 
235  bool found = lt->resolveLabel(incomingInterfaceName, mplsHeader->getLabel(), outLabel, outInterface, color);
236  if (!found) {
237  EV_INFO << "discarding packet, incoming label not resolved" << endl;
238 
239  delete packet;
240  return;
241  }
242 
243  NetworkInterface *outgoingInterface = CHK(ift->findInterfaceByName(outInterface.c_str()));
244 
245  doStackOps(packet, outLabel);
246 
247  if ((packet->getTag<PacketProtocolTag>()->getProtocol()->getId() == Protocol::mpls.getId())) {
248  // forward labeled packet
249  EV_INFO << "forwarding packet to " << outInterface << endl;
250 
251  if (packet->hasPar("color")) {
252  packet->par("color") = color;
253  }
254  else {
255  packet->addPar("color") = color;
256  }
257 
258 // ASSERT(labelIf[outgoingPort]);
259  packet->removeTagIfPresent<DispatchProtocolReq>();
260  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(outgoingInterface->getInterfaceId());
261  packet->trim();
262  sendToL2(packet);
263  }
264  else {
265  // last label popped, decapsulate and send out Ipv4 datagram
266 
267  EV_INFO << "decapsulating Ipv4 datagram" << endl;
268  ASSERT(packet->getTag<PacketProtocolTag>()->getProtocol()->getId() == Protocol::ipv4.getId());
269 
270  if (outgoingInterface) {
271  packet->trim();
272  packet->removeTagIfPresent<DispatchProtocolReq>();
273  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(outgoingInterface->getInterfaceId());
274  sendToL2(packet);
275  }
276  else {
277  sendToL3(packet);
278  }
279  }
280 }

Referenced by processPacketFromL2().

◆ processPacketFromL2()

void inet::Mpls::processPacketFromL2 ( Packet msg)
protectedvirtual
192 {
193  int protocolId = packet->getTag<PacketProtocolTag>()->getProtocol()->getId();
194  if (protocolId == Protocol::mpls.getId()) {
195  processMplsPacketFromL2(packet);
196  }
197  else if (protocolId == Protocol::ipv4.getId()) {
198  // Ipv4 datagram arrives at Ingress router. We'll try to classify it
199  // and add an MPLS header
200 
201  if (!tryLabelAndForwardIpv4Datagram(packet)) {
202  sendToL3(packet);
203  }
204  }
205  else {
206  throw cRuntimeError("Unknown message received");
207  // FIXME remove throw below
208  sendToL3(packet);
209  }
210 }

Referenced by handleMessage().

◆ processPacketFromL3()

void inet::Mpls::processPacketFromL3 ( Packet msg)
protectedvirtual
61 {
62  using namespace tcp;
63 
64  const Protocol *protocol = msg->getTag<PacketProtocolTag>()->getProtocol();
65  if (protocol != &Protocol::ipv4) {
66  // only the Ipv4 protocol supported yet
67  sendToL2(msg);
68  return;
69  }
70 
71  const auto& ipHeader = msg->peekAtFront<Ipv4Header>();
72 
73  // TODO temporary solution, until TcpSocket and Ipv4 are extended to support nam tracing
74  if (ipHeader->getProtocolId() == IP_PROT_TCP) {
75  const auto& seg = msg->peekDataAt<TcpHeader>(ipHeader->getChunkLength());
76  if (seg->getDestPort() == LDP_PORT || seg->getSrcPort() == LDP_PORT) {
77  ASSERT(!msg->hasPar("color"));
78  msg->addPar("color") = LDP_TRAFFIC;
79  }
80  }
81  else if (ipHeader->getProtocolId() == IP_PROT_ICMP) {
82 // ASSERT(!msg->hasPar("color")); TODO this did not hold sometimes...
83  if (!msg->hasPar("color"))
84  msg->addPar("color") = ICMP_TRAFFIC;
85  }
86  // TODO end of temporary area
87 
89 }

Referenced by handleMessage().

◆ pushLabel()

void inet::Mpls::pushLabel ( Packet packet,
Ptr< MplsHeader > &  newMplsHeader 
)
protected
135 {
136  packet->trimFront();
137  newMplsHeader->setS(packet->getTag<PacketProtocolTag>()->getProtocol()->getId() != Protocol::mpls.getId());
138  packet->insertAtFront(newMplsHeader);
139  packet->getTagForUpdate<PacketProtocolTag>()->setProtocol(&Protocol::mpls);
140 }

Referenced by doStackOps().

◆ sendToL2()

void inet::Mpls::sendToL2 ( Packet msg)
protectedvirtual
283 {
284  ASSERT(msg->findTag<InterfaceReq>());
285  ASSERT(msg->findTag<PacketProtocolTag>());
286  send(msg, "ifOut");
287 }

Referenced by labelAndForwardIpv4Datagram(), processMplsPacketFromL2(), processPacketFromL3(), and tryLabelAndForwardIpv4Datagram().

◆ sendToL3()

void inet::Mpls::sendToL3 ( Packet msg)
protectedvirtual
290 {
291  ASSERT(msg->findTag<InterfaceInd>());
292  ASSERT(msg->findTag<DispatchProtocolReq>());
293  send(msg, "netwOut");
294 }

Referenced by processMplsPacketFromL2(), and processPacketFromL2().

◆ swapLabel()

void inet::Mpls::swapLabel ( Packet packet,
Ptr< MplsHeader > &  newMplsHeader 
)
protected
143 {
144  ASSERT(packet->getTag<PacketProtocolTag>()->getProtocol()->getId() == Protocol::mpls.getId());
145  packet->trimFront();
146  auto oldMplsHeader = packet->removeAtFront<MplsHeader>();
147  newMplsHeader->setS(oldMplsHeader->getS());
148  packet->insertAtFront(newMplsHeader);
149 }

Referenced by doStackOps().

◆ tryLabelAndForwardIpv4Datagram()

bool inet::Mpls::tryLabelAndForwardIpv4Datagram ( Packet ipdatagram)
protectedvirtual
92 {
93  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
94  (void)ipv4Header; // unused variable
95  LabelOpVector outLabel;
96  std::string outInterface; // FIXME set based on interfaceID
97  int color;
98 
99  if (!pct->lookupLabel(packet, outLabel, outInterface, color)) {
100  EV_WARN << "no mapping exists for this packet" << endl;
101  return false;
102  }
103  int outInterfaceId = CHK(ift->findInterfaceByName(outInterface.c_str()))->getInterfaceId();
104 
105  ASSERT(outLabel.size() > 0);
106 
107  doStackOps(packet, outLabel);
108 
109  EV_INFO << "forwarding packet to " << outInterface << endl;
110 
111  packet->addPar("color") = color;
112 
113  packet->trim();
114  packet->removeTagIfPresent<DispatchProtocolReq>();
115  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(outInterfaceId);
116  sendToL2(packet);
117 
118  return true;
119 }

Referenced by labelAndForwardIpv4Datagram(), and processPacketFromL2().

Member Data Documentation

◆ delay1

simtime_t inet::Mpls::delay1
protected

◆ ift

◆ lt

ModuleRefByPar<LibTable> inet::Mpls::lt
protected

◆ pct

ModuleRefByPar<IIngressClassifier> inet::Mpls::pct
protected

The documentation for this class was generated from the following files:
CHK
#define CHK(x)
Definition: INETDefs.h:87
inet::Mpls::processPacketFromL3
virtual void processPacketFromL3(Packet *msg)
Definition: Mpls.cc:60
protocol
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::IP_PROT_ICMP
@ IP_PROT_ICMP
Definition: IpProtocolId_m.h:91
inet::Mpls::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Mpls.h:38
ICMP_TRAFFIC
#define ICMP_TRAFFIC
Definition: Mpls.cc:23
inet::Mpls::pushLabel
void pushLabel(Packet *packet, Ptr< MplsHeader > &newMplsHeader)
Definition: Mpls.cc:134
InterfaceReq
removed InterfaceReq
Definition: IUdp-gates.txt:11
inet::Mpls::lt
ModuleRefByPar< LibTable > lt
Definition: Mpls.h:37
inet::Mpls::doStackOps
virtual void doStackOps(Packet *packet, const LabelOpVector &outLabel)
Definition: Mpls.cc:160
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::INITSTAGE_NETWORK_LAYER
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
inet::registerService
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
inet::Mpls::labelAndForwardIpv4Datagram
virtual void labelAndForwardIpv4Datagram(Packet *ipdatagram)
Definition: Mpls.cc:121
inet::SWAP_OPER
@ SWAP_OPER
Definition: LibTable.h:22
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::units::units::g
milli< kg >::type g
Definition: Units.h:1071
LDP_TRAFFIC
#define LDP_TRAFFIC
Definition: Ldp.h:27
inet::Mpls::swapLabel
void swapLabel(Packet *packet, Ptr< MplsHeader > &newMplsHeader)
Definition: Mpls.cc:142
inet::Protocol::mpls
static const Protocol mpls
Definition: Protocol.h:101
inet::LabelOpVector
std::vector< LabelOp > LabelOpVector
Definition: LibTable.h:32
inet::Mpls::tryLabelAndForwardIpv4Datagram
virtual bool tryLabelAndForwardIpv4Datagram(Packet *ipdatagram)
Definition: Mpls.cc:91
inet::Mpls::processMplsPacketFromL2
virtual void processMplsPacketFromL2(Packet *mplsPacket)
Definition: Mpls.cc:212
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::IP_PROT_TCP
@ IP_PROT_TCP
Definition: IpProtocolId_m.h:94
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::POP_OPER
@ POP_OPER
Definition: LibTable.h:23
inet::Protocol::getId
int getId() const
Definition: Protocol.h:37
inet::registerInterface
void registerInterface(const NetworkInterface &interface, cGate *in, cGate *out)
Definition: IInterfaceRegistrationListener.cc:12
inet::Mpls::pct
ModuleRefByPar< IIngressClassifier > pct
Definition: Mpls.h:39
inet::Mpls::popLabel
void popLabel(Packet *packet)
Definition: Mpls.cc:151
inet::registerProtocol
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
inet::PUSH_OPER
@ PUSH_OPER
Definition: LibTable.h:21
inet::Mpls::sendToL2
virtual void sendToL2(Packet *msg)
Definition: Mpls.cc:282
inet::Mpls::sendToL3
virtual void sendToL3(Packet *msg)
Definition: Mpls.cc:289
inet::Mpls::processPacketFromL2
virtual void processPacketFromL2(Packet *msg)
Definition: Mpls.cc:191
LDP_PORT
#define LDP_PORT
Definition: Ldp.h:25