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

#include <FailureProtectionConfigurator.h>

Inheritance diagram for inet::FailureProtectionConfigurator:
inet::NetworkConfiguratorBase

Classes

class  Path
 
class  StreamConfiguration
 
class  Tree
 

Public Member Functions

const std::vector< StreamConfiguration > & getStreams () const
 

Static Public Member Functions

static NodefindConnectedNode (const Interface *interface)
 
static int countParalellLinks (const Interface *interface)
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual void computeConfiguration ()
 Computes the network configuration for all nodes in the network. More...
 
virtual void computeStreams ()
 
virtual void computeStream (cValueMap *streamConfiguration)
 
virtual std::vector< TreeselectBestTreeSubset (cValueMap *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
 
virtual double computeTreeCost (const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const Tree &tree) const
 
virtual Tree computeCanonicalTree (const Tree &tree) const
 
virtual bool checkNodeFailureProtection (cValueArray *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
 
virtual bool checkLinkFailureProtection (cValueArray *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
 
virtual void configureStreams () const
 
virtual std::vector< TreecollectAllTrees (Node *sourceNode, const std::vector< const Node * > &destinationNodes) const
 
virtual void collectAllTrees (const std::vector< const Node * > &stopNodes, const std::vector< const Node * > &destinationNodes, int destinationNodeIndex, std::vector< Path > &currentTree, std::vector< Tree > &allTrees) const
 
virtual std::vector< PathcollectAllPaths (const std::vector< const Node * > &stopNodes, const Node *destinationNode) const
 
virtual void collectAllPaths (const std::vector< const Node * > &stopNodes, const Node *currentNode, std::vector< const Interface * > &currentPath, std::vector< Path > &allPaths) const
 
virtual std::vector< const Node * > collectNetworkNodes (const std::string &filter) const
 
virtual std::vector< const Link * > collectNetworkLinks (const std::string &filter) const
 
virtual void collectReachedNodes (const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const Tree &tree, const std::vector< const Node * > &failedNodes, std::vector< bool > &reachedDestinationNodes) const
 
virtual void collectReachedNodes (const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const Tree &tree, const std::vector< const Link * > &failedLinks, std::vector< bool > &reachedDestinationNodes) const
 
virtual bool matchesFilter (const std::string &name, const std::string &filter) const
 
- Protected Member Functions inherited from inet::NetworkConfiguratorBase
virtual ~NetworkConfiguratorBase ()
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void extractTopology (Topology &topology)
 Extracts network topology by walking through the module hierarchy. More...
 
virtual std::vector< Node * > computeShortestNodePath (Node *source, Node *destination) const
 
virtual std::vector< Link * > computeShortestLinkPath (Node *source, Node *destination) const
 
virtual bool isBridgeNode (Node *node) const
 
virtual LinkfindLinkIn (const Node *node, const char *neighbor) const
 
virtual LinkfindLinkOut (const Node *node, const char *neighbor) const
 
virtual LinkfindLinkOut (const Node *node, const Node *neighbor) const
 
virtual LinkfindLinkOut (const Interface *interface) const
 
virtual Topology::LinkfindLinkOut (const Node *node, int gateId) const
 
virtual InterfacefindInterface (const Node *node, NetworkInterface *networkInterface) const
 

Protected Attributes

cValueArray * configuration
 
std::vector< StreamConfigurationstreamConfigurations
 
- Protected Attributes inherited from inet::NetworkConfiguratorBase
Topologytopology = nullptr
 

Member Function Documentation

◆ checkLinkFailureProtection()

bool inet::FailureProtectionConfigurator::checkLinkFailureProtection ( cValueArray *  configuration,
const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const std::vector< Tree > &  trees 
) const
protectedvirtual
259 {
260  EV_DETAIL << "Checking trees for link failure protection" << EV_ENDL;
261  for (auto& tree : trees)
262  EV_DETAIL << " " << tree << std::endl;
263  for (int i = 0; i < configuration->size(); i++) {
264  cValueMap *protection = check_and_cast<cValueMap *>(configuration->get(i).objectValue());
265  auto of = protection->containsKey("of") ? protection->get("of").stringValue() : "*";
266  auto networkLinks = collectNetworkLinks(of);
267  int n = networkLinks.size();
268  int k = protection->get("any").intValue();
269  std::vector<bool> mask(k, true); // k leading 1's
270  mask.resize(n, false); // n-k trailing 0's
271  EV_DETAIL << "Checking link failure protection for " << k << " failed links out of " << networkLinks.size() << " links" << EV_ENDL;
272  do {
273  EV_DEBUG << "Assuming failed links: ";
274  std::vector<const Link *> failedLinks;
275  bool first = true;
276  for (int i = 0; i < n; i++) {
277  if (mask[i]) {
278  auto link = (Link *)networkLinks[i];
279  if (!first) { EV_DEBUG << ", "; first = false; }
280  EV_DEBUG << link->sourceInterface->node->module->getFullName() << "." << link->sourceInterface->networkInterface->getInterfaceName() << " -> " << link->destinationInterface->node->module->getFullName() << "." << link->destinationInterface->networkInterface->getInterfaceName();
281  failedLinks.push_back(networkLinks[i]);
282  }
283  }
284  EV_DEBUG << std::endl;
285  std::vector<bool> reachedDestinationNodes;
286  reachedDestinationNodes.resize(destinationNodes.size(), false);
287  for (int i = 0; i < trees.size(); i++)
288  collectReachedNodes(sourceNode, destinationNodes, trees[i], failedLinks, reachedDestinationNodes);
289  bool isProtected = std::all_of(reachedDestinationNodes.begin(), reachedDestinationNodes.end(), [] (bool v) { return v; });
290  EV_DEBUG << "Link failure protection " << (isProtected ? "succeeded" : "failed") << EV_ENDL;
291  if (!isProtected)
292  return false;
293  } while (std::prev_permutation(mask.begin(), mask.end()));
294  EV_DETAIL << "Link failure protection succeeded for " << k << " failed links out of " << networkLinks.size() << " links" << EV_ENDL;
295  }
296  return true;
297 }

Referenced by selectBestTreeSubset().

◆ checkNodeFailureProtection()

bool inet::FailureProtectionConfigurator::checkNodeFailureProtection ( cValueArray *  configuration,
const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const std::vector< Tree > &  trees 
) const
protectedvirtual
218 {
219  EV_DETAIL << "Checking trees for node failure protection" << EV_ENDL;
220  for (auto& tree : trees)
221  EV_DETAIL << " " << tree << std::endl;
222  for (int i = 0; i < configuration->size(); i++) {
223  cValueMap *protection = check_and_cast<cValueMap *>(configuration->get(i).objectValue());
224  auto of = protection->containsKey("of") ? protection->get("of").stringValue() : "*";
225  auto networkNodes = collectNetworkNodes(of);
226  int n = networkNodes.size();
227  int k = protection->get("any").intValue();
228  std::vector<bool> mask(k, true); // k leading 1's
229  mask.resize(n, false); // n-k trailing 0's
230  EV_DETAIL << "Checking node failure protection for " << k << " failed nodes out of " << networkNodes.size() << " nodes" << EV_ENDL;
231  do {
232  EV_DEBUG << "Assuming failed nodes: ";
233  std::vector<const Node *> failedNodes;
234  bool first = true;
235  for (int i = 0; i < n; i++) {
236  if (mask[i]) {
237  auto node = networkNodes[i];
238  if (!first) { EV_DEBUG << ", "; first = false; }
239  EV_DEBUG << node->module->getFullName();
240  failedNodes.push_back(node);
241  }
242  }
243  EV_DEBUG << std::endl;
244  std::vector<bool> reachedDestinationNodes;
245  reachedDestinationNodes.resize(destinationNodes.size(), false);
246  for (int i = 0; i < trees.size(); i++)
247  collectReachedNodes(sourceNode, destinationNodes, trees[i], failedNodes, reachedDestinationNodes);
248  bool isProtected = std::all_of(reachedDestinationNodes.begin(), reachedDestinationNodes.end(), [] (bool v) { return v; });
249  EV_DEBUG << "Node failure protection " << (isProtected ? "succeeded" : "failed") << EV_ENDL;
250  if (!isProtected)
251  return false;
252  } while (std::prev_permutation(mask.begin(), mask.end()));
253  EV_DETAIL << "Node failure protection succeeded for " << k << " failed nodes out of " << networkNodes.size() << " nodes" << EV_ENDL;
254  }
255  return true;
256 }

Referenced by selectBestTreeSubset().

◆ collectAllPaths() [1/2]

void inet::FailureProtectionConfigurator::collectAllPaths ( const std::vector< const Node * > &  stopNodes,
const Node currentNode,
std::vector< const Interface * > &  currentPath,
std::vector< Path > &  allPaths 
) const
protectedvirtual
415 {
416  if (std::find(stopNodes.begin(), stopNodes.end(), currentNode) != stopNodes.end()) {
417  allPaths.push_back(Path(currentPath));
418  std::reverse(allPaths.back().interfaces.begin(), allPaths.back().interfaces.end());
419  }
420  else {
421  for (int i = 0; i < currentNode->getNumPaths(); i++) {
422  auto link = (Link *)currentNode->getPath(i);
423  auto nextNode = (Node *)currentNode->getPath(i)->getLinkOutRemoteNode();
424  if (std::find_if(currentPath.begin(), currentPath.end(), [&] (const Interface *interface) { return interface->node == nextNode; }) == currentPath.end()) {
425  bool first = currentPath.empty();
426  if (first)
427  currentPath.push_back(link->sourceInterface);
428  currentPath.push_back(link->destinationInterface);
429  collectAllPaths(stopNodes, nextNode, currentPath, allPaths);
430  currentPath.erase(currentPath.end() - (first ? 2 : 1), currentPath.end());
431  }
432  }
433  }
434 }

◆ collectAllPaths() [2/2]

std::vector< FailureProtectionConfigurator::Path > inet::FailureProtectionConfigurator::collectAllPaths ( const std::vector< const Node * > &  stopNodes,
const Node destinationNode 
) const
protectedvirtual
407 {
408  std::vector<Path> allPaths;
409  std::vector<const Interface *> currentPath;
410  collectAllPaths(stopNodes, destinationNode, currentPath, allPaths);
411  return allPaths;
412 }

◆ collectAllTrees() [1/2]

void inet::FailureProtectionConfigurator::collectAllTrees ( const std::vector< const Node * > &  stopNodes,
const std::vector< const Node * > &  destinationNodes,
int  destinationNodeIndex,
std::vector< Path > &  currentTree,
std::vector< Tree > &  allTrees 
) const
protectedvirtual
384 {
385  if (destinationNodes.size() == destinationNodeIndex)
386  allTrees.push_back(computeCanonicalTree(currentTree));
387  else {
388  auto destinationNode = destinationNodes[destinationNodeIndex];
389  if (std::find(stopNodes.begin(), stopNodes.end(), destinationNode) != stopNodes.end())
390  collectAllTrees(stopNodes, destinationNodes, destinationNodeIndex + 1, currentTree, allTrees);
391  else {
392  auto allPaths = collectAllPaths(stopNodes, destinationNode);
393  for (auto& path : allPaths) {
394  auto destinationStopNodes = stopNodes;
395  for (auto interface : path.interfaces)
396  if (std::find(destinationStopNodes.begin(), destinationStopNodes.end(), interface->node) == destinationStopNodes.end())
397  destinationStopNodes.push_back(interface->node);
398  currentTree.push_back(path);
399  collectAllTrees(destinationStopNodes, destinationNodes, destinationNodeIndex + 1, currentTree, allTrees);
400  currentTree.erase(currentTree.end() - 1);
401  }
402  }
403  }
404 }

◆ collectAllTrees() [2/2]

std::vector< FailureProtectionConfigurator::Tree > inet::FailureProtectionConfigurator::collectAllTrees ( Node sourceNode,
const std::vector< const Node * > &  destinationNodes 
) const
protectedvirtual
373 {
374  std::vector<Tree> allTrees;
376  std::vector<Path> currentTree;
377  std::vector<const Node *> stopNodes;
378  stopNodes.push_back(sourceNode);
379  collectAllTrees(stopNodes, destinationNodes, 0, currentTree, allTrees);
380  return allTrees;
381 }

Referenced by computeStream().

◆ collectNetworkLinks()

std::vector< const FailureProtectionConfigurator::Link * > inet::FailureProtectionConfigurator::collectNetworkLinks ( const std::string &  filter) const
protectedvirtual
449 {
450  std::vector<const Link *> result;
451  for (int i = 0; i < topology->getNumNodes(); i++) {
452  auto localNode = (Node *)topology->getNode(i);
453  std::string localName = localNode->module->getFullName();
454  for (int j = 0; j < localNode->getNumOutLinks(); j++) {
455  auto link = localNode->getLinkOut(j);
456  auto remoteNode = (Node *)link->getLinkOutRemoteNode();
457  std::string remoteName = remoteNode->module->getFullName();
458  std::string linkName = localName + "->" + remoteName;
459  if (matchesFilter(linkName.c_str(), filter))
460  result.push_back((Link *)link);
461  }
462  }
463  return result;
464 }

◆ collectNetworkNodes()

std::vector< const FailureProtectionConfigurator::Node * > inet::FailureProtectionConfigurator::collectNetworkNodes ( const std::string &  filter) const
protectedvirtual
437 {
438  std::vector<const Node *> result;
439  for (int i = 0; i < topology->getNumNodes(); i++) {
440  auto node = (Node *)topology->getNode(i);
441  auto name = node->module->getFullName();
442  if (matchesFilter(name, filter))
443  result.push_back(node);
444  }
445  return result;
446 }

◆ collectReachedNodes() [1/2]

void inet::FailureProtectionConfigurator::collectReachedNodes ( const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const Tree tree,
const std::vector< const Link * > &  failedLinks,
std::vector< bool > &  reachedDestinationNodes 
) const
protectedvirtual
490 {
491  std::deque<const Node *> todoNodes;
492  todoNodes.push_back(sourceNode);
493  while (!todoNodes.empty()) {
494  auto startNode = todoNodes.front();
495  todoNodes.pop_front();
496  for (auto path : tree.paths) {
497  if (path.interfaces[0]->node == startNode) {
498  const Interface *previousInterface = nullptr;
499  for (auto interface : path.interfaces) {
500  if (previousInterface != nullptr) {
501  Link *pathLink = findLinkOut(previousInterface);
502  if (pathLink->destinationInterface->node != interface->node)
503  pathLink = findLinkOut(previousInterface->node, interface->node);
504  if (std::find(failedLinks.begin(), failedLinks.end(), pathLink) != failedLinks.end())
505  break;
506  }
507  auto it = std::find_if(destinationNodes.begin(), destinationNodes.end(), [&] (const Node *node) { return interface->node == node; });
508  if (it != destinationNodes.end())
509  reachedDestinationNodes[it - destinationNodes.begin()] = true;
510  if (interface->node != startNode)
511  todoNodes.push_back(interface->node);
512  previousInterface = interface;
513  }
514  }
515  }
516  }
517 }

◆ collectReachedNodes() [2/2]

void inet::FailureProtectionConfigurator::collectReachedNodes ( const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const Tree tree,
const std::vector< const Node * > &  failedNodes,
std::vector< bool > &  reachedDestinationNodes 
) const
protectedvirtual
467 {
468  std::deque<const Node *> todoNodes;
469  todoNodes.push_back(sourceNode);
470  while (!todoNodes.empty()) {
471  auto startNode = todoNodes.front();
472  todoNodes.pop_front();
473  for (auto path : tree.paths) {
474  if (path.interfaces[0]->node == startNode) {
475  for (auto interface : path.interfaces) {
476  if (std::find(failedNodes.begin(), failedNodes.end(), interface->node) != failedNodes.end())
477  break;
478  auto it = std::find_if(destinationNodes.begin(), destinationNodes.end(), [&] (const Node *node) { return interface->node == node; });
479  if (it != destinationNodes.end())
480  reachedDestinationNodes[it - destinationNodes.begin()] = true;
481  if (interface->node != startNode)
482  todoNodes.push_back(interface->node);
483  }
484  }
485  }
486  }
487 }

◆ computeCanonicalTree()

FailureProtectionConfigurator::Tree inet::FailureProtectionConfigurator::computeCanonicalTree ( const Tree tree) const
protectedvirtual
167 {
168  Tree canonicalTree({});
169  for (auto& path : tree.paths) {
170  auto startInterface = path.interfaces[0];
171  auto itStart = std::find_if(canonicalTree.paths.begin(), canonicalTree.paths.end(), [&] (auto path) {
172  return path.interfaces.front()->node == startInterface->node;
173  });
174  if (itStart != canonicalTree.paths.end())
175  // just insert the path into the tree
176  canonicalTree.paths.push_back(path);
177  else {
178  auto itEnd = std::find_if(canonicalTree.paths.begin(), canonicalTree.paths.end(), [&] (auto path) {
179  return path.interfaces.back()->node == startInterface->node;
180  });
181  if (itEnd != canonicalTree.paths.end()) {
182  // append the path to a path that is already in the tree
183  auto& canonicalPath = *itEnd;
184  canonicalPath.interfaces.insert(canonicalPath.interfaces.end(), path.interfaces.begin() + 1, path.interfaces.end());
185  }
186  else {
187  auto itMiddle = std::find_if(canonicalTree.paths.begin(), canonicalTree.paths.end(), [&] (auto path) {
188  auto jt = std::find_if(path.interfaces.begin(), path.interfaces.end(), [&] (auto interface) {
189  return interface->node == startInterface->node;
190  });
191  return jt != path.interfaces.end();
192  });
193  if (itMiddle == canonicalTree.paths.end())
194  // just insert the path into the tree
195  canonicalTree.paths.push_back(path);
196  else {
197  // split an existing path that is already in the tree and insert the path into the tree
198  auto& canonicalPath = *itMiddle;
199  auto it = std::find_if(canonicalPath.interfaces.begin(), canonicalPath.interfaces.end(), [&] (auto interface) {
200  return interface->node == startInterface->node;
201  });
202  Path firstPathFragment({});
203  Path secondPathFragment({});
204  firstPathFragment.interfaces.insert(firstPathFragment.interfaces.begin(), canonicalPath.interfaces.begin(), it + 1);
205  secondPathFragment.interfaces.insert(secondPathFragment.interfaces.begin(), it, canonicalPath.interfaces.end());
206  canonicalTree.paths.erase(itMiddle);
207  canonicalTree.paths.push_back(firstPathFragment);
208  canonicalTree.paths.push_back(secondPathFragment);
209  canonicalTree.paths.push_back(path);
210  }
211  }
212  }
213  }
214  return canonicalTree;
215 }

◆ computeConfiguration()

void inet::FailureProtectionConfigurator::computeConfiguration ( )
protectedvirtual

Computes the network configuration for all nodes in the network.

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

29 {
30  long initializeStartTime = clock();
31  delete topology;
32  topology = new Topology();
35  printElapsedTime("initialize", initializeStartTime);
36 }

Referenced by initialize().

◆ computeStream()

void inet::FailureProtectionConfigurator::computeStream ( cValueMap *  streamConfiguration)
protectedvirtual
47 {
48  auto streamName = configuration->get("name").stringValue();
49  StreamConfiguration streamConfiguration;
50  streamConfiguration.name = streamName;
51  if (configuration->containsKey("pcp"))
52  streamConfiguration.pcp = configuration->get("pcp").intValue();
53  if (configuration->containsKey("gateIndex"))
54  streamConfiguration.gateIndex = configuration->get("gateIndex").intValue();
55  streamConfiguration.packetFilter = configuration->get("packetFilter");
56  auto sourceNetworkNodeName = configuration->get("source").stringValue();
57  streamConfiguration.source = sourceNetworkNodeName;
58  Node *sourceNode = static_cast<Node *>(topology->getNodeFor(getParentModule()->getSubmodule(sourceNetworkNodeName)));
59  std::vector<const Node *> destinationNodes;
60  cMatchExpression destinationFilter;
61  destinationFilter.setPattern(configuration->get("destination").stringValue(), false, false, true);
62  for (int i = 0; i < topology->getNumNodes(); i++) {
63  auto node = (Node *)topology->getNode(i);
64  MatchableObject matchableObject(MatchableObject::ATTRIBUTE_FULLNAME, node->module);
65  if (destinationFilter.matches(&matchableObject)) {
66  destinationNodes.push_back(node);
67  streamConfiguration.destinations.push_back(node->module->getFullName());
68  }
69  }
70  auto sourceNodeName = sourceNode->module->getFullName();
71  std::stringstream destinationNodeNames;
72  destinationNodeNames << "[";
73  for (int i = 0; i < destinationNodes.size(); i++) {
74  if (i != 0)
75  destinationNodeNames << ", ";
76  destinationNodeNames << destinationNodes[i]->module->getFullName();
77  }
78  destinationNodeNames << "]";
79  EV_INFO << "Computing stream configuration" << EV_FIELD(streamName) << EV_FIELD(sourceNodeName) << EV_FIELD(destinationNodeNames) << EV_ENDL;
80  streamConfiguration.destinationAddress = configuration->containsKey("destinationAddress") ? configuration->get("destinationAddress").stringValue() : streamConfiguration.destinations[0];
81  EV_INFO << "Collecting all possible trees" << EV_FIELD(streamName) << EV_ENDL;
82  auto allTrees = collectAllTrees(sourceNode, destinationNodes);
83  for (auto tree : allTrees)
84  EV_INFO << " Found tree" << EV_FIELD(streamName) << EV_FIELD(tree) << std::endl;
85  EV_INFO << "Selecting best tree subset" << EV_FIELD(streamName) << EV_ENDL;
86  streamConfiguration.trees = selectBestTreeSubset(configuration, sourceNode, destinationNodes, allTrees);
87  EV_INFO << "Smallest tree subset having the best cost that still provide failure protection" << EV_FIELD(streamName) << EV_FIELD(sourceNodeName) << EV_FIELD(destinationNodeNames) << EV_ENDL;
88  for (auto tree : streamConfiguration.trees)
89  EV_INFO << " Selected tree" << EV_FIELD(streamName) << EV_FIELD(tree) << std::endl;
90  streamConfigurations.push_back(streamConfiguration);
91 }

Referenced by computeStreams().

◆ computeStreams()

void inet::FailureProtectionConfigurator::computeStreams ( )
protectedvirtual
39 {
40  for (int i = 0; i < configuration->size(); i++) {
41  cValueMap *streamConfiguration = check_and_cast<cValueMap *>(configuration->get(i).objectValue());
42  computeStream(streamConfiguration);
43  }
44 }

Referenced by computeConfiguration().

◆ computeTreeCost()

double inet::FailureProtectionConfigurator::computeTreeCost ( const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const Tree tree 
) const
protectedvirtual
136 {
137  double cost = 0;
138  // sum up the total number of links in the shortest paths to all destinations
139  for (auto destinationNode : destinationNodes) {
140  std::deque<std::pair<const Node *, int>> todoNodes;
141  todoNodes.push_back({sourceNode, 0});
142  while (!todoNodes.empty()) {
143  auto it = todoNodes.front();
144  todoNodes.pop_front();
145  auto startNode = it.first;
146  auto startCost = it.second;
147  for (auto path : tree.paths) {
148  if (path.interfaces[0]->node == startNode) {
149  for (int i = 0; i < path.interfaces.size(); i++) {
150  auto interface = path.interfaces[i];
151  if (interface->node == destinationNode) {
152  cost += startCost + i;
153  goto nextDestinationNode;
154  }
155  if (interface->node != startNode)
156  todoNodes.push_back({interface->node, startCost + i});
157  }
158  }
159  }
160  }
161  nextDestinationNode:;
162  }
163  return cost;
164 }

Referenced by selectBestTreeSubset().

◆ configureStreams()

void inet::FailureProtectionConfigurator::configureStreams ( ) const
protectedvirtual
300 {
301  const char *streamRedundancyConfiguratorModulePath = par("streamRedundancyConfiguratorModule");
302  if (strlen(streamRedundancyConfiguratorModulePath) != 0) {
303  auto streamRedundancyConfigurator = check_and_cast<StreamRedundancyConfigurator *>(getModuleByPath(streamRedundancyConfiguratorModulePath));
304  cValueArray *streamsParameterValue = new cValueArray();
305  for (auto& streamConfiguration : streamConfigurations) {
306  cValueMap *streamParameterValue = new cValueMap();
307  cValueArray *treesParameterValue = new cValueArray();
308  streamParameterValue->set("name", streamConfiguration.name.c_str());
309  streamParameterValue->set("pcp", streamConfiguration.pcp);
310  streamParameterValue->set("packetFilter", streamConfiguration.packetFilter);
311  streamParameterValue->set("source", streamConfiguration.source.c_str());
312  // TODO KLUDGE
313  streamParameterValue->set("destination", streamConfiguration.destinations[0].c_str());
314  streamParameterValue->set("destinationAddress", streamConfiguration.destinationAddress.c_str());
315  for (auto& tree : streamConfiguration.trees) {
316  cValueArray *treeParameterValue = new cValueArray();
317  for (auto& path : tree.paths) {
318  cValueArray *pathParameterValue = new cValueArray();
319  for (auto& interface : path.interfaces) {
320  std::string name;
321  name = interface->node->module->getFullName();
323  name = name + "." + interface->networkInterface->getInterfaceName();
324  pathParameterValue->add(name.c_str());
325  }
326  treeParameterValue->add(pathParameterValue);
327  }
328  treesParameterValue->add(treeParameterValue);
329  }
330  streamParameterValue->set("trees", treesParameterValue);
331  streamsParameterValue->add(streamParameterValue);
332  }
333  EV_INFO << "Configuring stream configurator" << EV_FIELD(streamRedundancyConfigurator) << EV_FIELD(streamsParameterValue) << EV_ENDL;
334  streamRedundancyConfigurator->par("configuration") = streamsParameterValue;
335  const char *gateScheduleConfiguratorModulePath = par("gateScheduleConfiguratorModule");
336  if (strlen(gateScheduleConfiguratorModulePath) != 0) {
337  auto gateScheduleConfigurator = getModuleByPath(gateScheduleConfiguratorModulePath);
338  cValueArray *parameterValue = new cValueArray();
339  for (int i = 0; i < configuration->size(); i++) {
340  cValueMap *streamConfiguration = check_and_cast<cValueMap *>(configuration->get(i).objectValue());
341  auto source = streamConfiguration->get("source").stringValue();
342  auto destination = streamConfiguration->get("destination").stringValue();
343  auto pathFragments = streamRedundancyConfigurator->getPathFragments(streamConfiguration->get("name").stringValue());
344  cValueMap *streamParameterValue = new cValueMap();
345  cValueArray *pathFragmentsParameterValue = new cValueArray();
346  for (auto& pathFragment : pathFragments) {
347  cValueArray *pathFragmentParameterValue = new cValueArray();
348  for (auto nodeName : pathFragment)
349  pathFragmentParameterValue->add(nodeName);
350  pathFragmentsParameterValue->add(pathFragmentParameterValue);
351  }
352  streamParameterValue->set("pathFragments", pathFragmentsParameterValue);
353  streamParameterValue->set("name", streamConfiguration->get("name").stringValue());
354  streamParameterValue->set("application", streamConfiguration->get("application"));
355  streamParameterValue->set("source", source);
356  streamParameterValue->set("destination", destination);
357  if (streamConfiguration->containsKey("pcp"))
358  streamParameterValue->set("pcp", streamConfiguration->get("pcp").intValue());
359  if (streamConfiguration->containsKey("gateIndex"))
360  streamParameterValue->set("gateIndex", streamConfiguration->get("gateIndex").intValue());
361  streamParameterValue->set("packetLength", cValue(streamConfiguration->get("packetLength").doubleValueInUnit("B"), "B"));
362  streamParameterValue->set("packetInterval", cValue(streamConfiguration->get("packetInterval").doubleValueInUnit("s"), "s"));
363  if (streamConfiguration->containsKey("maxLatency"))
364  streamParameterValue->set("maxLatency", cValue(streamConfiguration->get("maxLatency").doubleValueInUnit("s"), "s"));
365  parameterValue->add(streamParameterValue);
366  }
367  gateScheduleConfigurator->par("configuration") = parameterValue;
368  }
369  }
370 }

Referenced by initialize().

◆ countParalellLinks()

static int inet::FailureProtectionConfigurator::countParalellLinks ( const Interface interface)
inlinestatic
95  {
96  int count = 0;
97  auto node = interface->node;
98  for (auto otherInterface : node->interfaces)
99  if (findConnectedNode(interface) == findConnectedNode(otherInterface))
100  count++;
101  return count;
102  }

◆ findConnectedNode()

static Node* inet::FailureProtectionConfigurator::findConnectedNode ( const Interface interface)
inlinestatic
85  {
86  auto node = interface->node;
87  for (int i = 0; i < node->getNumOutLinks(); i++) {
88  auto link = (Link *)node->getLinkOut(i);
89  if (link->sourceInterface == interface)
90  return link->destinationInterface->node;
91  }
92  return nullptr;
93  }

◆ getStreams()

const std::vector<StreamConfiguration>& inet::FailureProtectionConfigurator::getStreams ( ) const
inline
83 { return streamConfigurations; }

◆ initialize()

void inet::FailureProtectionConfigurator::initialize ( int  stage)
overrideprotectedvirtual
18 {
19  NetworkConfiguratorBase::initialize(stage);
20  if (stage == INITSTAGE_LOCAL)
21  configuration = check_and_cast<cValueArray *>(par("configuration").objectValue());
22  else if (stage == INITSTAGE_NETWORK_CONFIGURATION) {
25  }
26 }

◆ matchesFilter()

bool inet::FailureProtectionConfigurator::matchesFilter ( const std::string &  name,
const std::string &  filter 
) const
protectedvirtual
520 {
521  cMatchExpression matchExpression;
522  matchExpression.setPattern(filter.c_str(), false, false, true);
523  cMatchableString matchableString(name.c_str());
524  return matchExpression.matches(&matchableString);
525 }

◆ selectBestTreeSubset()

std::vector< FailureProtectionConfigurator::Tree > inet::FailureProtectionConfigurator::selectBestTreeSubset ( cValueMap *  configuration,
const Node sourceNode,
const std::vector< const Node * > &  destinationNodes,
const std::vector< Tree > &  trees 
) const
protectedvirtual
94 {
95  cValueArray *nodeFailureProtection = configuration->containsKey("nodeFailureProtection") ? check_and_cast<cValueArray *>(configuration->get("nodeFailureProtection").objectValue()) : nullptr;
96  cValueArray *linkFailureProtection = configuration->containsKey("linkFailureProtection") ? check_and_cast<cValueArray *>(configuration->get("linkFailureProtection").objectValue()) : nullptr;
97  int n = trees.size();
98  int maxRedundancy = configuration->containsKey("maxRedundancy") ? configuration->get("maxRedundancy").intValue() : n;
99  for (int k = 1; k <= maxRedundancy; k++) {
100  EV_DETAIL << "Trying to find best tree subset for " << k << " trees" << EV_ENDL;
101  std::vector<bool> mask(k, true); // k leading 1's
102  mask.resize(n, false); // n-k trailing 0's
103  std::vector<bool> bestMask;
104  double bestCost = DBL_MAX;
105  do {
106  double cost = 0;
107  for (int i = 0; i < n; i++)
108  if (mask[i])
109  cost += computeTreeCost(sourceNode, destinationNodes, trees[i]);
110  cost /= k;
111  if (cost < bestCost) {
112  std::vector<Tree> candidate;
113  for (int i = 0; i < n; i++)
114  if (mask[i])
115  candidate.push_back(trees[i]);
116  if ((nodeFailureProtection == nullptr || checkNodeFailureProtection(nodeFailureProtection, sourceNode, destinationNodes, candidate)) &&
117  (linkFailureProtection == nullptr || checkLinkFailureProtection(linkFailureProtection, sourceNode, destinationNodes, candidate)))
118  {
119  bestCost = cost;
120  bestMask = mask;
121  }
122  }
123  } while (std::prev_permutation(mask.begin(), mask.end()));
124  if (bestCost != DBL_MAX) {
125  std::vector<Tree> result;
126  for (int i = 0; i < n; i++)
127  if (bestMask[i])
128  result.push_back(trees[i]);
129  return result;
130  }
131  }
132  throw cRuntimeError("Cannot find tree combination that protects against all configured node and link failures");
133 }

Referenced by computeStream().

Member Data Documentation

◆ configuration

cValueArray* inet::FailureProtectionConfigurator::configuration
protected

◆ streamConfigurations

std::vector<StreamConfiguration> inet::FailureProtectionConfigurator::streamConfigurations
protected

Referenced by computeStream().


The documentation for this class was generated from the following files:
inet::INITSTAGE_NETWORK_CONFIGURATION
INET_API InitStage INITSTAGE_NETWORK_CONFIGURATION
Initialization of network configuration (e.g.
inet::FailureProtectionConfigurator::computeTreeCost
virtual double computeTreeCost(const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const Tree &tree) const
Definition: FailureProtectionConfigurator.cc:135
inet::FailureProtectionConfigurator::collectNetworkNodes
virtual std::vector< const Node * > collectNetworkNodes(const std::string &filter) const
Definition: FailureProtectionConfigurator.cc:436
inet::FailureProtectionConfigurator::collectReachedNodes
virtual void collectReachedNodes(const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const Tree &tree, const std::vector< const Node * > &failedNodes, std::vector< bool > &reachedDestinationNodes) const
Definition: FailureProtectionConfigurator.cc:466
inet::FailureProtectionConfigurator::countParalellLinks
static int countParalellLinks(const Interface *interface)
Definition: FailureProtectionConfigurator.h:95
inet::FailureProtectionConfigurator::checkLinkFailureProtection
virtual bool checkLinkFailureProtection(cValueArray *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
Definition: FailureProtectionConfigurator.cc:258
inet::FailureProtectionConfigurator::configuration
cValueArray * configuration
Definition: FailureProtectionConfigurator.h:78
inet::NetworkConfiguratorBase::findLinkOut
virtual Link * findLinkOut(const Node *node, const char *neighbor) const
Definition: NetworkConfiguratorBase.cc:116
inet::FailureProtectionConfigurator::collectNetworkLinks
virtual std::vector< const Link * > collectNetworkLinks(const std::string &filter) const
Definition: FailureProtectionConfigurator.cc:448
inet::NetworkConfiguratorBase::Node::module
cModule * module
Definition: NetworkConfiguratorBase.h:28
inet::FailureProtectionConfigurator::findConnectedNode
static Node * findConnectedNode(const Interface *interface)
Definition: FailureProtectionConfigurator.h:85
inet::count
int count(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:54
inet::Topology::getNodeFor
Node * getNodeFor(cModule *mod) const
Returns the graph node which corresponds to the given module in the network.
Definition: Topology.cc:355
inet::find
std::vector< T >::iterator find(std::vector< T > &v, const Tk &a)
Definition: stlutils.h:44
inet::Topology::getNode
Node * getNode(int i) const
Returns pointer to the ith node in the graph.
Definition: Topology.cc:348
inet::FailureProtectionConfigurator::configureStreams
virtual void configureStreams() const
Definition: FailureProtectionConfigurator.cc:299
inet::FailureProtectionConfigurator::collectAllTrees
virtual std::vector< Tree > collectAllTrees(Node *sourceNode, const std::vector< const Node * > &destinationNodes) const
Definition: FailureProtectionConfigurator.cc:372
inet::Topology::calculateUnweightedSingleShortestPathsTo
void calculateUnweightedSingleShortestPathsTo(Node *target) const
Apply the Dijkstra algorithm to find all shortest paths to the given graph node.
Definition: Topology.cc:364
inet::FailureProtectionConfigurator::collectAllPaths
virtual std::vector< Path > collectAllPaths(const std::vector< const Node * > &stopNodes, const Node *destinationNode) const
Definition: FailureProtectionConfigurator.cc:406
EV_FIELD
#define EV_FIELD(...)
Definition: INETDefs.h:112
inet::NetworkConfiguratorBase::extractTopology
virtual void extractTopology(Topology &topology)
Extracts network topology by walking through the module hierarchy.
Definition: NetworkConfiguratorBase.cc:19
inet::FailureProtectionConfigurator::computeStream
virtual void computeStream(cValueMap *streamConfiguration)
Definition: FailureProtectionConfigurator.cc:46
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::Topology::getNumNodes
int getNumNodes() const
Returns the number of nodes in the graph.
Definition: Topology.h:516
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
inet::FailureProtectionConfigurator::computeConfiguration
virtual void computeConfiguration()
Computes the network configuration for all nodes in the network.
Definition: FailureProtectionConfigurator.cc:28
inet::FailureProtectionConfigurator::streamConfigurations
std::vector< StreamConfiguration > streamConfigurations
Definition: FailureProtectionConfigurator.h:80
inet::FailureProtectionConfigurator::selectBestTreeSubset
virtual std::vector< Tree > selectBestTreeSubset(cValueMap *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
Definition: FailureProtectionConfigurator.cc:93
TIME
#define TIME(CODE)
Definition: INETDefs.h:96
inet::NetworkConfiguratorBase::topology
Topology * topology
Definition: NetworkConfiguratorBase.h:67
inet::FailureProtectionConfigurator::computeStreams
virtual void computeStreams()
Definition: FailureProtectionConfigurator.cc:38
inet::FailureProtectionConfigurator::computeCanonicalTree
virtual Tree computeCanonicalTree(const Tree &tree) const
Definition: FailureProtectionConfigurator.cc:166
inet::FailureProtectionConfigurator::matchesFilter
virtual bool matchesFilter(const std::string &name, const std::string &filter) const
Definition: FailureProtectionConfigurator.cc:519
inet::FailureProtectionConfigurator::checkNodeFailureProtection
virtual bool checkNodeFailureProtection(cValueArray *configuration, const Node *sourceNode, const std::vector< const Node * > &destinationNodes, const std::vector< Tree > &trees) const
Definition: FailureProtectionConfigurator.cc:217
EV_ENDL
#define EV_ENDL
Definition: INETDefs.h:114
inet::printElapsedTime
void printElapsedTime(const char *name, long startTime)
Definition: INETDefs.h:91
inet::MatchableObject::ATTRIBUTE_FULLNAME
@ ATTRIBUTE_FULLNAME
Definition: MatchableObject.h:22