36 NS_LOG_COMPONENT_DEFINE ("Ipv4ClickRouting"); |
38 NS_LOG_COMPONENT_DEFINE ("Ipv4ClickRouting"); |
37 |
39 |
38 std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > Ipv4ClickRouting::m_clickInstanceFromSimNode; |
40 std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > Ipv4ClickRouting::m_clickInstanceFromSimNode; |
39 |
41 |
40 Ipv4ClickRouting::Ipv4ClickRouting () |
42 Ipv4ClickRouting::Ipv4ClickRouting () |
|
43 : m_clickFile (NULL), |
|
44 m_ipv4 (0) |
41 {} |
45 {} |
42 |
46 |
43 Ipv4ClickRouting::~Ipv4ClickRouting () |
47 Ipv4ClickRouting::~Ipv4ClickRouting () |
44 {} |
48 {} |
45 |
49 |
46 void |
50 void |
47 Ipv4ClickRouting::DoStart () |
51 Ipv4ClickRouting::DoStart () |
48 { |
52 { |
49 m_simnode = new simclick_node_t; |
53 uint32_t id = m_ipv4->GetObject<Node> ()->GetId (); |
|
54 |
|
55 std::stringstream name; |
|
56 name << "Node" << id; |
|
57 m_nodeName = name.str (); |
|
58 |
|
59 m_simNode = new simclick_node_t; |
50 AddSimNodeToClickMapping (); |
60 AddSimNodeToClickMapping (); |
|
61 |
|
62 NS_ASSERT (m_clickFile != NULL); |
|
63 |
|
64 if (simclick_click_create (m_simNode, m_clickFile) >= 0) |
|
65 { |
|
66 NS_LOG_DEBUG (m_nodeName << " has initialised a Click Router"); |
|
67 } |
|
68 else |
|
69 { |
|
70 NS_LOG_DEBUG ("Click Router Initialisation failed for " << m_nodeName); |
|
71 } |
|
72 |
|
73 timerclear (&m_simNode->curtime); |
|
74 simclick_click_run (m_simNode); |
51 } |
75 } |
52 |
76 |
53 void |
77 void |
54 Ipv4ClickRouting::SetIpv4 (Ptr<Ipv4> ipv4) |
78 Ipv4ClickRouting::SetIpv4 (Ptr<Ipv4> ipv4) |
55 { |
79 { |
58 |
82 |
59 void |
83 void |
60 Ipv4ClickRouting::DoDispose () |
84 Ipv4ClickRouting::DoDispose () |
61 { |
85 { |
62 m_ipv4 = 0; |
86 m_ipv4 = 0; |
|
87 delete m_simNode; |
|
88 } |
|
89 |
|
90 void |
|
91 Ipv4ClickRouting::SetClickFile (const char *clickfile) |
|
92 { |
|
93 m_clickFile = clickfile; |
|
94 } |
|
95 |
|
96 void |
|
97 Ipv4ClickRouting::SetNodeName (std::string name) |
|
98 { |
|
99 m_nodeName = name; |
|
100 } |
|
101 |
|
102 std::string |
|
103 Ipv4ClickRouting::GetNodeName () |
|
104 { |
|
105 return m_nodeName; |
63 } |
106 } |
64 |
107 |
65 void |
108 void |
66 Ipv4ClickRouting::ReceiveFromExtRouter (Ptr<Packet>, bool direction) |
109 Ipv4ClickRouting::ReceiveFromExtRouter (Ptr<Packet>, bool direction) |
67 {} |
110 {} |
68 |
111 |
69 void |
112 void |
70 Ipv4ClickRouting::SendToExtRouter (Ptr<Packet>, bool direction) |
113 Ipv4ClickRouting::SendToExtRouter (Ptr<Packet>, bool direction) |
71 {} |
114 {} |
72 |
115 |
|
116 int |
|
117 Ipv4ClickRouting::GetInterfaceId (const char *ifname) |
|
118 { |
|
119 int retval = -1; |
|
120 |
|
121 if (strstr(ifname, "tap") || strstr(ifname, "tun")) |
|
122 { |
|
123 retval = ExtRouter::IFID_KERNELTAP; |
|
124 } |
|
125 else if (const char *devname = strstr(ifname, "eth")) |
|
126 { |
|
127 while (*devname && !isdigit((unsigned char) *devname)) |
|
128 { |
|
129 devname++; |
|
130 } |
|
131 |
|
132 if (*devname) |
|
133 { |
|
134 retval = atoi(devname) + ExtRouter::IFID_FIRSTIF; |
|
135 } |
|
136 } |
|
137 else if (const char *devname = strstr(ifname, "drop")) |
|
138 { |
|
139 while (*devname && !isdigit((unsigned char) *devname)) |
|
140 { |
|
141 devname++; |
|
142 } |
|
143 if (*devname) |
|
144 { |
|
145 retval = atoi(devname) + ExtRouter::IFID_FIRSTIFDROP; |
|
146 } |
|
147 } |
|
148 |
|
149 return retval; |
|
150 } |
|
151 |
|
152 std::string |
|
153 Ipv4ClickRouting::GetIpAddrFromIfid (int ifid) |
|
154 { |
|
155 std::stringstream addr; |
|
156 m_ipv4->GetAddress (ifid, 0).GetLocal ().Print (addr); |
|
157 |
|
158 return addr.str (); |
|
159 } |
|
160 |
|
161 std::string |
|
162 Ipv4ClickRouting::GetMacAddrFromIfid (int ifid) |
|
163 { |
|
164 std::stringstream addr; |
|
165 |
|
166 Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid); |
|
167 |
|
168 Address devAddr = device->GetAddress (); |
|
169 addr << Mac48Address::ConvertFrom(devAddr); |
|
170 |
|
171 NS_LOG_DEBUG (addr.str ()); |
|
172 return addr.str (); |
|
173 } |
73 |
174 |
74 void |
175 void |
75 Ipv4ClickRouting::AddSimNodeToClickMapping () |
176 Ipv4ClickRouting::AddSimNodeToClickMapping () |
76 { |
177 { |
77 m_clickInstanceFromSimNode.insert (std::make_pair (m_simnode, this)); |
178 m_clickInstanceFromSimNode.insert (std::make_pair (m_simNode, this)); |
78 } |
179 } |
79 |
180 |
80 Ptr<Ipv4ClickRouting> |
181 Ptr<Ipv4ClickRouting> |
81 Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode) |
182 Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode) |
82 { |
183 { |
84 } |
185 } |
85 |
186 |
86 void |
187 void |
87 Ipv4ClickRouting::HandleScheduleFromClick (const struct timeval *when) |
188 Ipv4ClickRouting::HandleScheduleFromClick (const struct timeval *when) |
88 { |
189 { |
89 NS_LOG_UNCOND ("HandleScheduleFromClick at " << Simulator::Now ()); |
190 NS_LOG_DEBUG ("HandleScheduleFromClick at " << Simulator::Now ()); |
90 // simclick_simpacketinfo pinfo; |
191 |
91 |
192 m_simNode->curtime = *when; |
92 m_simnode->curtime = *when; |
193 simclick_click_run (m_simNode); |
93 simclick_click_run (m_simnode); |
|
94 // simclick_click_send(simnode,1,-1,0,100,&pinfo); |
|
95 } |
194 } |
96 |
195 |
97 void |
196 void |
98 Ipv4ClickRouting::HandlePacketFromClick (int ifid, int ptype, const unsigned char* data, int len) |
197 Ipv4ClickRouting::HandlePacketFromClick (int ifid, int ptype, const unsigned char* data, int len) |
99 { |
198 { |
100 NS_LOG_UNCOND ("HandlePacketFromClick"); |
199 NS_LOG_DEBUG ("HandlePacketFromClick"); |
101 |
200 |
102 // Figure out packet's destination here: |
201 // Figure out packet's destination here: |
103 // If ifid == 0, then packet's going up |
202 // If ifid == 0, then packet's going up |
104 // else, packet's going down |
203 // else, packet's going down |
105 |
|
106 Simulator::Schedule (Seconds (1.0), &Ipv4ClickRouting::SendPacketToClick, this, 2, -1, data, 100); |
|
107 |
204 |
108 } |
205 } |
109 |
206 |
110 void |
207 void |
111 Ipv4ClickRouting::SendPacketToClick (int ifid, int ptype, const unsigned char* data, int len) |
208 Ipv4ClickRouting::SendPacketToClick (int ifid, int ptype, const unsigned char* data, int len) |
112 { |
209 { |
113 simclick_simpacketinfo pinfo; |
210 simclick_simpacketinfo pinfo; |
114 simclick_click_send(m_simnode,ifid,ptype,data,len,&pinfo); |
211 simclick_click_send(m_simNode,ifid,ptype,data,len,&pinfo); |
115 } |
212 } |
116 |
213 |
117 void |
214 void |
118 Ipv4ClickRouting::TestInit () |
215 Ipv4ClickRouting::TestInit () |
119 { |
216 { |
120 timerclear (&m_simnode->curtime); |
217 // NS_LOG_DEBUG ("GetNInterfaces () : " << m_ipv4->GetNInterfaces ()); |
121 |
218 // DoStart (); // Call DoStart for now, because we are not using Helpers yet |
122 DoStart (); |
219 |
123 |
220 |
124 // This would go into DoStart () |
221 // simclick_simpacketinfo pinfo; |
125 if (simclick_click_create (m_simnode, "/home/nightstrike/builds/gsoc/ns-3-click/src/routing/click/nsclick-simple-bridge.click") >= 0) |
|
126 { |
|
127 NS_LOG_UNCOND ("Initialised a Click Router"); |
|
128 } |
|
129 else |
|
130 { |
|
131 NS_LOG_UNCOND ("Initialisation failed"); |
|
132 } |
|
133 |
|
134 NS_LOG_UNCOND ("Testing simclick run"); |
|
135 |
|
136 simclick_click_run (m_simnode); |
|
137 |
|
138 NS_LOG_UNCOND ("Testing simclick_click_send"); |
|
139 |
|
140 simclick_simpacketinfo pinfo; |
|
141 |
|
142 // simnode_->curtime = *when; |
222 // simnode_->curtime = *when; |
143 pinfo.id = 2; |
223 // pinfo.id = 2; |
144 pinfo.fid =2; |
224 // pinfo.fid =2; |
145 |
|
146 // simclick_click_send(simnode_,ifid_,ptype_,data_,len_,&pinfo); |
225 // simclick_click_send(simnode_,ifid_,ptype_,data_,len_,&pinfo); |
147 simclick_click_send(m_simnode,1,-1,0,100,&pinfo); |
226 |
|
227 // simclick_click_send(m_simNode,1,-1,0,100,&pinfo); |
148 } |
228 } |
149 |
229 |
150 } // namespace ns3 |
230 } // namespace ns3 |
151 |
231 |
152 #ifdef __cplusplus |
232 #ifdef __cplusplus |
167 } |
247 } |
168 |
248 |
169 s.copy(buf, len); |
249 s.copy(buf, len); |
170 buf[len] = '\0'; |
250 buf[len] = '\0'; |
171 } |
251 } |
172 |
252 return 0; |
173 return 0; |
|
174 } |
253 } |
175 |
254 |
176 // Sends a Packet from Click to the Simulator: Defined in simclick.h |
255 // Sends a Packet from Click to the Simulator: Defined in simclick.h |
177 int simclick_sim_send(simclick_node_t *simnode, |
256 int simclick_sim_send(simclick_node_t *simnode, |
178 int ifid, int type, const unsigned char* data, int len, |
257 int ifid, int type, const unsigned char* data, int len, |
179 simclick_simpacketinfo *pinfo) |
258 simclick_simpacketinfo *pinfo) |
180 { |
259 { |
181 NS_LOG_UNCOND ("simclick_sim_send called : " << ifid << " " << type << " " << data << " "<< len); |
260 NS_LOG_DEBUG ("simclick_sim_send called : " << ifid << " " << type << " " << data << " "<< len); |
182 |
261 |
183 Ptr<Ipv4ClickRouting> clickInstance = Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode); |
262 Ptr<Ipv4ClickRouting> clickInstance = Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode); |
184 |
263 |
185 clickInstance->HandlePacketFromClick (ifid, type, data, len); |
264 clickInstance->HandlePacketFromClick (ifid, type, data, len); |
186 |
265 |
213 |
292 |
214 case SIMCLICK_IFID_FROM_NAME: |
293 case SIMCLICK_IFID_FROM_NAME: |
215 { |
294 { |
216 const char *ifname = va_arg(val, const char *); |
295 const char *ifname = va_arg(val, const char *); |
217 |
296 |
218 retval = -1; |
297 retval = clickInstance->GetInterfaceId (ifname); |
219 |
|
220 if (strstr(ifname, "tap") || strstr(ifname, "tun")) |
|
221 { |
|
222 retval = ExtRouter::IFID_KERNELTAP; |
|
223 } |
|
224 else if (const char *devname = strstr(ifname, "eth")) |
|
225 { |
|
226 while (*devname && !isdigit((unsigned char) *devname)) |
|
227 { |
|
228 devname++; |
|
229 } |
|
230 |
|
231 if (*devname) |
|
232 { |
|
233 retval = atoi(devname) + ExtRouter::IFID_FIRSTIF; |
|
234 } |
|
235 } |
|
236 else if (const char *devname = strstr(ifname, "drop")) |
|
237 { |
|
238 while (*devname && !isdigit((unsigned char) *devname)) |
|
239 { |
|
240 devname++; |
|
241 } |
|
242 if (*devname) |
|
243 { |
|
244 retval = atoi(devname) + ExtRouter::IFID_FIRSTIFDROP; |
|
245 } |
|
246 } |
|
247 |
298 |
248 NS_LOG_UNCOND ("SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval); |
299 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval); |
249 break; |
300 break; |
250 } |
301 } |
251 |
302 |
252 case SIMCLICK_IPADDR_FROM_NAME: |
303 case SIMCLICK_IPADDR_FROM_NAME: |
253 { |
304 { |
254 const char *ifname = va_arg(val, const char *); |
305 const char *ifname = va_arg(val, const char *); |
255 char *buf = va_arg(val, char *); |
306 char *buf = va_arg(val, char *); |
256 int len = va_arg(val, int); |
307 int len = va_arg(val, int); |
257 |
308 |
258 retval = simstrlcpy(buf, len, "172.16.1.10"); // For testing purposes: Instead, retrieve interface IP addr. |
309 retval = simstrlcpy(buf, len, clickInstance->GetIpAddrFromIfid (clickInstance->GetInterfaceId (ifname))); |
259 |
310 |
260 NS_LOG_UNCOND ("SIMCLICK_IPADDR_FROM_NAME: "<< ifname << " "<< buf << " " << len); |
311 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPADDR_FROM_NAME: "<< ifname << " "<< buf << " " << len); |
261 break; |
312 break; |
262 } |
313 } |
263 |
314 |
264 case SIMCLICK_MACADDR_FROM_NAME: |
315 case SIMCLICK_MACADDR_FROM_NAME: |
265 { |
316 { |
266 const char *ifname = va_arg(val, const char *); |
317 const char *ifname = va_arg(val, const char *); |
267 char *buf = va_arg(val, char *); |
318 char *buf = va_arg(val, char *); |
268 int len = va_arg(val, int); |
319 int len = va_arg(val, int); |
269 // int ifid = cc->GetIFID(ifname); |
320 // int ifid = cc->GetIFID(ifname); |
270 retval = simstrlcpy(buf, len, "00:03:47:70:89:03"); // For testing purposes: Instead, retrieve interface MAC addr. |
321 retval = simstrlcpy(buf, len, clickInstance->GetMacAddrFromIfid (clickInstance->GetInterfaceId (ifname))); |
271 |
322 |
272 NS_LOG_UNCOND ("SIMCLICK_MACADDR_FROM_NAME: "<< ifname << " "<< buf << " "<< len); |
323 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_MACADDR_FROM_NAME: "<< ifname << " "<< buf << " "<< len); |
273 break; |
324 break; |
274 } |
325 } |
275 |
326 |
276 case SIMCLICK_SCHEDULE: |
327 case SIMCLICK_SCHEDULE: |
277 { |
328 { |
281 |
332 |
282 |
333 |
283 Simulator::Schedule (Seconds(simdelay), &Ipv4ClickRouting::HandleScheduleFromClick, clickInstance, when); //Testing |
334 Simulator::Schedule (Seconds(simdelay), &Ipv4ClickRouting::HandleScheduleFromClick, clickInstance, when); //Testing |
284 |
335 |
285 // clickInstance->HandleScheduleFromClick (simnode,when); |
336 // clickInstance->HandleScheduleFromClick (simnode,when); |
286 NS_LOG_UNCOND ("SIMCLICK_SCHEDULE: "<< simtime << " " << Simulator::Now ().GetSeconds () << " " <<simdelay); |
337 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_SCHEDULE: "<< simtime << " " << Simulator::Now ().GetSeconds () << " " <<simdelay); |
287 |
338 |
288 retval = 0; |
339 retval = 0; |
289 break; |
340 break; |
290 } |
341 } |
291 |
342 |
292 case SIMCLICK_GET_NODE_NAME: |
343 case SIMCLICK_GET_NODE_NAME: |
293 { |
344 { |
294 char *buf = va_arg(val, char *); |
345 char *buf = va_arg(val, char *); |
295 int len = va_arg(val, int); |
346 int len = va_arg(val, int); |
296 retval = simstrlcpy(buf, len, "Node0"); |
347 retval = simstrlcpy(buf, len, clickInstance->GetNodeName ()); |
297 |
348 |
298 NS_LOG_UNCOND ("SIMCLICK_GET_NODE_NAME: " << buf); |
349 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_GET_NODE_NAME: " << buf); |
299 break; |
350 break; |
300 } |
351 } |
301 |
352 |
302 case SIMCLICK_IF_READY: |
353 case SIMCLICK_IF_READY: |
303 { |
354 { |
304 int ifid = va_arg(val, int); |
355 int ifid = va_arg(val, int); |
305 |
356 |
306 // We're not using a ClickQueue, so we're always ready (for the timebeing) |
357 // We're not using a ClickQueue, so we're always ready (for the timebeing) |
307 retval = 1; |
358 retval = 1; |
308 |
359 |
309 NS_LOG_UNCOND ("SIMCLICK_IF_READY: " << ifid << " " << Simulator::Now ()); |
360 NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_READY: " << ifid << " " << Simulator::Now ()); |
310 break; |
361 break; |
311 } |
362 } |
312 |
363 |
313 case SIMCLICK_TRACE: |
364 case SIMCLICK_TRACE: |
314 { |
365 { |
315 NS_LOG_UNCOND ("Received a call for SIMCLICK_TRACE"); |
366 NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_TRACE"); |
316 break; |
367 break; |
317 } |
368 } |
318 |
369 |
319 case SIMCLICK_GET_NODE_ID: |
370 case SIMCLICK_GET_NODE_ID: |
320 { |
371 { |
321 NS_LOG_UNCOND ("Received a call for SIMCLICK_GET_NODE_ID"); |
372 NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID"); |
322 break; |
373 break; |
323 } |
374 } |
324 } |
375 } |
325 return retval; |
376 return retval; |
326 } |
377 } |