--- a/src/internet-stack/ipv4-l3-protocol.cc Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.cc Tue Apr 21 16:22:45 2009 +0400
@@ -53,7 +53,7 @@
Ipv4L3Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
- .SetParent<Object> ()
+ .SetParent<Ipv4> ()
.AddConstructor<Ipv4L3Protocol> ()
.AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
UintegerValue (64),
@@ -181,8 +181,8 @@
Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
interface->SetNode (m_node);
- interface->SetAddress (Ipv4Address::GetLoopback ());
- interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
+ Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
+ interface->AddAddress (ifaceAddr);
uint32_t index = AddIpv4Interface (interface);
AddHostRouteTo (Ipv4Address::GetLoopback (), index);
interface->SetUp ();
@@ -248,17 +248,17 @@
{
NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
- Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+ Lookup (Ipv4RoutingProtocol::INTERFACE_ANY, ipHeader, packet, routeReply);
}
void
Ipv4L3Protocol::Lookup (
- uint32_t ifIndex,
+ uint32_t interface,
Ipv4Header const &ipHeader,
Ptr<Packet> packet,
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
{
- NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+ NS_LOG_FUNCTION (this << interface << &ipHeader << packet << &routeReply);
for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
m_routingProtocols.begin ();
@@ -266,13 +266,13 @@
rprotoIter++)
{
NS_LOG_LOGIC ("Requesting route");
- if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet,
+ if ((*rprotoIter).second->RequestRoute (interface, ipHeader, packet,
routeReply))
return;
}
if (ipHeader.GetDestination ().IsMulticast () &&
- ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
+ interface == Ipv4RoutingProtocol::INTERFACE_ANY)
{
NS_LOG_LOGIC ("Multicast destination with local source");
//
@@ -304,7 +304,7 @@
void
Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
- int priority)
+ int16_t priority)
{
NS_LOG_FUNCTION (this << &routingProtocol << priority);
m_routingProtocols.push_back
@@ -319,11 +319,11 @@
return m_staticRouting->GetNRoutes ();
}
-Ipv4Route *
+Ipv4Route
Ipv4L3Protocol::GetRoute (uint32_t index)
{
NS_LOG_FUNCTION_NOARGS ();
- return m_staticRouting->GetRoute (index);
+ return *m_staticRouting->GetRoute (index);
}
void
@@ -360,11 +360,11 @@
return m_staticRouting->GetNMulticastRoutes ();
}
-Ipv4MulticastRoute *
+Ipv4MulticastRoute
Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
{
NS_LOG_FUNCTION (this << index);
- return m_staticRouting->GetMulticastRoute (index);
+ return *m_staticRouting->GetMulticastRoute (index);
}
void
@@ -438,14 +438,17 @@
{
NS_LOG_FUNCTION (this << addr);
- uint32_t ifIndex = 0;
+ uint32_t interface = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end ();
- i++, ifIndex++)
+ i++, interface++)
{
- if ((*i)->GetAddress () == addr)
+ for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
{
- return ifIndex;
+ if ((*i)->GetAddress (j).GetLocal () == addr)
+ {
+ return interface;
+ }
}
}
@@ -459,14 +462,17 @@
{
NS_LOG_FUNCTION (this << addr << mask);
- uint32_t ifIndex = 0;
+ uint32_t interface = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end ();
- i++, ifIndex++)
+ i++, interface++)
{
- if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
+ for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
{
- return ifIndex;
+ if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == addr.CombineMask (mask))
+ {
+ return interface;
+ }
}
}
@@ -476,18 +482,18 @@
}
int32_t
-Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
+Ipv4L3Protocol::FindInterfaceForDevice (Ptr<NetDevice> device) const
{
NS_LOG_FUNCTION (this << device);
- uint32_t ifIndex = 0;
+ uint32_t interface = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end ();
- i++, ifIndex++)
+ i++, interface++)
{
if ((*i)->GetDevice () == device)
{
- return ifIndex;
+ return interface;
}
}
@@ -647,11 +653,15 @@
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
{
Ptr<Ipv4Interface> outInterface = *ifaceIter;
- if (destination.IsSubnetDirectedBroadcast (
- outInterface->GetNetworkMask ()))
- {
- ipHeader.SetTtl (1);
- }
+ // XXX this logic might not be completely correct for multi-addressed interface
+ for (uint32_t j = 0; j < outInterface->GetNAddresses(); j++)
+ {
+ if (destination.IsSubnetDirectedBroadcast (
+ outInterface->GetAddress (j).GetMask ()))
+ {
+ ipHeader.SetTtl (1);
+ }
+ }
}
}
if (destination.IsBroadcast ())
@@ -664,9 +674,10 @@
Ptr<Packet> packetCopy = packet->Copy ();
packetCopy->AddHeader (ipHeader);
+ // XXX Handle multiple address on interface
if (packetCopy->GetSize () > outInterface->GetMtu () &&
ipHeader.IsDontFragment () &&
- IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+ IsUnicast (ipHeader.GetDestination (), outInterface->GetAddress (0).GetMask ()))
{
Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
NS_ASSERT (icmp != 0);
@@ -728,9 +739,10 @@
NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
+ // XXX handle multiple address on interface
if (packet->GetSize () > outInterface->GetMtu () &&
ipHeader.IsDontFragment () &&
- IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+ IsUnicast (ipHeader.GetDestination (), outInterface->GetAddress (0).GetMask ()))
{
NS_LOG_LOGIC ("Too big: need fragmentation but not allowed");
Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
@@ -782,21 +794,24 @@
bool
Ipv4L3Protocol::Forwarding (
- uint32_t ifIndex,
+ uint32_t interface,
Ptr<Packet> packet,
Ipv4Header &ipHeader,
Ptr<NetDevice> device)
{
- NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
+ NS_LOG_FUNCTION (interface << packet << &ipHeader<< device);
NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end (); i++)
{
- if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ()))
+ for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
{
- NS_LOG_LOGIC ("For me (destination match)");
- return false;
+ if ((*i)->GetAddress (j).GetLocal ().IsEqual (ipHeader.GetDestination ()))
+ {
+ NS_LOG_LOGIC ("For me (destination match)");
+ return false;
+ }
}
}
@@ -806,7 +821,8 @@
Ptr<Ipv4Interface> interface = *i;
if (interface->GetDevice () == device)
{
- if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
+ // XXX multi-address case
+ if (ipHeader.GetDestination ().IsEqual (interface->GetAddress (0).GetBroadcast ()))
{
NS_LOG_LOGIC ("For me (interface broadcast address)");
return false;
@@ -840,26 +856,27 @@
// We forward with a packet copy, since forwarding may change
// the packet, affecting our local delivery
NS_LOG_LOGIC ("Forwarding (multicast).");
- DoForward (ifIndex, packet->Copy (), ipHeader);
+ DoForward (interface, packet->Copy (), ipHeader);
return false;
}
}
- DoForward (ifIndex, packet, ipHeader);
+ DoForward (interface, packet, ipHeader);
return true;
}
void
-Ipv4L3Protocol::DoForward (uint32_t ifIndex,
+Ipv4L3Protocol::DoForward (uint32_t interface,
Ptr<Packet> packet,
Ipv4Header ipHeader)
{
- NS_LOG_FUNCTION (this << ifIndex << packet << ipHeader);
+ NS_LOG_FUNCTION (this << interface << packet << ipHeader);
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+ // XXX handle multi-interfaces
if (ipHeader.GetTtl () == 0)
{
- if (IsUnicast (ipHeader.GetDestination (), GetInterface (ifIndex)->GetNetworkMask ()))
+ if (IsUnicast (ipHeader.GetDestination (), GetInterface (interface)->GetAddress (0).GetMask ()))
{
Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
icmp->SendTimeExceededTtl (ipHeader, packet);
@@ -869,7 +886,7 @@
return;
}
NS_LOG_LOGIC ("Not for me, forwarding.");
- Lookup (ifIndex, ipHeader, packet,
+ Lookup (interface, ipHeader, packet,
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
}
@@ -894,7 +911,8 @@
case Ipv4L4Protocol::RX_CSUM_FAILED:
break;
case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
- if (IsUnicast (ip.GetDestination (), incomingInterface->GetNetworkMask ()))
+ // XXX handle multi-interface case
+ if (IsUnicast (ip.GetDestination (), incomingInterface->GetAddress (0).GetMask ()))
{
GetIcmp ()->SendDestUnreachPort (ip, copy);
}
@@ -928,36 +946,28 @@
}
}
-void
-Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
+uint32_t
+Ipv4L3Protocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
{
NS_LOG_FUNCTION (this << i << address);
Ptr<Ipv4Interface> interface = GetInterface (i);
- interface->SetAddress (address);
-}
-
-void
-Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
- NS_LOG_FUNCTION (this << i << mask);
- Ptr<Ipv4Interface> interface = GetInterface (i);
- interface->SetNetworkMask (mask);
+ return interface->AddAddress (address);
}
-Ipv4Mask
-Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
+Ipv4InterfaceAddress
+Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
{
- NS_LOG_FUNCTION (this << i);
- Ptr<Ipv4Interface> interface = GetInterface (i);
- return interface->GetNetworkMask ();
+ NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
+ Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
+ return interface->GetAddress (addressIndex);
}
-Ipv4Address
-Ipv4L3Protocol::GetAddress (uint32_t i) const
+uint32_t
+Ipv4L3Protocol::GetNAddresses (uint32_t interface) const
{
- NS_LOG_FUNCTION (this << i);
- Ptr<Ipv4Interface> interface = GetInterface (i);
- return interface->GetAddress ();
+ NS_LOG_FUNCTION (this << interface);
+ Ptr<Ipv4Interface> iface = GetInterface (interface);
+ return iface->GetNAddresses ();
}
void
@@ -977,10 +987,10 @@
}
bool
-Ipv4L3Protocol::GetIfIndexForDestination (
- Ipv4Address destination, uint32_t& ifIndex) const
+Ipv4L3Protocol::GetInterfaceForDestination (
+ Ipv4Address destination, uint32_t& interface) const
{
- NS_LOG_FUNCTION (this << destination << &ifIndex);
+ NS_LOG_FUNCTION (this << destination << &interface);
//
// The first thing we do in trying to determine a source address is to
// consult the routing protocols. These will also check for a default route
@@ -991,12 +1001,12 @@
i++)
{
NS_LOG_LOGIC ("Requesting Source Address");
- uint32_t ifIndexTmp;
+ uint32_t interfaceTmp;
- if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
+ if ((*i).second->RequestInterface (destination, interfaceTmp))
{
- NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
- ifIndex = ifIndexTmp;
+ NS_LOG_LOGIC ("Found interface " << interfaceTmp);
+ interface = interfaceTmp;
return true;
}
}
@@ -1012,7 +1022,7 @@
if (GetNInterfaces () == 2)
{
NS_LOG_LOGIC ("One Interface. Using interface 1.");
- ifIndex = 1;
+ interface = 1;
return true;
}
//
@@ -1035,14 +1045,14 @@
if (route == NULL)
{
- NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
+ NS_LOG_LOGIC ("Ipv4L3Protocol::GetInterfaceForDestination (): "
"Unable to determine outbound interface. No default route set");
return false;
}
- ifIndex = route->GetInterface ();
+ interface = route->GetInterface ();
- NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
+ NS_LOG_LOGIC ("Default route specifies interface " << interface);
return true;
}
@@ -1072,11 +1082,13 @@
// If interface address and network mask have been set, add a route
// to the network of the interface (like e.g. ifconfig does on a
// Linux box)
- if (((interface->GetAddress ()) != (Ipv4Address ()))
- && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
+ for (uint32_t j = 0; j < interface->GetNAddresses (); j++)
{
- AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
- interface->GetNetworkMask (), i);
+ if (((interface->GetAddress (j).GetLocal ()) != (Ipv4Address ()))
+ && (interface->GetAddress (j).GetMask ()) != (Ipv4Mask ()))
+ {
+ AddNetworkRouteTo (interface->GetAddress (j).GetLocal ().CombineMask (interface->GetAddress (j).GetMask ()), interface->GetAddress (j).GetMask (), i);
+ }
}
}
@@ -1094,8 +1106,8 @@
modified = false;
for (uint32_t i = 0; i < GetNRoutes (); i++)
{
- Ipv4Route *route = GetRoute (i);
- if (route->GetInterface () == ifaceIndex)
+ Ipv4Route route = GetRoute (i);
+ if (route.GetInterface () == ifaceIndex)
{
RemoveRoute (i);
modified = true;
@@ -1105,4 +1117,43 @@
}
}
+// Note: This method will be removed in Ipv4 routing work
+Ipv4Address
+Ipv4L3Protocol::GetSourceAddress (Ipv4Address destination) const
+{
+ uint32_t interface = 0xffffffff;
+
+ bool result = GetInterfaceForDestination (destination, interface);
+
+ if (result)
+ {
+ // if multiple addresses exist, search for the first one on the same subnet
+ for (uint32_t i = 0; i < GetNAddresses (interface); i++)
+ {
+ Ipv4InterfaceAddress ipv4InAddr = GetAddress (interface, i);
+ if (ipv4InAddr.GetLocal().CombineMask(ipv4InAddr.GetMask ()) == destination.CombineMask (ipv4InAddr.GetMask ()))
+ {
+ return ipv4InAddr.GetLocal ();
+ }
+ }
+ // Destination is off-link, so return first address.
+ return GetAddress (interface, 0).GetLocal ();
+ }
+ else
+ {
+//
+// If we can't find any address, just leave it 0.0.0.0
+//
+ return Ipv4Address::GetAny ();
+ }
+}
+
+Ptr<NetDevice>
+Ipv4L3Protocol::GetNetDevice (uint32_t i)
+{
+ return GetInterface (i)-> GetDevice ();
+}
+
+
+
}//namespace ns3