|
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * Copyright (c) 2008,2009 IITP RAS |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License version 2 as |
|
7 * published by the Free Software Foundation; |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 * |
|
18 * Author: Kirill Andreev <andreev@iitp.ru> |
|
19 */ |
|
20 |
|
21 |
|
22 #include "ns3/object.h" |
|
23 #include "ns3/assert.h" |
|
24 #include "ns3/simulator.h" |
|
25 #include "ns3/ptr.h" |
|
26 #include "ns3/log.h" |
|
27 #include "ns3/node.h" |
|
28 #include "hwmp-rtable.h" |
|
29 |
|
30 NS_LOG_COMPONENT_DEFINE ("HwmpRtable"); |
|
31 |
|
32 namespace ns3 { |
|
33 |
|
34 NS_OBJECT_ENSURE_REGISTERED (HwmpRtable); |
|
35 |
|
36 TypeId |
|
37 HwmpRtable::GetTypeId(void) |
|
38 { |
|
39 static TypeId tid = TypeId ("ns3::HwmpRtable") |
|
40 .SetParent<Object> () |
|
41 .AddConstructor<HwmpRtable> (); |
|
42 return tid; |
|
43 |
|
44 } |
|
45 |
|
46 HwmpRtable::HwmpRtable() |
|
47 { |
|
48 } |
|
49 |
|
50 HwmpRtable::~HwmpRtable() |
|
51 { |
|
52 DoDispose(); |
|
53 } |
|
54 |
|
55 void |
|
56 HwmpRtable::DoDispose() |
|
57 { |
|
58 NS_LOG_UNCOND("RTABLE DISPOSE STARTED"); |
|
59 m_routes.clear(); |
|
60 m_roots.clear(); |
|
61 } |
|
62 |
|
63 void |
|
64 HwmpRtable::AddReactivePath( |
|
65 Mac48Address destination, |
|
66 Mac48Address retransmitter, |
|
67 uint32_t port, |
|
68 uint32_t metric, |
|
69 Time lifetime, |
|
70 uint32_t seqnum |
|
71 ) |
|
72 { |
|
73 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination); |
|
74 if(i == m_routes.end()) |
|
75 { |
|
76 struct ReactiveRoute newroute; |
|
77 m_routes[destination] = newroute; |
|
78 } |
|
79 else |
|
80 { |
|
81 /** |
|
82 * if outport differs from stored, routing info is |
|
83 * actual and metric is worse - we ignore this |
|
84 * information |
|
85 */ |
|
86 if( |
|
87 (i->second.port != port) && |
|
88 (i->second.metric < metric) && |
|
89 /** |
|
90 * The routing info is actual or it |
|
91 * was received from peer |
|
92 */ |
|
93 ((i->second.whenExpire > Simulator::Now())||(i->second.whenExpire == Seconds(0))) |
|
94 ) |
|
95 return; |
|
96 } |
|
97 i = m_routes.find(destination); |
|
98 NS_ASSERT(i != m_routes.end()); |
|
99 i->second.retransmitter = retransmitter; |
|
100 i->second.port = port; |
|
101 i->second.metric = metric; |
|
102 if(lifetime != Seconds(0)) |
|
103 i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds()); |
|
104 else |
|
105 /** |
|
106 * Information about peer does not have lifetime |
|
107 */ |
|
108 i->second.whenExpire = Seconds(0); |
|
109 i->second.seqnum = seqnum; |
|
110 } |
|
111 |
|
112 void |
|
113 HwmpRtable::AddProactivePath( |
|
114 uint32_t metric, |
|
115 Mac48Address root, |
|
116 Mac48Address retransmitter, |
|
117 uint32_t port, |
|
118 Time lifetime, |
|
119 uint32_t seqnum |
|
120 ) |
|
121 { |
|
122 struct ProactiveRoute newroute; |
|
123 m_roots[port] = newroute; |
|
124 std::map<uint32_t,struct ProactiveRoute>::iterator i = m_roots.find(port); |
|
125 NS_ASSERT(i != m_roots.end()); |
|
126 i->second.root = root; |
|
127 i->second.retransmitter = retransmitter; |
|
128 i->second.metric = metric; |
|
129 i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds()); |
|
130 i->second.seqnum = seqnum; |
|
131 |
|
132 } |
|
133 |
|
134 void |
|
135 HwmpRtable::AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor) |
|
136 { |
|
137 bool should_add = true; |
|
138 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination); |
|
139 if((i != m_routes.end()) && (i->second.port == port)) |
|
140 { |
|
141 for(unsigned int j = 0 ; j < i->second.precursors.size(); j ++) |
|
142 if(i->second.precursors[j] == precursor) |
|
143 { |
|
144 should_add = false; |
|
145 break; |
|
146 } |
|
147 if(should_add) |
|
148 i->second.precursors.push_back(precursor); |
|
149 } |
|
150 std::map<uint32_t,struct ProactiveRoute>::iterator k = m_roots.find(port); |
|
151 if(k!= m_roots.end()) |
|
152 { |
|
153 for(unsigned int j = 0 ; j < k->second.precursors.size(); j ++) |
|
154 if(k->second.precursors[j] == precursor) |
|
155 return; |
|
156 k->second.precursors.push_back(precursor); |
|
157 return; |
|
158 } |
|
159 } |
|
160 |
|
161 void |
|
162 HwmpRtable::DeleteProactivePath(uint32_t port) |
|
163 { |
|
164 std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port); |
|
165 if(j != m_roots.end()) |
|
166 m_roots.erase(j); |
|
167 |
|
168 } |
|
169 void |
|
170 HwmpRtable::DeleteProactivePath(Mac48Address root, uint32_t port) |
|
171 { |
|
172 std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port); |
|
173 if((j != m_roots.end())&&(j->second.root == root)) |
|
174 m_roots.erase(j); |
|
175 |
|
176 } |
|
177 |
|
178 void |
|
179 HwmpRtable::DeleteReactivePath(Mac48Address destination, uint32_t port) |
|
180 { |
|
181 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination); |
|
182 if(i != m_routes.end()) |
|
183 if(i->second.port == port) |
|
184 m_routes.erase(i); |
|
185 } |
|
186 |
|
187 struct HwmpRtable::LookupResult |
|
188 HwmpRtable::LookupReactive(Mac48Address destination) |
|
189 { |
|
190 struct LookupResult result; |
|
191 result.retransmitter = Mac48Address::GetBroadcast(); |
|
192 result.metric = MAX_METRIC; |
|
193 result.ifIndex = PORT_ANY; |
|
194 |
|
195 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination); |
|
196 if(i == m_routes.end()) |
|
197 return result; |
|
198 result.ifIndex = i->second.port; |
|
199 //Seconds(0) means that this is routing |
|
200 if(i->second.whenExpire < Simulator::Now()) |
|
201 if(i->second.retransmitter != destination) |
|
202 return result; |
|
203 result.retransmitter = i->second.retransmitter; |
|
204 result.metric = i->second.metric; |
|
205 result.seqnum = i->second.seqnum; |
|
206 return result; |
|
207 } |
|
208 |
|
209 struct HwmpRtable::LookupResult |
|
210 HwmpRtable::LookupProactive(uint32_t port) |
|
211 { |
|
212 struct LookupResult result; |
|
213 result.retransmitter = Mac48Address::GetBroadcast(); |
|
214 result.metric = MAX_METRIC; |
|
215 result.ifIndex = PORT_ANY; |
|
216 std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port); |
|
217 if(i == m_roots.end()) |
|
218 return result; |
|
219 result.ifIndex = i->first; |
|
220 if(i->second.whenExpire < Simulator::Now()) |
|
221 return result; |
|
222 result.retransmitter = i->second.retransmitter; |
|
223 result.metric = i->second.metric; |
|
224 result.seqnum = i->second.seqnum; |
|
225 return result; |
|
226 } |
|
227 |
|
228 std::vector<struct HwmpRtable::FailedDestination> |
|
229 HwmpRtable::GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port) |
|
230 { |
|
231 std::vector<struct FailedDestination> retval; |
|
232 for(std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.begin(); i!= m_routes.end(); i++) |
|
233 if((i->second.retransmitter == peerAddress)&&(i->second.port == port)) |
|
234 { |
|
235 struct FailedDestination dst; |
|
236 dst.destination = i->first; |
|
237 i->second.seqnum ++; |
|
238 dst.seqnum = i->second.seqnum; |
|
239 retval.push_back(dst); |
|
240 } |
|
241 /** |
|
242 * Lookup a path to root |
|
243 */ |
|
244 std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port); |
|
245 if((i != m_roots.end())&&(i->second.retransmitter == peerAddress)) |
|
246 { |
|
247 struct FailedDestination dst; |
|
248 dst.destination = i->second.root; |
|
249 dst.seqnum = i->second.seqnum; |
|
250 retval.push_back(dst); |
|
251 } |
|
252 return retval; |
|
253 } |
|
254 uint32_t |
|
255 HwmpRtable::RequestSeqnum(Mac48Address destination) |
|
256 { |
|
257 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination); |
|
258 if(i == m_routes.end()) |
|
259 return 0; |
|
260 return i->second.seqnum; |
|
261 } |
|
262 |
|
263 std::vector<Mac48Address> |
|
264 HwmpRtable::GetPrecursors(Mac48Address destination, uint32_t port) |
|
265 { |
|
266 std::vector<Mac48Address> retval; |
|
267 std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator root = m_roots.find(port); |
|
268 if((root != m_roots.end()) &&(root->second.root == destination)) |
|
269 { |
|
270 for(unsigned int i = 0; i < root->second.precursors.size(); i ++) |
|
271 retval.push_back(root->second.precursors[i]); |
|
272 } |
|
273 std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator route = m_routes.find(destination); |
|
274 if( (route != m_routes.end()) && (route->second.port == port) ) |
|
275 { |
|
276 for(unsigned int i = 0; i < route->second.precursors.size(); i ++) |
|
277 retval.push_back(route->second.precursors[i]); |
|
278 } |
|
279 return retval; |
|
280 } |
|
281 |
|
282 }//namespace ns3 |