Support dynamic routing and multiple routing protocols; static routing table is refactored as a "routing protocol".
Support sending IP broadcast (255.255.255.255) packets (bug #36).
This commit is contained in:
@@ -39,6 +39,13 @@ Ipv4Impl::DoDispose (void)
|
||||
m_ipv4 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority)
|
||||
{
|
||||
m_ipv4->AddRoutingProtocol (routingProtocol, priority);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
|
||||
@@ -35,6 +35,9 @@ public:
|
||||
|
||||
virtual ~Ipv4Impl ();
|
||||
|
||||
virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority);
|
||||
|
||||
virtual void AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
|
||||
@@ -48,9 +48,10 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
|
||||
m_nInterfaces (0),
|
||||
m_defaultTtl (64),
|
||||
m_identification (0),
|
||||
m_defaultRoute (0),
|
||||
m_node (node)
|
||||
{
|
||||
m_staticRouting = Create<Ipv4StaticRouting> ();
|
||||
AddRoutingProtocol (m_staticRouting, 0);
|
||||
SetupLoopback ();
|
||||
}
|
||||
Ipv4L3Protocol::~Ipv4L3Protocol ()
|
||||
@@ -64,25 +65,10 @@ Ipv4L3Protocol::DoDispose (void)
|
||||
delete (*i);
|
||||
}
|
||||
m_interfaces.clear ();
|
||||
for (HostRoutesI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i = m_hostRoutes.erase (i))
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j = m_networkRoutes.erase (j))
|
||||
{
|
||||
delete (*j);
|
||||
}
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
m_node = 0;
|
||||
L3Protocol::DoDispose ();
|
||||
m_staticRouting->Dispose ();
|
||||
m_staticRouting = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -132,17 +118,13 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
|
||||
}
|
||||
void
|
||||
Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
m_staticRouting->AddHostRouteTo (dest, interface);
|
||||
}
|
||||
void
|
||||
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
||||
@@ -150,163 +132,63 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateNetworkRouteTo (network,
|
||||
networkMask,
|
||||
nextHop,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
|
||||
}
|
||||
void
|
||||
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateNetworkRouteTo (network,
|
||||
networkMask,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
|
||||
}
|
||||
void
|
||||
Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = route;
|
||||
m_staticRouting->SetDefaultRoute (nextHop, interface);
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4L3Protocol::Lookup (Ipv4Address dest)
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
||||
{
|
||||
for (HostRoutesCI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
|
||||
rprotoIter != m_routingProtocols.end (); rprotoIter++)
|
||||
{
|
||||
NS_ASSERT ((*i)->IsHost ());
|
||||
if ((*i)->GetDest ().IsEqual (dest))
|
||||
{
|
||||
return (*i);
|
||||
}
|
||||
if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
|
||||
return;
|
||||
}
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
NS_ASSERT ((*j)->IsNetwork ());
|
||||
Ipv4Mask mask = (*j)->GetDestNetworkMask ();
|
||||
Ipv4Address entry = (*j)->GetDestNetwork ();
|
||||
if (mask.IsMatch (dest, entry))
|
||||
{
|
||||
return (*j);
|
||||
}
|
||||
}
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
NS_ASSERT (m_defaultRoute->IsDefault ());
|
||||
return m_defaultRoute;
|
||||
}
|
||||
return 0;
|
||||
// No route found
|
||||
routeReply (false, Ipv4Route (), packet, ipHeader);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority)
|
||||
{
|
||||
m_routingProtocols.push_back
|
||||
(std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
|
||||
m_routingProtocols.sort ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::GetNRoutes (void)
|
||||
{
|
||||
uint32_t n = 0;
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
n += m_hostRoutes.size ();
|
||||
n += m_networkRoutes.size ();
|
||||
return n;
|
||||
return m_staticRouting->GetNRoutes ();
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4L3Protocol::GetRoute (uint32_t index)
|
||||
{
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
return m_defaultRoute;
|
||||
}
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesCI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
index -= m_hostRoutes.size ();
|
||||
uint32_t tmp = 0;
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *j;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
// quiet compiler.
|
||||
return 0;
|
||||
return m_staticRouting->GetRoute (index);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::RemoveRoute (uint32_t index)
|
||||
{
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *i;
|
||||
m_hostRoutes.erase (i);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
index -= m_hostRoutes.size ();
|
||||
uint32_t tmp = 0;
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *j;
|
||||
m_networkRoutes.erase (j);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
m_staticRouting->RemoveRoute (index);
|
||||
}
|
||||
|
||||
|
||||
@@ -386,6 +268,7 @@ Ipv4L3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
|
||||
ForwardUp (packet, ipHeader);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::Send (Packet const &packet,
|
||||
Ipv4Address source,
|
||||
@@ -404,30 +287,49 @@ Ipv4L3Protocol::Send (Packet const &packet,
|
||||
|
||||
m_identification ++;
|
||||
|
||||
// XXX Note here that in most ipv4 stacks in the world,
|
||||
// the route calculation for an outgoing packet is not
|
||||
// done in the ip layer. It is done within the application
|
||||
// socket when the first packet is sent to avoid this
|
||||
// costly lookup on a per-packet basis.
|
||||
// That would require us to get the route from the packet,
|
||||
// most likely with a packet tag. The higher layers do not
|
||||
// do this yet for us.
|
||||
Ipv4Route *route = Lookup (ipHeader.GetDestination ());
|
||||
if (route == 0)
|
||||
if (destination.IsBroadcast ())
|
||||
{
|
||||
NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
|
||||
m_dropTrace (packet);
|
||||
return;
|
||||
}
|
||||
uint32_t ifaceIndex = 0;
|
||||
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
|
||||
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
|
||||
{
|
||||
Ipv4Interface *outInterface = *ifaceIter;
|
||||
Packet packetCopy = packet;
|
||||
|
||||
SendRealOut (packet, ipHeader, *route);
|
||||
NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
|
||||
packetCopy.AddHeader (ipHeader);
|
||||
m_txTrace (packetCopy, ifaceIndex);
|
||||
outInterface->Send (packetCopy, destination);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX Note here that in most ipv4 stacks in the world,
|
||||
// the route calculation for an outgoing packet is not
|
||||
// done in the ip layer. It is done within the application
|
||||
// socket when the first packet is sent to avoid this
|
||||
// costly lookup on a per-packet basis.
|
||||
// That would require us to get the route from the packet,
|
||||
// most likely with a packet tag. The higher layers do not
|
||||
// do this yet for us.
|
||||
Lookup (ipHeader, packet,
|
||||
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
|
||||
Ipv4L3Protocol::SendRealOut (bool found,
|
||||
Ipv4Route const &route,
|
||||
Packet packet,
|
||||
Ipv4Header const &ipHeader)
|
||||
{
|
||||
Packet packet = p;
|
||||
packet.AddHeader (ip);
|
||||
if (!found)
|
||||
{
|
||||
NS_DEBUG ("no route to host. drop.");
|
||||
m_dropTrace (packet);
|
||||
return;
|
||||
}
|
||||
packet.AddHeader (ipHeader);
|
||||
Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
|
||||
NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
|
||||
m_txTrace (packet, route.GetInterface ());
|
||||
@@ -437,7 +339,7 @@ Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route co
|
||||
}
|
||||
else
|
||||
{
|
||||
outInterface->Send (packet, ip.GetDestination ());
|
||||
outInterface->Send (packet, ipHeader.GetDestination ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +372,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetD
|
||||
}
|
||||
}
|
||||
|
||||
if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ()))
|
||||
if (ipHeader.GetDestination ().IsBroadcast ())
|
||||
{
|
||||
NS_DEBUG ("for me 3");
|
||||
return false;
|
||||
@@ -489,15 +391,10 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetD
|
||||
return true;
|
||||
}
|
||||
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
|
||||
Ipv4Route *route = Lookup (ipHeader.GetDestination ());
|
||||
if (route == 0)
|
||||
{
|
||||
NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
|
||||
m_dropTrace (packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_DEBUG ("not for me -- forwarding.");
|
||||
SendRealOut (packet, ipHeader, *route);
|
||||
Lookup (ipHeader, packet,
|
||||
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@
|
||||
#include "ns3/callback-trace-source.h"
|
||||
#include "ns3/array-trace-resolver.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ipv4-header.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "l3-protocol.h"
|
||||
#include "ipv4-static-routing.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -124,7 +127,10 @@ public:
|
||||
void SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
|
||||
Ipv4Route *Lookup (Ipv4Address dest);
|
||||
void Lookup (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply);
|
||||
|
||||
uint32_t GetNRoutes (void);
|
||||
Ipv4Route *GetRoute (uint32_t i);
|
||||
void RemoveRoute (uint32_t i);
|
||||
@@ -143,11 +149,19 @@ public:
|
||||
void SetUp (uint32_t i);
|
||||
void SetDown (uint32_t i);
|
||||
|
||||
void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
|
||||
|
||||
void SendRealOut (bool found,
|
||||
Ipv4Route const &route,
|
||||
Packet packet,
|
||||
Ipv4Header const &ipHeader);
|
||||
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
|
||||
void ForwardUp (Packet p, Ipv4Header const&ip);
|
||||
uint32_t AddIpv4Interface (Ipv4Interface *interface);
|
||||
@@ -155,26 +169,22 @@ private:
|
||||
TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
|
||||
|
||||
typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
|
||||
typedef std::list<Ipv4Route *> HostRoutes;
|
||||
typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
|
||||
typedef std::list<Ipv4Route *>::iterator HostRoutesI;
|
||||
typedef std::list<Ipv4Route *> NetworkRoutes;
|
||||
typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
|
||||
typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
|
||||
typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
|
||||
|
||||
Ipv4InterfaceList m_interfaces;
|
||||
uint32_t m_nInterfaces;
|
||||
uint8_t m_defaultTtl;
|
||||
uint16_t m_identification;
|
||||
HostRoutes m_hostRoutes;
|
||||
NetworkRoutes m_networkRoutes;
|
||||
Ipv4Route *m_defaultRoute;
|
||||
Ptr<Node> m_node;
|
||||
CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
|
||||
CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
|
||||
CallbackTraceSource<Packet const &> m_dropTrace;
|
||||
|
||||
Ipv4RoutingProtocolList m_routingProtocols;
|
||||
|
||||
Ptr<Ipv4StaticRouting> m_staticRouting;
|
||||
};
|
||||
|
||||
} // Namespace ns3
|
||||
|
||||
#endif /* IPV$_L3_PROTOCOL_H */
|
||||
#endif /* IPV4_L3_PROTOCOL_H */
|
||||
|
||||
253
src/internet-node/ipv4-static-routing.cc
Normal file
253
src/internet-node/ipv4-static-routing.cc
Normal file
@@ -0,0 +1,253 @@
|
||||
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// 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: George F. Riley<riley@ece.gatech.edu>
|
||||
// Gustavo Carneiro <gjc@inescporto.pt>
|
||||
|
||||
#include "ipv4-static-routing.h"
|
||||
#include "ns3/packet.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
}
|
||||
void
|
||||
Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
}
|
||||
void
|
||||
Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateNetworkRouteTo (network,
|
||||
networkMask,
|
||||
nextHop,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
}
|
||||
void
|
||||
Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateNetworkRouteTo (network,
|
||||
networkMask,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
}
|
||||
void
|
||||
Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = route;
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
|
||||
{
|
||||
for (HostRoutesCI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
NS_ASSERT ((*i)->IsHost ());
|
||||
if ((*i)->GetDest ().IsEqual (dest))
|
||||
{
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
NS_ASSERT ((*j)->IsNetwork ());
|
||||
Ipv4Mask mask = (*j)->GetDestNetworkMask ();
|
||||
Ipv4Address entry = (*j)->GetDestNetwork ();
|
||||
if (mask.IsMatch (dest, entry))
|
||||
{
|
||||
return (*j);
|
||||
}
|
||||
}
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
NS_ASSERT (m_defaultRoute->IsDefault ());
|
||||
return m_defaultRoute;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4StaticRouting::GetNRoutes (void)
|
||||
{
|
||||
uint32_t n = 0;
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
n += m_hostRoutes.size ();
|
||||
n += m_networkRoutes.size ();
|
||||
return n;
|
||||
}
|
||||
Ipv4Route *
|
||||
Ipv4StaticRouting::GetRoute (uint32_t index)
|
||||
{
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
return m_defaultRoute;
|
||||
}
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesCI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
index -= m_hostRoutes.size ();
|
||||
uint32_t tmp = 0;
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *j;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
// quiet compiler.
|
||||
return 0;
|
||||
}
|
||||
void
|
||||
Ipv4StaticRouting::RemoveRoute (uint32_t index)
|
||||
{
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *i;
|
||||
m_hostRoutes.erase (i);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
index -= m_hostRoutes.size ();
|
||||
uint32_t tmp = 0;
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *j;
|
||||
m_networkRoutes.erase (j);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply)
|
||||
{
|
||||
Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
|
||||
if (route != 0)
|
||||
{
|
||||
routeReply (true, *route, packet, ipHeader);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // Let other routing protocols try to handle this
|
||||
// route request.
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::DoDispose (void)
|
||||
{
|
||||
for (HostRoutesI i = m_hostRoutes.begin ();
|
||||
i != m_hostRoutes.end ();
|
||||
i = m_hostRoutes.erase (i))
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin ();
|
||||
j != m_networkRoutes.end ();
|
||||
j = m_networkRoutes.erase (j))
|
||||
{
|
||||
delete (*j);
|
||||
}
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
Ipv4RoutingProtocol::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
}//namespace ns3
|
||||
101
src/internet-node/ipv4-static-routing.h
Normal file
101
src/internet-node/ipv4-static-routing.h
Normal file
@@ -0,0 +1,101 @@
|
||||
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// 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: George F. Riley<riley@ece.gatech.edu>
|
||||
// Gustavo Carneiro <gjc@inescporto.pt>
|
||||
//
|
||||
|
||||
#ifndef IPV4_STATIC_ROUTING_H
|
||||
#define IPV4_STATIC_ROUTING_H
|
||||
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
#include "ns3/callback-trace-source.h"
|
||||
#include "ns3/array-trace-resolver.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ipv4-header.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "l3-protocol.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Packet;
|
||||
class NetDevice;
|
||||
class Ipv4Interface;
|
||||
class Ipv4Address;
|
||||
class Ipv4Header;
|
||||
class Ipv4Route;
|
||||
class Node;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
|
||||
class Ipv4StaticRouting : public Ipv4RoutingProtocol
|
||||
{
|
||||
|
||||
public:
|
||||
Ipv4StaticRouting () : m_defaultRoute (0) {}
|
||||
|
||||
virtual bool RequestRoute (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply);
|
||||
|
||||
|
||||
void AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
void AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface);
|
||||
|
||||
void AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
void AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
uint32_t interface);
|
||||
void SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
uint32_t GetNRoutes (void);
|
||||
Ipv4Route *GetRoute (uint32_t i);
|
||||
void RemoveRoute (uint32_t i);
|
||||
|
||||
protected:
|
||||
void DoDispose (void);
|
||||
|
||||
private:
|
||||
typedef std::list<Ipv4Route *> HostRoutes;
|
||||
typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
|
||||
typedef std::list<Ipv4Route *>::iterator HostRoutesI;
|
||||
typedef std::list<Ipv4Route *> NetworkRoutes;
|
||||
typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
|
||||
typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
|
||||
|
||||
Ipv4Route *LookupStatic (Ipv4Address dest);
|
||||
|
||||
HostRoutes m_hostRoutes;
|
||||
NetworkRoutes m_networkRoutes;
|
||||
Ipv4Route *m_defaultRoute;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // Namespace ns3
|
||||
|
||||
#endif /* IPV4_STATIC_ROUTING_H */
|
||||
@@ -17,6 +17,7 @@ def build(bld):
|
||||
'ipv4-checksum.cc',
|
||||
'ipv4-interface.cc',
|
||||
'ipv4-l3-protocol.cc',
|
||||
'ipv4-static-routing.cc',
|
||||
'ipv4-end-point.cc',
|
||||
'udp-l4-protocol.cc',
|
||||
'arp-header.cc',
|
||||
@@ -40,4 +41,5 @@ def build(bld):
|
||||
'internet-node.h',
|
||||
'ascii-trace.h',
|
||||
'pcap-trace.h',
|
||||
'ipv4-header.h',
|
||||
]
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdint.h>
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ipv4-route.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -31,6 +32,30 @@ namespace ns3 {
|
||||
class NetDevice;
|
||||
class Packet;
|
||||
class Ipv4Route;
|
||||
class Ipv4Header; // FIXME: ipv4-header.h needs to move from module
|
||||
// "internet-node" to module "node"
|
||||
|
||||
class Ipv4RoutingProtocol : public Object
|
||||
{
|
||||
public:
|
||||
// void (*RouteReply) (bool found, Ipv4Route route, Packet packet, Ipv4Header const &ipHeader);
|
||||
typedef Callback<void, bool, Ipv4Route const&, Packet, Ipv4Header const &> RouteReplyCallback;
|
||||
|
||||
/**
|
||||
* \brief Asynchronously requests a route for a given packet and IP header
|
||||
*
|
||||
* \param ipHeader IP header of the packet
|
||||
* \param packet packet that is being sent or forwarded
|
||||
* \param routeReply callback that will receive the route reply
|
||||
*
|
||||
* \returns true if the routing protocol should be able to get the
|
||||
* route, false otherwise.
|
||||
*/
|
||||
virtual bool RequestRoute (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces
|
||||
*
|
||||
@@ -47,7 +72,10 @@ public:
|
||||
static const InterfaceId iid;
|
||||
Ipv4 ();
|
||||
virtual ~Ipv4 ();
|
||||
|
||||
|
||||
virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority) = 0;
|
||||
|
||||
/**
|
||||
* \param dest destination address
|
||||
* \param nextHop address of next hop.
|
||||
|
||||
Reference in New Issue
Block a user