RINASim  October 2016
Documentation of framework for OMNeT++
SimpleEdgeForwarding.cc
Go to the documentation of this file.
1 // The MIT License (MIT)
2 //
3 // Copyright (c) 2014-2016 Brno University of Technology, PRISTINE project
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 
23 #include "SimpleEdgeForwarding.h"
24 #include <sstream>
25 #include "Utils.h"
26 
27 namespace NSPSimpleDC {
28 
29  Register_Class(SimpleEdgeForwarding);
30 
31  using namespace std;
32 
33  eFWDEntry::eFWDEntry() : entryType(false), inverseStorage(false) {}
34 
35 
37  downCount = par("downCount").longValue();
38  if(downCount < 0) { downCount = 0; }
39  portsArray = new Port[downCount];
40  for(int i = 0; i<downCount; i++) { portsArray[i] = nullptr; }
41  }
42 
43  vector<Port> SimpleEdgeForwarding::search(const DCAddr & n_addr) {
44  if(Im == n_addr) { return vector<Port>(); }
45  if(n_addr.type < 0 || n_addr.type > 3) {
46  cerr << "Invalid dst addr ("<<n_addr<< ")" << endl;
47  return vector<Port>();
48  }
49 
50  auto r = table.find(n_addr);
51  if(r != table.end()) {
52  auto & e = r->second;
53  if(!e.entryType) { return vector<Port>(); }
54 
55  vector<Port> ret;
56  for(int i = 0; i<downCount; i++) {
57  Port p = portsArray[i];
58  if(e.inverseStorage == (e.ports.find(p) == e.ports.end()) ) {
59  ret.push_back(p);
60  }
61  }
62  return ret;
63  }
64 
65  if(n_addr.type == 2 && n_addr.a == Im.b) {
66  if(n_addr.b < downCount && portsArray[n_addr.b] != nullptr) {
67  vector<Port> ret;
68  ret.push_back(portsArray[n_addr.b]);
69  return ret;
70  } else { cout << "!!! Invalid port to " << (n_addr.b) << " at " << Im << endl; }
71  }
72  return downV;
73  }
74 
75 
76  bool SimpleEdgeForwarding::setNeigh(const DCAddr & n_addr, Port port) {
77  if(n_addr.type != 2 || Im.b != n_addr.a || n_addr.b >= downCount) {
78  cerr << "Invalid neighbour ("<<n_addr<< ") found for Edge " << Im<<endl;
79  return false;
80  }
81 
82  Port t = portsArray[n_addr.b];
83  if(portsArray[n_addr.b] == port) { return true; }
84  portsArray[n_addr.b] = port;
85 
86 
87  downV.clear();
88  for(int i = 0; i<downCount; i++) {
89  if(portsArray[i]!= nullptr) {
90  downV.push_back(portsArray[i]);
91  }
92  }
93 
94 
95  for(auto & e : table) {
96  if(e.second.ports.find(t) != e.second.ports.end()) {
97  e.second.ports.erase(t);
98  if(port != nullptr) {
99  e.second.ports.insert(port);
100  }
101  }
102  }
103  refreshCache (t, port);
104  return true;
105  }
106 
107  void SimpleEdgeForwarding::setDst(const DCAddr & n_addr, const set<DCAddr> & next) {
108  if(n_addr == Im) { return; }
109 
110  if(n_addr.type < 0 || n_addr.type > 3) {
111  cerr << "Invalid dst addr ("<<n_addr<< ")" << endl;
112  return;
113  }
114 
115  int S = next.size();
116 
117  if(S == 0) {
118  table[n_addr] = eFWDEntry();
119  return;
120  }
121 
122  set<int> pIds;
123  for(const auto & n : next) {
124  pIds.insert(n.b);
125  }
126 
127 
128  if(n_addr.type == 2 && n_addr.a == Im.b) {
129  if(S == 1 && pIds.find(n_addr.b) != pIds.end()){
130  table.erase(n_addr);
131  } else {
132  table[n_addr] = getFWDEntry(pIds);
133  }
134  } else if (S == downCount) {
135  table.erase(n_addr);
136  } else {
137  table[n_addr] = getFWDEntry(pIds);
138  }
139 
140  refreshCache (n_addr);
141  }
142 
144  eFWDEntry ret;
145  ret.entryType = true;
146  ret.inverseStorage = ((int)pIds.size()*2 > downCount);
147 
148  for(int i = 0; i< downCount; i++) {
149  if(ret.inverseStorage == (pIds.find(i) == pIds.end())) {
150  ret.ports.insert(portsArray[i]);
151  }
152  }
153  return ret;
154  }
155 
157  if(par("printAtEnd").boolValue()) {
158  cout << "-----------------------" << endl;
159  cout << "SimpleEdgeForwarding at "<< endl;
160  cout << " " << getFullPath() << endl;
161 
162  cout << "I'm Edge "<< Im << endl;
163  if(downCount > 0) {
164  cout << "\tDown neighbours:" << endl;
165  for(int i = 0; i < downCount; i++) {
166  cout << "\t\t1."<<Im.a<<"."<<i<<" -> Status "<< (portsArray[i]!=nullptr? "ON":"OFF") << endl;
167  }
168  }
169  if(table.empty()) {
170  cout << "\tNo entries stored" << endl;
171  } else {
172  cout << "Stored entries " << table.size() << endl;
173  for(auto & e : table) {
174  cout <<"\t\t"<< e.first << " -- ";
175  if(e.second.entryType == false) {
176  cout << "Unreachable";
177  } else {
178  if(e.second.inverseStorage) {
179  cout << "(inverse) ";
180  }
181  cout << e.second.ports.size() << " stored ports:";
182  }
183  cout << endl;
184  for(auto &k : e.second.ports) {
185  cout << "\t\t\t" << k->getFullPath() << endl;
186  }
187  }
188  }
189  }
190 
191  delete portsArray;
192  }
193 
194 }
Register_Class(SimpleDCGenerator)
eFWDEntry getFWDEntry(const set< int > &pIds)
virtual void refreshCache(Port oldP, Port newP)
bool entryType
void setDst(const DCAddr &n_addr, const set< DCAddr > &next)
bool inverseStorage
set< Port > ports
bool setNeigh(const DCAddr &n_addr, Port port)
vector< Port > search(const DCAddr &n_addr)
eFWDEntry()