blob: 30d0780a070cf9cd0dc350e1a58ee18481a58dcd [file] [log] [blame]
Ilya Moiseenko58d26672011-12-08 13:48:06 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2010 Hajime Tazaki
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: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
19 * Ilya Moiseenko <iliamo@cs.ucla.edu>
20 */
21
22#include <fstream>
23#include <cstdlib>
24#include <iostream>
25#include <sstream>
26#include <regex.h>
27
28#include "ns3/log.h"
29#include "rocketfuel-weights-reader.h"
30
31namespace ns3 {
32
33 NS_LOG_COMPONENT_DEFINE ("RocketfuelWeightsReader");
34
35 NS_OBJECT_ENSURE_REGISTERED (RocketfuelWeightsReader);
36
37 TypeId RocketfuelWeightsReader::GetTypeId (void)
38 {
39 static TypeId tid = TypeId ("ns3::RocketfuelWeightsReader")
40 .SetParent<Object> ()
41 ;
42 return tid;
43 }
44
45 RocketfuelWeightsReader::RocketfuelWeightsReader ()
46 {
47 NS_LOG_FUNCTION (this);
48 }
49
50 RocketfuelWeightsReader::~RocketfuelWeightsReader ()
51 {
52 NS_LOG_FUNCTION (this);
53 }
54
55 /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
56
57#define REGMATCH_MAX 16
58
59#define START "^"
60#define END "$"
61#define SPACE "[ \t]+"
62#define MAYSPACE "[ \t]*"
63
64#define ROCKETFUEL_MAPS_LINE \
65START "(-*[0-9]+)" SPACE "(@[?A-Za-z0-9,+]+)" SPACE \
66"(\\+)*" MAYSPACE "(bb)*" MAYSPACE \
67"\\(([0-9]+)\\)" SPACE "(&[0-9]+)*" MAYSPACE \
68"->" MAYSPACE "(<[0-9 \t<>]+>)*" MAYSPACE \
69"(\\{-[0-9\\{\\} \t-]+\\})*" SPACE \
70"=([A-Za-z0-9.!-]+)" SPACE "r([0-9])" \
71MAYSPACE END
72
73#define ROCKETFUEL_WEIGHTS_LINE \
74START "([^ \t]+)" SPACE "([^ \t]+)" SPACE "([0-9.]+)" MAYSPACE END
75
76 int linksNumber = 0;
77 int nodesNumber = 0;
78 std::map<std::string, Ptr<Node> > nodeMap;
79
80 NodeContainer
Ilya Moiseenko09ac8992011-12-12 17:55:42 -080081 RocketfuelWeightsReader::GenerateFromWeightsFile (int argc, char *argv[], char *argl[])
Ilya Moiseenko58d26672011-12-08 13:48:06 -080082 {
83 /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
84 std::string sname;
85 std::string tname;
86 char *endptr;
87 NodeContainer nodes;
88
89 sname = argv[0];
90 tname = argv[1];
91 double v = strtod (argv[2], &endptr); // weight
Ilya Moiseenko09ac8992011-12-12 17:55:42 -080092 double l = strtod (argl[2], &endptr); //latency
Ilya Moiseenko58d26672011-12-08 13:48:06 -080093 // cast v to void , to suppress 'v' set but not used compiler warning
94 //(void) v;
95
96
97
98 if (*endptr != '\0')
99 {
100 NS_LOG_WARN ("invalid weight: " << argv[2]);
101 return nodes;
102 }
103
104 // Create node and link
105 if (!sname.empty () && !tname.empty ())
106 {
107 if (nodeMap[sname] == 0)
108 {
109 Ptr<Node> tmpNode = CreateObject<Node> ();
110 nodeMap[sname] = tmpNode;
111 nodes.Add (tmpNode);
112 nodesNumber++;
113 }
114
115 if (nodeMap[tname] == 0)
116 {
117 Ptr<Node> tmpNode = CreateObject<Node> ();
118 nodeMap[tname] = tmpNode;
119 nodes.Add (tmpNode);
120 nodesNumber++;
121 }
122 NS_LOG_INFO (linksNumber << ":" << nodesNumber << " From: " << sname << " to: " << tname);
123 TopologyReader::ConstLinksIterator iter;
124 bool found = false;
125 for (iter = LinksBegin (); iter != LinksEnd (); iter++)
126 {
127 if ((iter->GetFromNode () == nodeMap[tname])
128 && (iter->GetToNode () == nodeMap[sname]))
129 {
130 found = true;
131 break;
132 }
133 }
134
135 if (!found)
136 {
137 Link link (nodeMap[sname], sname, nodeMap[tname], tname);
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800138
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800139 std::ostringstream s;
140 s << std::setprecision(2) << v;
141 std::string ss = s.str();
142 link.SetAttribute ("OSPF", ss);
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800143
144 std::ostringstream s2;
145 s2 << std::setprecision(2) << l;
146 std::string ss2 = s2.str();
147 link.SetAttribute("Latency", ss2);
148 NS_LOG_INFO("Written Latency = " << ss2);
149
150
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800151 AddLink (link);
152 linksNumber++;
153 }
154 }
155 return nodes;
156 }
157
158 enum RocketfuelWeightsReader::RF_FileType
159 RocketfuelWeightsReader::GetFileType (const char *line)
160 {
161 int ret;
162 regmatch_t regmatch[REGMATCH_MAX];
163 regex_t regex;
164 char errbuf[512];
165
166 // Check whether MAPS file or not
167 ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
168 if (ret != 0)
169 {
170 regerror (ret, &regex, errbuf, sizeof (errbuf));
171 return RF_UNKNOWN;
172 }
173 ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
174 if (ret != REG_NOMATCH)
175 {
176 regfree (&regex);
177 return RF_MAPS;
178 }
179 regfree (&regex);
180
181 // Check whether Weights file or not
182 ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
183 if (ret != 0)
184 {
185 regerror (ret, &regex, errbuf, sizeof (errbuf));
186 return RF_UNKNOWN;
187 }
188 ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
189 if (ret != REG_NOMATCH)
190 {
191 regfree (&regex);
192 return RF_WEIGHTS;
193 }
194 regfree (&regex);
195
196 return RF_UNKNOWN;
197 }
198
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800199 NodeContainer
200 RocketfuelWeightsReader::Read (void)
201 {
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800202 NodeContainer nodes;
203 NS_LOG_INFO("Not implemented");
204 return nodes;
205 }
206
207 NodeContainer
208 RocketfuelWeightsReader::Read (std::string latenciesFile)
209 {
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800210 std::ifstream topgen;
211 topgen.open (GetFileName ().c_str ());
212 NodeContainer nodes;
213
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800214 std::ifstream latencies;
215 latencies.open(latenciesFile.c_str());
216
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800217 std::istringstream lineBuffer;
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800218 std::istringstream lineBuffer2;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800219 std::string line;
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800220 std::string line2;
221
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800222 int lineNumber = 0;
223 enum RF_FileType ftype = RF_UNKNOWN;
224 char errbuf[512];
225
226 if (!topgen.is_open ())
227 {
228 NS_LOG_WARN ("Couldn't open the file " << GetFileName ());
229 return nodes;
230 }
231
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800232 if (!latencies.is_open ())
233 {
234 NS_LOG_WARN ("Couldn't open Latencies file " << latenciesFile);
235 return nodes;
236 }
237
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800238 while (!topgen.eof ())
239 {
240 int ret;
241 int argc;
242 char *argv[REGMATCH_MAX];
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800243 char *argl[REGMATCH_MAX];
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800244 char *buf;
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800245 char *buf2;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800246
247 lineNumber++;
248 line.clear ();
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800249 line2.clear ();
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800250 lineBuffer.clear ();
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800251 lineBuffer2.clear ();
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800252
253 getline (topgen, line);
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800254 getline (latencies, line2);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800255 buf = (char *)line.c_str ();
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800256 buf2 = (char *)line2.c_str ();
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800257
258 if (lineNumber == 1)
259 {
260 ftype = GetFileType (buf);
261 if (ftype == RF_UNKNOWN)
262 {
263 NS_LOG_INFO ("Unknown File Format (" << GetFileName () << ")");
264 break;
265 }
266 }
267
268 regmatch_t regmatch[REGMATCH_MAX];
269 regex_t regex;
270
271 if (ftype == RF_MAPS)
272 {
273 ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
274 if (ret != 0)
275 {
276 regerror (ret, &regex, errbuf, sizeof (errbuf));
277 regfree (&regex);
278 break;
279 }
280
281 ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
282 if (ret == REG_NOMATCH)
283 {
284 NS_LOG_WARN ("match failed (maps file): %s" << buf);
285 regfree (&regex);
286 break;
287 }
288 }
289 else if (ftype == RF_WEIGHTS)
290 {
291 ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
292 if (ret != 0)
293 {
294 regerror (ret, &regex, errbuf, sizeof (errbuf));
295 regfree (&regex);
296 break;
297 }
298
299 ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800300 regexec (&regex, buf2, REGMATCH_MAX, regmatch, 0);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800301 if (ret == REG_NOMATCH)
302 {
303 NS_LOG_WARN ("match failed (weights file): %s" << buf);
304 regfree (&regex);
305 break;
306 }
307 }
308
309 line = buf;
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800310 line2 = buf2;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800311 argc = 0;
312
313 /* regmatch[0] is the entire strings that matched */
314 for (int i = 1; i < REGMATCH_MAX; i++)
315 {
316 if (regmatch[i].rm_so == -1)
317 {
318 argv[i - 1] = NULL;
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800319 argl[i - 1] = NULL;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800320 }
321 else
322 {
323 line[regmatch[i].rm_eo] = '\0';
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800324 line2[regmatch[i].rm_eo] = '\0';
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800325 argv[i - 1] = &line[regmatch[i].rm_so];
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800326 argl[i - 1] = &line2[regmatch[i].rm_so];
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800327 argc = i;
328 }
329 }
330
331 if (ftype == RF_MAPS)
332 {
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800333 NS_LOG_INFO("MAPS FILE is not supported");
334 //nodes.Add (GenerateFromMapsFile (argc, argv));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800335 }
336 else if (ftype == RF_WEIGHTS)
337 {
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800338 nodes.Add (GenerateFromWeightsFile (argc, argv, argl));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800339 }
340 else
341 {
342 NS_LOG_WARN ("Unsupported file format (only Maps/Weights are supported)");
343 }
344
345 regfree (&regex);
346 }
347
348
349 topgen.close ();
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800350 latencies.close ();
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800351 NS_LOG_INFO ("Rocketfuel topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
352 return nodes;
353 }
354
355
356void
357RocketfuelWeightsReader::ApplySettings(NetDeviceContainer* ndc, NodeContainer* nc)
358{
359 InternetStackHelper stack;
360 Ipv4AddressHelper address;
361 address.SetBase ("10.1.0.0", "255.255.0.0");
362
363 Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
364 stack.SetRoutingHelper (ipv4RoutingHelper);
365
366 //This loop passes all links and checks if ipv4 is installed on the node
367 // if not, it installs.
368 // We can't use stack.Install(nc) because in nc there are duplicates and assertion fails
369 TopologyReader::ConstLinksIterator iter;
370 int j = 0;
371 for ( iter = this->LinksBegin (); iter != this->LinksEnd (); iter++, j++ )
372 {
373 NodeContainer twoNodes = nc[j];
374
375 Ptr<Node> nd = twoNodes.Get(0);
376 if(nd==NULL)
377 NS_LOG_INFO("nd = null");
378
379 Ptr<Node> nd2 = twoNodes.Get(1);
380 if(nd2==NULL)
381 NS_LOG_INFO("nd2 = null");
382
383 Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
384 if(ipv4 == 0)
385 {
386 NS_LOG_INFO("ipv4 = null");
387 stack.Install(nd);
388 }
389
390 Ptr<Ipv4> ipv42 = nd2->GetObject<Ipv4>();
391 if(ipv42 == 0)
392 {
393 NS_LOG_INFO("ipv42 = null");
394 stack.Install(nd2);
395 }
396
397 //NS_LOG_INFO("#netdevices = " << nd->GetNDevices());
398 //NS_LOG_INFO("#netdevices = " << nd2->GetNDevices());
399 }
400
401 NS_LOG_INFO("ITER2");
402
403 PointToPointHelper p2p;
404 TopologyReader::ConstLinksIterator iter2;
405 int i = 0;
406 for ( iter2 = this->LinksBegin (); iter2 != this->LinksEnd (); iter2++, i++ )
407 {
408 p2p.SetDeviceAttribute("DataRate", StringValue("9920000Kbps"));
Ilya Moiseenko09ac8992011-12-12 17:55:42 -0800409 //p2p.SetChannelAttribute("Delay", StringValue("10ms"));
410 NS_LOG_INFO("Latency = " + iter2->GetAttribute("Latency")+"ms");
411 p2p.SetChannelAttribute("Delay", StringValue(iter2->GetAttribute("Latency")+"ms"));
412
413
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800414 p2p.SetQueue("ns3::DropTailQueue","MaxPackets",StringValue("100"));
415 ndc[i] = p2p.Install(nc[i]);
416
417
418 NodeContainer twoNodes = nc[i];
419
420 Ptr<Node> nd = twoNodes.Get(0);
421 if(nd==NULL)
422 NS_LOG_INFO("nd = null");
423
424
425
426 Ptr<Node> nd2 = twoNodes.Get(1);
427 if(nd2==NULL)
428 NS_LOG_INFO("nd2 = null");
429
430 //NS_LOG_INFO("1");
431 NS_LOG_INFO("#netdevices = " << nd->GetNDevices());
432 NS_LOG_INFO("#netdevices = " << nd2->GetNDevices());
433
434 Ptr<NetDevice> device = nd->GetDevice(nd->GetNDevices()-1)->GetObject<PointToPointNetDevice> ();
435
436 if(device==NULL)
437 NS_LOG_INFO("device = 0");
438
439 std::string ospf = iter2->GetAttribute("OSPF");
440 double metric_d = atof(ospf.c_str());
441 uint16_t metric = static_cast<int>(metric_d * 10);
442 NS_LOG_INFO("OSPF metric = " << metric);
443
444 {
445 NetDeviceContainer* temp = new NetDeviceContainer[1];
446 temp->Add(device);
447 address.Assign (*temp);
448 }
449
450 Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
451 if(ipv4 == 0)
452 {
453 NS_LOG_INFO("ipv4 = null");
454 //stack.Install(nd);
455 /*NetDeviceContainer* temp = new NetDeviceContainer[1];
456 temp->Add(device);
457 address.Assign (*temp);
458 ipv4 = nd->GetObject<Ipv4>();*/
459 }
460
461 NS_LOG_INFO("Before GetID");
462 int32_t interfaceId = ipv4->GetInterfaceForDevice(device);
463 NS_LOG_INFO("InterfaceID = " << interfaceId);
464 ipv4->SetMetric(interfaceId,metric);
465
466
467
468
469
470 /*Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
471
472 if(ipv4 == 0)
473 NS_LOG_INFO("ipv4 = null");
474 int32_t interfaceId = ipv4->GetInterfaceForDevice(device);
475 ipv4->SetMetric(interfaceId,metric);*/
476
477 //Ptr<Ipv4Interface> interface = nd->GetDevice(nd->GetNDevices()-1)->GetObject<Ipv4Interface> ();
478 //ipv4->SetMetric(metric);
479
480 //NS_LOG_INFO("2");
481
482 Ptr<NetDevice> device2 = nd2->GetDevice(nd2->GetNDevices()-1)->GetObject<PointToPointNetDevice> ();
483
484 if(device2==NULL)
485 NS_LOG_INFO("device2 = 0");
486
487 {
488 NetDeviceContainer* temp = new NetDeviceContainer[1];
489 temp->Add(device2);
490 address.Assign (*temp);
491 }
492
493 Ptr<Ipv4> ipv42 = nd2->GetObject<Ipv4>();
494 if(ipv42 == 0)
495 {
496 NS_LOG_INFO("ipv42 = null");
497 /*stack.Install(nd2);
498 NetDeviceContainer* temp = new NetDeviceContainer[1];
499 temp->Add(device2);
500 address.Assign (*temp);
501 ipv42 = nd2->GetObject<Ipv4>();*/
502 }
503
504 NS_LOG_INFO("Before GetID");
505 interfaceId = ipv42->GetInterfaceForDevice(device2);
506 NS_LOG_INFO("InterfaceID = " << interfaceId);
507 ipv42->SetMetric(interfaceId,metric);
508
509
510
511 /*PointerValue tmp1;
512 device->GetAttribute ("TxQueue", tmp1);
513 //NS_LOG_INFO("2.5");
514 Ptr<Object> txQueue1 = tmp1.GetObject ();
515
516 PointerValue tmp2;
517 device2->GetAttribute ("TxQueue", tmp2);
518 Ptr<Object> txQueue2 = tmp2.GetObject ();
519 //NS_LOG_INFO("3");
520 Ptr<DropTailQueue> dtq1 = txQueue1->GetObject <DropTailQueue> ();
521 NS_ASSERT (dtq1 != 0);
522
523 Ptr<DropTailQueue> dtq2 = txQueue2->GetObject <DropTailQueue> ();
524 NS_ASSERT (dtq2 != 0);
525
526 std::string queuesize1 = iter2->GetAttribute("QueueSizeNode1");
527 std::string queuesize2 = iter2->GetAttribute("QueueSizeNode2");
528 //NS_LOG_INFO("4");
529 txQueue1->SetAttribute("MaxPackets", UintegerValue (atoi(queuesize1.c_str())));
530 txQueue2->SetAttribute("MaxPackets", UintegerValue (atoi(queuesize2.c_str())));
531
532 UintegerValue limit;
533 txQueue1->GetAttribute ("MaxPackets", limit);
534 NS_LOG_INFO ("NetDevice #"<< device->GetIfIndex() << "has queue limit " << limit.Get () << " packets");
535
536 txQueue2->GetAttribute ("MaxPackets", limit);
537 NS_LOG_INFO ("NetDevice #"<< device2->GetIfIndex() << "has queue limit " << limit.Get () << " packets");*/
538 }
539 }
540
541
542} /* namespace ns3 */
543
544