From: Richard Whitehouse Date: Sat, 16 Apr 2011 14:50:18 +0000 (+0100) Subject: Refactored MooseHelper into generic Link Layer Helper X-Git-Url: https://git.richardwhiuk.com/?a=commitdiff_plain;h=eb52492e1d6cf88995ed26979e02c75a702a7d33;p=ns-moose.git Refactored MooseHelper into generic Link Layer Helper --- diff --git a/src/helper/link-layer-helper.cc b/src/helper/link-layer-helper.cc new file mode 100644 index 0000000..c0b6385 --- /dev/null +++ b/src/helper/link-layer-helper.cc @@ -0,0 +1,289 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008,2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard Whitehouse + */ + +#include +#include +#include "link-layer-helper.h" +#include "ns3/moose-prefix-address.h" +#include "ns3/log.h" + +#include +#include + +NS_LOG_COMPONENT_DEFINE ("LinkLayerHelper"); + +namespace ns3 { + +LinkLayerHelper::LinkLayerHelper(){ + // Sensible defaults. + + // Medium + + csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate("1Gbps"))); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + + // Internet + + // IPv4 + + ipv4.SetBase ("10.0.0.0", "255.0.0.0"); + + // Ethernet Technology + + moose = true; + routing = true; // Simulation based routing +} + +LinkLayerHelper::~LinkLayerHelper(){ + +} + +bool LinkLayerHelper::SupportsLinkLayer(std::string linkLayer){ + if(linkLayer == "moose" || linkLayer == "ethernet"){ + return true; + } + return false; +} + +void LinkLayerHelper::SetLinkLayer(std::string linkLayer){ + if(linkLayer == "moose"){ + moose = true; + } else if(linkLayer == "ethernet"){ + moose = false; + } +} + +void LinkLayerHelper::EnableDynamicRouting(){ + routing = false; +} + +void LinkLayerHelper::DisableDynamicRouting(){ + routing = true; +} + +LinkLayerHelper::Network LinkLayerHelper::Create(Topology& t){ + + // Create the bridges and hosts + + Network n; + + n.bridges.Create(t.bridges); + n.hosts.Create(t.hosts); + + std::map > > portMap; + + // Link them up + + // Host-Bridge + + for( + Topology::HostLinks::iterator it = t.hostLinks.begin(); + it != t.hostLinks.end(); + it ++){ + + NodeContainer nc; + + if(it->first >= t.hosts){ + assert(false); + } + + if(it->second >= t.bridges){ + assert(false); + } + + nc.Add(n.hosts.Get(it->first)); + nc.Add(n.bridges.Get(it->second)); + + NetDeviceContainer link = csma.Install(nc); + + n.hostDevices[it->first].Add(link.Get(0)); + n.bridgeDevices[it->second].Add(link.Get(1)); + } + + // Bridge-Bridge + + for( + Topology::BridgeLinks::iterator it = t.bridgeLinks.begin(); + it != t.bridgeLinks.end(); + it ++){ + + NodeContainer nc; + + if(it->first >= t.bridges){ + assert(false); + } + + if(it->second >= t.bridges){ + assert(false); + } + + nc.Add(n.bridges.Get(it->first)); + nc.Add(n.bridges.Get(it->second)); + + NetDeviceContainer link = csma.Install(nc); + + n.bridgeDevices[it->first].Add(link.Get(0)); + n.bridgeDevices[it->second].Add(link.Get(1)); + + portMap[it->first][it->second] = link.Get(0); + portMap[it->second][it->first] = link.Get(1); + + } + + + // Install Bridges + + if(moose){ + + // Routing + + if(routing){ + + // Djkstra - Give all links the same weight for now. + + std::vector weights(t.bridgeLinks.size(), 1); + + const long num_nodes = t.bridges; + + graph_t g(t.bridgeLinks.begin(), t.bridgeLinks.end(), weights.begin(), num_nodes); + boost::property_map::type weightmap = get(boost::edge_weight, g); + + for(long root = 0; root < t.bridges; root ++){ + + std::vector p(num_vertices(g)); + vertex_descriptor s = boost::vertex(root,g); + boost::dijkstra_shortest_paths(g, s, boost::predecessor_map(&p[0])); + + boost::graph_traits::vertex_iterator vi, vend; + + std::multimap, MoosePrefixAddress> routes; + + for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { + + if(*vi == s){ + // Don't inject into routing table. + } else { + vertex_descriptor current = *vi; + while(p[current] != p[p[current]]){ + current = p[current]; + } + + if(p[current] == s){ + // Inject routing decision + + routes.insert(std::make_pair(portMap[root][current],MoosePrefixAddress(*vi))); + + } else { + // Don't inject + } + } + } + + // Create the switch + + Ptr bridgeNode = n.bridges.Get(root); + mooseHelper.Install(bridgeNode, n.bridgeDevices[root], MoosePrefixAddress(root), routes); + + } + + } else { + + // Realtime routing + + for(long i = 0; i < t.bridges; i ++){ + Ptr bridgeNode = n.bridges.Get(i); + mooseHelper.Install(bridgeNode, n.bridgeDevices[i]); + } + } + } else { + if(routing){ + + // Kruskall's - Give all links the same weight for now. + + const long num_nodes = t.bridges; + + std::vector tree; + + std::vector weights(t.bridgeLinks.size(), 1); + + graph_t g(t.bridgeLinks.begin(), t.bridgeLinks.end(), weights.begin(), num_nodes); + + kruskal_minimum_spanning_tree(g,std::back_inserter(tree)); + + std::map > spanning; + + for(long i = 0; i < t.bridges; ++i){ + for(long j = 0; i < t.bridges; ++i){ + spanning[i][j] = false; + } + } + + for(std::vector::iterator it = tree.begin(); it != tree.end(); ++it){ + spanning[source(*it,g)][target(*it,g)] = true; + spanning[target(*it,g)][source(*it,g)] = true; + } + + // Disable the other ports not included. + + // bridge[0] has link to bridge[1] on port x => portMap[0][1] = x + + // Question: is bridge[0][1] in spanning tree? -> i.e. is there some x, for which tree[x] = <0,1> + + + for(long i = 0; i < t.bridges; i ++){ + + std::map, bool> portsEnabled; + + for(std::map >::iterator it = portMap[i].begin(); it != portMap[i].end(); it ++){ + portsEnabled[it->second] = spanning[i][it->first]; + } + + + Ptr bridgeNode = n.bridges.Get(i); + ethernetHelper.Install(bridgeNode, n.bridgeDevices[i], portsEnabled); + } + + + } else { + // Requires STP implementation + + for(long i = 0; i < t.bridges; i ++){ + + Ptr bridgeNode = n.bridges.Get(i); + ethernetHelper.Install(bridgeNode, n.bridgeDevices[i]); + } + } + } + + // Setup the internet + + internet.Install(n.hosts); + + for(long i = 0; i < t.hosts; i ++){ + n.interfaces[i] = ipv4.Assign(n.hostDevices[i]); + } + + return n; + +} + + +} + diff --git a/src/helper/link-layer-helper.h b/src/helper/link-layer-helper.h new file mode 100644 index 0000000..d09d4da --- /dev/null +++ b/src/helper/link-layer-helper.h @@ -0,0 +1,105 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008,2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard Whitehouse + */ + +#ifndef MOOSE_HELPER_H +#define MOOSE_HELPER_H + +#include "ns3/topology.h" +#include "ns3/node.h" +#include "ns3/moose-bridge-net-device.h" +#include "ns3/moose-bridge-helper.h" +#include "ns3/bridge-helper.h" +#include "internet-stack-helper.h" +#include "ipv4-address-helper.h" +#include "csma-helper.h" + +// Boost Graph Library for static route computation. + +#include +#include + +#include + +namespace ns3 { + +/** + * \ingroup bridge + * + * \brief Helper to create Ethernet / MOOSE bridged networks + */ +class LinkLayerHelper { + +public: + + typedef boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, boost::no_property, boost::property > graph_t; + + typedef boost::graph_traits< graph_t >::vertex_descriptor vertex_descriptor; + typedef boost::graph_traits< graph_t >::edge_descriptor edge_descriptor; + + struct Network { + + // Contains all the nodes :-) + + NodeContainer bridges; + NodeContainer hosts; + + // NetDevices + + std::map bridgeDevices; + std::map hostDevices; + + // IP Interfaces + + std::map interfaces; + + }; + + CsmaHelper csma; + Ipv4AddressHelper ipv4; + InternetStackHelper internet; + MooseBridgeHelper mooseHelper; + BridgeHelper ethernetHelper; + + LinkLayerHelper(); + + ~LinkLayerHelper(); + + bool SupportsLinkLayer(std::string linkLayer); + + void SetLinkLayer(std::string linkLayer); + + void EnableDynamicRouting(); + + void DisableDynamicRouting(); + + Network Create(Topology& t); + +private: + + bool moose; + bool routing; + + +}; + +} + +#endif + diff --git a/src/helper/moose-helper.cc b/src/helper/moose-helper.cc deleted file mode 100644 index 0cd64a7..0000000 --- a/src/helper/moose-helper.cc +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2008,2009 IITP RAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Richard Whitehouse - */ - -#include -#include -#include "moose-helper.h" -#include "ns3/moose-prefix-address.h" -#include "ns3/log.h" - -#include -#include - -NS_LOG_COMPONENT_DEFINE ("MooseHelper"); - -namespace ns3 { - -MooseHelper::MooseHelper(){ - // Sensible defaults. - - // Medium - - csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate("1Gbps"))); - csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); - - // Internet - - // IPv4 - - ipv4.SetBase ("10.0.0.0", "255.0.0.0"); - - // Ethernet Technology - - moose = true; - routing = true; // Simulation based routing -} - -MooseHelper::~MooseHelper(){ - -} - -void MooseHelper::SetMoose(){ - moose = true; -} - -void MooseHelper::SetEthernet(){ - moose = false; -} - -void MooseHelper::EnableDynamicRouting(){ - routing = false; -} - -void MooseHelper::DisableDynamicRouting(){ - routing = true; -} - -MooseHelper::Network MooseHelper::Create(Topology& t){ - - // Create the bridges and hosts - - Network n; - - n.bridges.Create(t.bridges); - n.hosts.Create(t.hosts); - - std::map > > portMap; - - // Link them up - - // Host-Bridge - - for( - Topology::HostLinks::iterator it = t.hostLinks.begin(); - it != t.hostLinks.end(); - it ++){ - - NodeContainer nc; - - if(it->first >= t.hosts){ - assert(false); - } - - if(it->second >= t.bridges){ - assert(false); - } - - nc.Add(n.hosts.Get(it->first)); - nc.Add(n.bridges.Get(it->second)); - - NetDeviceContainer link = csma.Install(nc); - - n.hostDevices[it->first].Add(link.Get(0)); - n.bridgeDevices[it->second].Add(link.Get(1)); - } - - // Bridge-Bridge - - for( - Topology::BridgeLinks::iterator it = t.bridgeLinks.begin(); - it != t.bridgeLinks.end(); - it ++){ - - NodeContainer nc; - - if(it->first >= t.bridges){ - assert(false); - } - - if(it->second >= t.bridges){ - assert(false); - } - - nc.Add(n.bridges.Get(it->first)); - nc.Add(n.bridges.Get(it->second)); - - NetDeviceContainer link = csma.Install(nc); - - n.bridgeDevices[it->first].Add(link.Get(0)); - n.bridgeDevices[it->second].Add(link.Get(1)); - - portMap[it->first][it->second] = link.Get(0); - portMap[it->second][it->first] = link.Get(1); - - } - - - // Install Bridges - - if(moose){ - - // Routing - - if(routing){ - - // Djkstra - Give all links the same weight for now. - - std::vector weights(t.bridgeLinks.size(), 1); - - const long num_nodes = t.bridges; - - graph_t g(t.bridgeLinks.begin(), t.bridgeLinks.end(), weights.begin(), num_nodes); - boost::property_map::type weightmap = get(boost::edge_weight, g); - - for(long root = 0; root < t.bridges; root ++){ - - std::vector p(num_vertices(g)); - vertex_descriptor s = boost::vertex(root,g); - boost::dijkstra_shortest_paths(g, s, boost::predecessor_map(&p[0])); - - boost::graph_traits::vertex_iterator vi, vend; - - std::multimap, MoosePrefixAddress> routes; - - for (boost::tie(vi, vend) = vertices(g); vi != vend; ++vi) { - - if(*vi == s){ - // Don't inject into routing table. - } else { - vertex_descriptor current = *vi; - while(p[current] != p[p[current]]){ - current = p[current]; - } - - if(p[current] == s){ - // Inject routing decision - - routes.insert(std::make_pair(portMap[root][current],MoosePrefixAddress(*vi))); - - } else { - // Don't inject - } - } - } - - // Create the switch - - Ptr bridgeNode = n.bridges.Get(root); - mooseHelper.Install(bridgeNode, n.bridgeDevices[root], MoosePrefixAddress(root), routes); - - } - - } else { - - // Realtime routing - - for(long i = 0; i < t.bridges; i ++){ - Ptr bridgeNode = n.bridges.Get(i); - mooseHelper.Install(bridgeNode, n.bridgeDevices[i]); - } - } - } else { - if(routing){ - - // Kruskall's - Give all links the same weight for now. - - const long num_nodes = t.bridges; - - std::vector tree; - - std::vector weights(t.bridgeLinks.size(), 1); - - graph_t g(t.bridgeLinks.begin(), t.bridgeLinks.end(), weights.begin(), num_nodes); - - kruskal_minimum_spanning_tree(g,std::back_inserter(tree)); - - std::map > spanning; - - for(long i = 0; i < t.bridges; ++i){ - for(long j = 0; i < t.bridges; ++i){ - spanning[i][j] = false; - } - } - - for(std::vector::iterator it = tree.begin(); it != tree.end(); ++it){ - spanning[source(*it,g)][target(*it,g)] = true; - spanning[target(*it,g)][source(*it,g)] = true; - } - - // Disable the other ports not included. - - // bridge[0] has link to bridge[1] on port x => portMap[0][1] = x - - // Question: is bridge[0][1] in spanning tree? -> i.e. is there some x, for which tree[x] = <0,1> - - - for(long i = 0; i < t.bridges; i ++){ - - std::map, bool> portsEnabled; - - for(std::map >::iterator it = portMap[i].begin(); it != portMap[i].end(); it ++){ - portsEnabled[it->second] = spanning[i][it->first]; - } - - - Ptr bridgeNode = n.bridges.Get(i); - ethernetHelper.Install(bridgeNode, n.bridgeDevices[i], portsEnabled); - } - - - } else { - // Requires STP implementation - - for(long i = 0; i < t.bridges; i ++){ - - Ptr bridgeNode = n.bridges.Get(i); - ethernetHelper.Install(bridgeNode, n.bridgeDevices[i]); - } - } - } - - // Setup the internet - - internet.Install(n.hosts); - - for(long i = 0; i < t.hosts; i ++){ - n.interfaces[i] = ipv4.Assign(n.hostDevices[i]); - } - - return n; - -} - - -} - diff --git a/src/helper/moose-helper.h b/src/helper/moose-helper.h deleted file mode 100644 index dc72fed..0000000 --- a/src/helper/moose-helper.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2008,2009 IITP RAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Richard Whitehouse - */ - -#ifndef MOOSE_HELPER_H -#define MOOSE_HELPER_H - -#include "ns3/topology.h" -#include "ns3/node.h" -#include "ns3/moose-bridge-net-device.h" -#include "ns3/moose-bridge-helper.h" -#include "ns3/bridge-helper.h" -#include "internet-stack-helper.h" -#include "ipv4-address-helper.h" -#include "csma-helper.h" - -// Boost Graph Library for static route computation. - -#include -#include - -#include - -namespace ns3 { - -/** - * \ingroup bridge - * - * \brief Helper to create Ethernet / MOOSE bridged networks - */ -class MooseHelper { - -public: - - typedef boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, boost::no_property, boost::property > graph_t; - - typedef boost::graph_traits< graph_t >::vertex_descriptor vertex_descriptor; - typedef boost::graph_traits< graph_t >::edge_descriptor edge_descriptor; - - struct Network { - - // Contains all the nodes :-) - - NodeContainer bridges; - NodeContainer hosts; - - // NetDevices - - std::map bridgeDevices; - std::map hostDevices; - - // IP Interfaces - - std::map interfaces; - - }; - - CsmaHelper csma; - Ipv4AddressHelper ipv4; - InternetStackHelper internet; - MooseBridgeHelper mooseHelper; - BridgeHelper ethernetHelper; - - MooseHelper(); - - ~MooseHelper(); - - void SetMoose(); - - void SetEthernet(); - - void EnableDynamicRouting(); - - void DisableDynamicRouting(); - - Network Create(Topology& t); - -private: - - bool moose; - bool routing; - - -}; - -} - -#endif - diff --git a/src/helper/wscript b/src/helper/wscript index 7c410ef..0fb2393 100644 --- a/src/helper/wscript +++ b/src/helper/wscript @@ -28,7 +28,7 @@ def build(bld): 'ipv4-routing-helper.cc', 'aodv-helper.cc', 'mesh-helper.cc', - 'moose-helper.cc', + 'link-layer-helper.cc', 'dot11s-installer.cc', 'flame-installer.cc', 'athstats-helper.cc', @@ -79,7 +79,7 @@ def build(bld): 'ipv4-routing-helper.h', 'aodv-helper.h', 'mesh-helper.h', - 'moose-helper.h', + 'link-layer-helper.h', 'mesh-stack-installer.h', 'dot11s-installer.h', 'flame-installer.h',