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

Computes L2 configuration of the network. More...

#include <L2NetworkConfigurator.h>

Inheritance diagram for inet::L2NetworkConfigurator:

Classes

class  InterfaceInfo
 Represents an interface in the network. More...
 
class  L2Topology
 
class  Link
 
class  Matcher
 
class  Node
 Represents a node in the network. More...
 

Public Types

typedef Ieee8021dInterfaceData::PortInfo PortInfo
 

Public Member Functions

 L2NetworkConfigurator ()
 
virtual void readInterfaceConfiguration (Node *rootNode)
 Reads interface elements from the configuration file and stores result. More...
 
virtual void configureInterface (NetworkInterface *networkInterface)
 Configures the provided interface based on the current network configuration. More...
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void extractTopology (L2Topology &topology)
 Extracts network topology by walking through the module hierarchy. More...
 
virtual void computeConfiguration ()
 Computes the Layer 2 network configuration for all nodes in the network. More...
 
virtual bool linkContainsMatchingHostExcept (InterfaceInfo *currentInfo, Matcher &hostMatcher, cModule *exceptModule)
 
void ensureConfigurationComputed (L2Topology &topology)
 
virtual Topology::LinkfindLinkOut (Node *node, int gateId)
 
void configureInterface (InterfaceInfo *interfaceInfo)
 

Protected Attributes

cXMLElement * configuration = nullptr
 
L2Topology topology
 
NoderootNode = nullptr
 

Detailed Description

Computes L2 configuration of the network.

See the NED definition for details.

Member Typedef Documentation

◆ PortInfo

Constructor & Destructor Documentation

◆ L2NetworkConfigurator()

inet::L2NetworkConfigurator::L2NetworkConfigurator ( )
inline
27 {}

Member Function Documentation

◆ computeConfiguration()

void inet::L2NetworkConfigurator::computeConfiguration ( )
protectedvirtual

Computes the Layer 2 network configuration for all nodes in the network.

The result of the computation is only stored in the network configurator.

193 {
194  long initializeStartTime = clock();
195  // extract topology into the L2Topology object
197  // read the configuration from XML; it will serve as input for port assignment
199  printElapsedTime("initialize", initializeStartTime);
200 }

Referenced by ensureConfigurationComputed().

◆ configureInterface() [1/2]

void inet::L2NetworkConfigurator::configureInterface ( InterfaceInfo interfaceInfo)
protected
257 {
258  NetworkInterface *networkInterface = interfaceInfo->networkInterface;
259  auto interfaceData = networkInterface->getProtocolDataForUpdate<Ieee8021dInterfaceData>();
260 
261  interfaceData->setLinkCost(interfaceInfo->portData.linkCost);
262  interfaceData->setPriority(interfaceInfo->portData.priority);
263  interfaceData->setEdge(interfaceInfo->portData.edge);
264 }

Referenced by configureInterface().

◆ configureInterface() [2/2]

void inet::L2NetworkConfigurator::configureInterface ( NetworkInterface networkInterface)
virtual

Configures the provided interface based on the current network configuration.

240 {
242  cModule *networkNodeModule = findContainingNode(networkInterface);
243  // TODO avoid linear search
244  for (int i = 0; i < topology.getNumNodes(); i++) {
245  Node *node = (Node *)topology.getNode(i);
246  if (node->module == networkNodeModule) {
247  for (auto& elem : node->interfaceInfos) {
248  InterfaceInfo *interfaceInfo = elem;
249  if (interfaceInfo->networkInterface == networkInterface)
250  return configureInterface(interfaceInfo);
251  }
252  }
253  }
254 }

◆ ensureConfigurationComputed()

void inet::L2NetworkConfigurator::ensureConfigurationComputed ( L2Topology topology)
protected
203 {
204  if (topology.getNumNodes() == 0)
206 }

Referenced by configureInterface(), and initialize().

◆ extractTopology()

void inet::L2NetworkConfigurator::extractTopology ( L2Topology topology)
protectedvirtual

Extracts network topology by walking through the module hierarchy.

Creates vertices from modules having @networkNode property. Creates edges from connections (wired and wireless) between network interfaces.

40 {
41  topology.extractByProperty("networkNode");
42  EV_DEBUG << "Topology found " << topology.getNumNodes() << " nodes\n";
43 
44  if (topology.getNumNodes() == 0)
45  throw cRuntimeError("Empty network!");
46 
47  // extract nodes, fill in interfaceTable and routingTable members in node
48  for (int i = 0; i < topology.getNumNodes(); i++) {
49  Node *node = (Node *)topology.getNode(i);
50  node->module = node->getModule();
51  cModule *ifTable = node->module->getSubmodule("interfaceTable");
52 
53  // EthernetHost has no InterfaceTable
54  if (ifTable) // todo:
55  node->interfaceTable = dynamic_cast<IInterfaceTable *>(ifTable);
56  }
57 
58  // extract links and interfaces
59  std::set<NetworkInterface *> interfacesSeen;
60  std::queue<Node *> Q; // unvisited nodes in the graph
61 
62  rootNode = (Node *)topology.getNode(0);
63  Q.push(rootNode);
64 
65  while (!Q.empty()) {
66  Node *node = Q.front();
67  Q.pop();
68  IInterfaceTable *interfaceTable = node->interfaceTable;
69 
70  if (interfaceTable) {
71  // push neighbors to the queue
72  for (int i = 0; i < interfaceTable->getNumInterfaces(); i++) {
73  NetworkInterface *networkInterface = interfaceTable->getInterface(i);
74  if (interfacesSeen.count(networkInterface) == 0) {
75  // visiting this interface
76  interfacesSeen.insert(networkInterface);
77 
78  Topology::Link *linkOut = findLinkOut(node, networkInterface->getNodeOutputGateId());
79 
80  Node *childNode = nullptr;
81 
82  if (linkOut) {
83  childNode = (Node *)linkOut->getLinkOutRemoteNode();
84  Q.push(childNode);
85  }
86 
87  InterfaceInfo *info = new InterfaceInfo(node, childNode, networkInterface);
88  node->interfaceInfos.push_back(info);
89  }
90  }
91  }
92  }
93 }

Referenced by computeConfiguration().

◆ findLinkOut()

Topology::Link * inet::L2NetworkConfigurator::findLinkOut ( Node node,
int  gateId 
)
protectedvirtual
209 {
210  for (int i = 0; i < node->getNumOutLinks(); i++)
211  if (node->getLinkOut(i)->getLinkOutLocalGateId() == gateId)
212  return node->getLinkOut(i);
213 
214  return nullptr;
215 }

Referenced by extractTopology().

◆ handleMessage()

virtual void inet::L2NetworkConfigurator::handleMessage ( cMessage *  msg)
inlineoverrideprotectedvirtual
97 { throw cRuntimeError("this module doesn't handle messages, it runs only in initialize()"); }

◆ initialize()

void inet::L2NetworkConfigurator::initialize ( int  stage)
overrideprotectedvirtual
25 {
26  if (stage == INITSTAGE_LOCAL)
27  configuration = par("config");
28  else if (stage == INITSTAGE_NETWORK_CONFIGURATION)
30 }

◆ linkContainsMatchingHostExcept()

bool inet::L2NetworkConfigurator::linkContainsMatchingHostExcept ( InterfaceInfo currentInfo,
Matcher hostMatcher,
cModule *  exceptModule 
)
protectedvirtual
219 {
220  Node *childNode = currentInfo->childNode;
221 
222  if (childNode == nullptr)
223  return false;
224 
225  cModule *hostModule = childNode->module;
226 
227  std::string hostFullPath = hostModule->getFullPath();
228  std::string hostShortenedFullPath = hostFullPath.substr(hostFullPath.find('.') + 1);
229 
230  if (hostModule == exceptModule)
231  return false;
232 
233  if (hostMatcher.matches(hostShortenedFullPath.c_str()) || hostMatcher.matches(hostFullPath.c_str()))
234  return true;
235 
236  return false;
237 }

Referenced by readInterfaceConfiguration().

◆ numInitStages()

virtual int inet::L2NetworkConfigurator::numInitStages ( ) const
inlineoverrideprotectedvirtual
96 { return NUM_INIT_STAGES; }

◆ readInterfaceConfiguration()

void inet::L2NetworkConfigurator::readInterfaceConfiguration ( Node rootNode)
virtual

Reads interface elements from the configuration file and stores result.

96 {
97  std::set<NetworkInterface *> matchedBefore;
98  cXMLElementList interfaceElements = configuration->getChildrenByTagName("interface");
99 
100  for (auto& interfaceElements_i : interfaceElements) {
101  std::set<NetworkInterface *> interfacesSeen;
102  cXMLElement *interfaceElement = interfaceElements_i;
103 
104  const char *hostAttr = interfaceElement->getAttribute("hosts"); // "host* router[0..3]"
105  const char *interfaceAttr = interfaceElement->getAttribute("names"); // i.e. interface names, like "eth* ppp0"
106  const char *towardsAttr = interfaceElement->getAttribute("towards"); // neighbor host names, like "ap switch"
107  const char *amongAttr = interfaceElement->getAttribute("among"); // neighbor host names, like "host[*] router1"
108  const char *portsAttr = interfaceElement->getAttribute("ports"); // switch gate indices, like "0 1 2"
109 
110  // Begin RSTP properties, for more information see RSTP module
111  const char *cost = interfaceElement->getAttribute("cost");
112  const char *priority = interfaceElement->getAttribute("priority");
113  const char *edge = interfaceElement->getAttribute("edge");
114  // End RSTP properties
115 
116  if (amongAttr && *amongAttr) { // among="X Y Z" means hosts = "X Y Z" towards = "X Y Z"
117  if ((hostAttr && *hostAttr) || (towardsAttr && *towardsAttr))
118  throw cRuntimeError("The 'hosts'/'towards' and 'among' attributes are mutually exclusive, at %s",
119  interfaceElement->getSourceLocation());
120  towardsAttr = hostAttr = amongAttr;
121  }
122 
123  try {
124  // parse host/interface/towards expressions
125  Matcher hostMatcher(hostAttr);
126  Matcher interfaceMatcher(interfaceAttr);
127  Matcher towardsMatcher(towardsAttr);
128  Matcher portsMatcher(portsAttr);
129 
130  std::queue<Node *> Q;
131  Q.push(rootNode);
132 
133  // configure port type/cost/priority constraints on matching interfaces
134  while (!Q.empty()) {
135  Node *currentNode = Q.front();
136  Q.pop();
137 
138  for (unsigned int i = 0; i < currentNode->interfaceInfos.size(); i++) {
139  NetworkInterface *ifEntry = currentNode->interfaceInfos[i]->networkInterface;
140  if (interfacesSeen.count(ifEntry) == 0 && matchedBefore.count(ifEntry) == 0) {
141  cModule *hostModule = currentNode->module;
142  std::string hostFullPath = hostModule->getFullPath();
143  std::string hostShortenedFullPath = hostFullPath.substr(hostFullPath.find('.') + 1);
144 
145  // loopback interfaces
146  if (ifEntry->getNodeInputGateId() == -1) {
147  interfacesSeen.insert(ifEntry);
148  continue;
149  }
150 
151  cGate *gate = hostModule->gate(ifEntry->getNodeInputGateId());
152  std::stringstream ss;
153  ss << gate->getIndex();
154  std::string port = ss.str();
155 
156  // Note: "hosts", "interfaces" and "towards" must ALL match on the interface for the rule to apply
157  if ((hostMatcher.matchesAny() || hostMatcher.matches(hostShortenedFullPath.c_str()) || hostMatcher.matches(hostFullPath.c_str()))
158  && (interfaceMatcher.matchesAny() || interfaceMatcher.matches(ifEntry->getInterfaceName()))
159  && (towardsMatcher.matchesAny() || linkContainsMatchingHostExcept(currentNode->interfaceInfos[i], towardsMatcher, hostModule))
160  && (portsMatcher.matchesAny() || portsMatcher.matches(port.c_str())))
161  {
162  // cost
163  if (!opp_isempty(cost))
164  currentNode->interfaceInfos[i]->portData.linkCost = atoi(cost);
165 
166  // priority
167  if (!opp_isempty(priority))
168  currentNode->interfaceInfos[i]->portData.priority = atoi(priority);
169 
170  // edge
171  if (!opp_isempty(edge))
172  currentNode->interfaceInfos[i]->portData.edge = strcmp(edge, "true") ? false : true;
173  EV_DEBUG << hostModule->getFullPath() << ":" << ifEntry->getInterfaceName() << endl;
174 
175  matchedBefore.insert(ifEntry);
176  }
177 
178  interfacesSeen.insert(ifEntry);
179  if (currentNode->interfaceInfos[i]->childNode)
180  Q.push(currentNode->interfaceInfos[i]->childNode);
181  }
182  }
183  }
184  }
185  catch (std::exception& e) {
186  throw cRuntimeError("Error in XML <interface> element at %s: %s", interfaceElement->getSourceLocation(),
187  e.what());
188  }
189  }
190 }

Referenced by computeConfiguration().

Member Data Documentation

◆ configuration

cXMLElement* inet::L2NetworkConfigurator::configuration = nullptr
protected

◆ rootNode

Node* inet::L2NetworkConfigurator::rootNode = nullptr
protected

◆ topology

L2Topology inet::L2NetworkConfigurator::topology
protected

The documentation for this class was generated from the following files:
inet::findContainingNode
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
inet::INITSTAGE_NETWORK_CONFIGURATION
INET_API InitStage INITSTAGE_NETWORK_CONFIGURATION
Initialization of network configuration (e.g.
inet::L2NetworkConfigurator::readInterfaceConfiguration
virtual void readInterfaceConfiguration(Node *rootNode)
Reads interface elements from the configuration file and stores result.
Definition: L2NetworkConfigurator.cc:95
inet::L2NetworkConfigurator::Node::interfaceTable
IInterfaceTable * interfaceTable
Definition: L2NetworkConfigurator.h:39
inet::L2NetworkConfigurator::configureInterface
void configureInterface(InterfaceInfo *interfaceInfo)
Definition: L2NetworkConfigurator.cc:256
inet::L2NetworkConfigurator::findLinkOut
virtual Topology::Link * findLinkOut(Node *node, int gateId)
Definition: L2NetworkConfigurator.cc:208
inet::units::constants::e
const value< double, units::C > e(1.602176487e-19)
inet::Topology::getNode
Node * getNode(int i) const
Returns pointer to the ith node in the graph.
Definition: Topology.cc:348
inet::Topology::extractByProperty
void extractByProperty(const char *propertyName, const char *value=nullptr)
Extracts model topology by a module property.
Definition: Topology.cc:149
inet::L2NetworkConfigurator::computeConfiguration
virtual void computeConfiguration()
Computes the Layer 2 network configuration for all nodes in the network.
Definition: L2NetworkConfigurator.cc:192
inet::L2NetworkConfigurator::extractTopology
virtual void extractTopology(L2Topology &topology)
Extracts network topology by walking through the module hierarchy.
Definition: L2NetworkConfigurator.cc:39
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::L2NetworkConfigurator::configuration
cXMLElement * configuration
Definition: L2NetworkConfigurator.h:90
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::Topology::getNumNodes
int getNumNodes() const
Returns the number of nodes in the graph.
Definition: Topology.h:516
inet::L2NetworkConfigurator::topology
L2Topology topology
Definition: L2NetworkConfigurator.h:91
TIME
#define TIME(CODE)
Definition: INETDefs.h:96
inet::L2NetworkConfigurator::linkContainsMatchingHostExcept
virtual bool linkContainsMatchingHostExcept(InterfaceInfo *currentInfo, Matcher &hostMatcher, cModule *exceptModule)
Definition: L2NetworkConfigurator.cc:217
inet::IInterfaceTable::getInterface
virtual NetworkInterface * getInterface(int pos) const =0
Returns the NetworkInterface specified by an index 0..numInterfaces-1.
inet::L2NetworkConfigurator::rootNode
Node * rootNode
Definition: L2NetworkConfigurator.h:92
inet::printElapsedTime
void printElapsedTime(const char *name, long startTime)
Definition: INETDefs.h:91
inet::L2NetworkConfigurator::Node::module
cModule * module
Definition: L2NetworkConfigurator.h:38
inet::L2NetworkConfigurator::ensureConfigurationComputed
void ensureConfigurationComputed(L2Topology &topology)
Definition: L2NetworkConfigurator.cc:202