diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index fb4f91311..bc44cd0f0 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -122,16 +122,25 @@ int main (int argc, char *argv[]) PointToPointTopology::AddIpv4Addresses ( channel0, n0, Ipv4Address("10.1.1.1"), n2, Ipv4Address("10.1.1.2")); - channel0->Unref (); PointToPointTopology::AddIpv4Addresses ( channel1, n1, Ipv4Address("10.1.2.1"), n2, Ipv4Address("10.1.2.2")); - channel1->Unref (); PointToPointTopology::AddIpv4Addresses ( channel2, n2, Ipv4Address("10.1.3.1"), n3, Ipv4Address("10.1.3.2")); + + // Finally, we add static routes. These three steps (Channel and + // NetDevice creation, IP Address assignment, and routing) are + // separated because there may be a need to postpone IP Address + // assignment (emulation) or modify to use dynamic routing + PointToPointTopology::AddIpv4Routes(n0, n2, channel0); + PointToPointTopology::AddIpv4Routes(n1, n2, channel1); + PointToPointTopology::AddIpv4Routes(n2, n3, channel2); + + channel0->Unref (); + channel1->Unref (); channel2->Unref (); // Create the OnOff application to send UDP datagrams of size diff --git a/src/devices/p2p/p2p-topology.cc b/src/devices/p2p/p2p-topology.cc index 6ff05eab9..84b02528b 100644 --- a/src/devices/p2p/p2p-topology.cc +++ b/src/devices/p2p/p2p-topology.cc @@ -24,6 +24,8 @@ #include #include "ns3/assert.h" +#include "ns3/debug.h" +#include "ns3/fatal-error.h" #include "ns3/nstime.h" @@ -62,7 +64,7 @@ PointToPointTopology::AddPointToPointLink( return channel; } -bool +void PointToPointTopology::AddIpv4Addresses( const PointToPointChannel *chan, Node* n1, const Ipv4Address& addr1, @@ -101,15 +103,82 @@ PointToPointTopology::AddIpv4Addresses( ip2->SetNetworkMask (index2, netmask); ip2->SetUp (index2); - ip1->AddHostRouteTo (addr2, index1); - ip2->AddHostRouteTo (addr1, index2); - ip1->Unref (); ip2->Unref (); - return true; } +void +PointToPointTopology::AddIpv4Routes ( + Node* n1, Node* n2, const PointToPointChannel* chan) +{ + // The PointToPoint channel is used to find the relevant NetDevices + NS_ASSERT (chan->GetNDevices () == 2); + NetDevice* nd1 = chan->GetDevice (0); + NetDevice* nd2 = chan->GetDevice (1); + // XXX nd1, nd2 should be reference counted + + // Assert that n1 is the Node owning one of the two NetDevices + // and make sure that nd1 corresponds to it + if (nd1->PeekNode ()->GetId () == n1->GetId ()) + { + ; // Do nothing + } + else if (nd2->PeekNode ()->GetId () == n1->GetId ()) + { + std::swap(nd1, nd2); + } + else + { + NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel"); + } + + // Assert that n2 is the Node owning one of the two NetDevices + // and make sure that nd2 corresponds to it + if (nd2->PeekNode ()->GetId () != n2->GetId ()) + { + NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel"); + } + + // Assert that both are Ipv4 nodes + IIpv4 *ip1 = nd1->PeekNode ()->QueryInterface (IIpv4::iid); + IIpv4 *ip2 = nd2->PeekNode ()->QueryInterface (IIpv4::iid); + NS_ASSERT(ip1 && ip2); + + // Get interface indexes for both nodes corresponding to the right channel + uint32_t index1 = 0; + bool found = false; + for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++) + { + if (ip1 ->PeekNetDevice (i) == nd1) + { + index1 = i; + found = true; + } + } + NS_ASSERT(found); + + uint32_t index2 = 0; + found = false; + for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++) + { + if (ip2 ->PeekNetDevice (i) == nd2) + { + index2 = i; + found = true; + } + } + NS_ASSERT(found); + + ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1); + ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); + + ip1->Unref (); + ip2->Unref (); + +} + + #ifdef NOTYET // Get the net device connecting node n1 to n2. For topologies where diff --git a/src/devices/p2p/p2p-topology.h b/src/devices/p2p/p2p-topology.h index dc8cbb88d..1a1ed9870 100644 --- a/src/devices/p2p/p2p-topology.h +++ b/src/devices/p2p/p2p-topology.h @@ -33,30 +33,51 @@ class Node; class IPAddr; class DataRate; class Queue; -//class Time; /** - * \brief A helper class to create Topologies based on the ns3::PointToPointNetDevice and - * ns3::PointToPointChannel objects. - * - * XXX ?? - * I think that some of the methods below are not implemented. - * If so, remove them. + * \brief A helper class to create Topologies based on the + * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects. */ class PointToPointTopology { public: /** + * \param n1 Node + * \param n2 Node + * \param rate Maximum transmission link rate + * \param delay one-way propagation delay + * \return Pointer to the underlying PointToPointChannel + * * Add a full-duplex point-to-point link between two nodes - * with the specified IP addresses, with specified maximum transmission rate - * and propagation delay. + * and attach PointToPointNetDevices to the resulting + * PointToPointChannel. */ static PointToPointChannel* AddPointToPointLink( - Node*, Node*, const DataRate&, const Time&); + Node* n1, Node* n2, const DataRate& rate, const Time& delay); - static bool AddIpv4Addresses( - const PointToPointChannel*, - Node*, const Ipv4Address&, - Node*, const Ipv4Address&); + /** + * \param chan PointToPointChannel to use + * \param n1 Node + * \param addr1 Ipv4 Address for n1 + * \param n2 Node + * \param addr2 Ipv4 Address for n2 + * + * Add Ipv4Addresses to the Ipv4 interfaces associated with the + * two PointToPointNetDevices on the provided PointToPointChannel + */ + static void AddIpv4Addresses( + const PointToPointChannel* chan, + Node* n1, const Ipv4Address& addr1, + Node* n2, const Ipv4Address& addr2); + + /** + * \param chan PointToPointChannel to use + * \param n1 Node + * \param n2 Node + * + * For the given PointToPointChannel, for each Node, add an + * IPv4 host route to the IPv4 address of the peer node. + */ + static void AddIpv4Routes (Node*, Node*, const PointToPointChannel*); /** * Get the connecting node n1 to node n2 diff --git a/src/internet-node/i-ipv4-impl.cc b/src/internet-node/i-ipv4-impl.cc index 82b5d0155..df612b2d1 100644 --- a/src/internet-node/i-ipv4-impl.cc +++ b/src/internet-node/i-ipv4-impl.cc @@ -20,6 +20,7 @@ */ #include "i-ipv4-impl.h" #include "ipv4.h" +#include "ipv4-interface.h" #include "ns3/assert.h" namespace ns3 { @@ -99,6 +100,11 @@ IIpv4Impl::GetNInterfaces (void) { return m_ipv4->GetNInterfaces (); } +NetDevice* +IIpv4Impl::PeekNetDevice (uint32_t i) +{ + return m_ipv4->GetInterface (i)-> PeekDevice(); +} void IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address) diff --git a/src/internet-node/i-ipv4-impl.h b/src/internet-node/i-ipv4-impl.h index b3240a089..52ca9869e 100644 --- a/src/internet-node/i-ipv4-impl.h +++ b/src/internet-node/i-ipv4-impl.h @@ -53,6 +53,7 @@ public: virtual void RemoveRoute (uint32_t i); virtual uint32_t AddInterface (NetDevice *device); virtual uint32_t GetNInterfaces (void); + virtual NetDevice* PeekNetDevice(uint32_t i); virtual void SetAddress (uint32_t i, Ipv4Address address); virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); diff --git a/src/node/i-ipv4.h b/src/node/i-ipv4.h index 11197de90..20ec3394f 100644 --- a/src/node/i-ipv4.h +++ b/src/node/i-ipv4.h @@ -122,6 +122,11 @@ public: */ virtual uint32_t GetNInterfaces (void) = 0; + /** + * Return address of the NetDevice associated with the Ipv4Interface + */ + virtual NetDevice* PeekNetDevice (uint32_t i) = 0; + virtual void SetAddress (uint32_t i, Ipv4Address address) = 0; virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0; virtual Ipv4Mask GetNetworkMask (uint32_t t) const = 0;