more multicast plumbing

This commit is contained in:
Craig Dowell
2007-08-13 12:08:01 -07:00
parent dfae0be7d0
commit e567af9b24
11 changed files with 177 additions and 97 deletions

View File

@@ -65,7 +65,7 @@ main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
#if 0
#if 0
DebugComponentEnable("Me");
DebugComponentEnable("Object");
DebugComponentEnable("Queue");
@@ -87,16 +87,9 @@ main (int argc, char *argv[])
#endif
DebugComponentEnable("Me");
DebugComponentEnable("OnOffApplication");
DebugComponentEnable("UdpSocket");
DebugComponentEnable("UdpL4Protocol");
DebugComponentEnable("Ipv4L3Protocol");
DebugComponentEnable("Ipv4StaticRouting");
DebugComponentEnable("CsmaNetDevice");
DebugComponentEnable("CsmaChannel");
DebugComponentEnable("Ipv4Interface");
DebugComponentEnable("ArpIpv4Interface");
DebugComponentEnable("Ipv4LoopbackInterface");
DebugComponentEnable("CsmaNetDevice");
DebugComponentEnable("UdpL4Protocol");
// Set up some default values for the simulation. Use the Bind()
// technique to tell the system what subclass of Queue to use,
@@ -125,29 +118,47 @@ main (int argc, char *argv[])
DataRate(5000000), MilliSeconds(2));
NS_DEBUG("Build Topology.");
uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
Eui48Address("10:54:23:54:23:50"));
uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
Eui48Address("10:54:23:54:23:51"));
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
Eui48Address("10:54:23:54:23:52"));
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
Eui48Address("10:54:23:54:23:53"));
uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0,
channel0, Eui48Address("10:54:23:54:23:50"));
uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1,
channel0, Eui48Address("10:54:23:54:23:51"));
uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2,
channel0, Eui48Address("10:54:23:54:23:52"));
uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3,
channel0, Eui48Address("10:54:23:54:23:53"));
NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0);
NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1);
NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2);
NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3);
// Later, we add IP addresses.
NS_DEBUG("Assign IP Addresses.");
// XXX BUGBUG
// Need a better way to get the interface index. The point-to-point topology
// as implemented can't return the index since it creates interfaces on both
// sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on
// Ipv4 to find the interface index corresponding to a given ipv4 address.
uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0,
netDeviceNumberNode0, Ipv4Address ("10.1.1.1"),
Ipv4Mask ("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1,
netDeviceNumberNode1, Ipv4Address ("10.1.1.2"),
Ipv4Mask ("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2,
netDeviceNumberNode2, Ipv4Address ("10.1.1.3"),
Ipv4Mask ("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3,
netDeviceNumberNode3, Ipv4Address ("10.1.1.4"),
Ipv4Mask ("255.255.255.0"));
NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0);
NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1);
NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2);
NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3);
// Configure multicasting
NS_DEBUG("Configure multicasting.");
@@ -158,22 +169,21 @@ main (int argc, char *argv[])
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
std::vector<uint32_t> outputInterfaces (1);
outputInterfaces[0] = n0ifIndex;
outputInterfaces[0] = ifIndexNode0;
ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0,
outputInterfaces);
ipv4 = n1->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
// ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
// ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
// ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
// Create the OnOff application to send UDP datagrams
// from n0 to the multicast group
NS_DEBUG("Create Applications.");
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
@@ -181,10 +191,12 @@ main (int argc, char *argv[])
InetSocketAddress (multicastGroup, 80),
"Udp",
ConstantVariable(1),
ConstantVariable(0));
ConstantVariable(0),
DataRate ("128b/s"),
128);
// Start the application
ooff->Start(Seconds(1.0));
ooff->Stop (Seconds(10.0));
ooff->Start(Seconds(1.));
ooff->Stop (Seconds(10.));
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the csma-one-subnet.tr file

View File

@@ -199,9 +199,12 @@ void OnOffApplication::ScheduleNextTx()
if (m_totBytes < m_maxBytes)
{
uint32_t bits = m_pktSize * 8 - m_residualBits;
NS_DEBUG("OnOffApplication::ScheduleNextTx (): bits = " << bits);
Time nextTime(Seconds (bits /
static_cast<double>(m_cbrRate.GetBitRate()))); // Time till next packet
m_sendEvent = Simulator::Schedule(nextTime, &OnOffApplication::SendPacket, this);
NS_DEBUG("OnOffApplication::ScheduleNextTx (): nextTime = " << nextTime);
m_sendEvent = Simulator::Schedule(nextTime,
&OnOffApplication::SendPacket, this);
}
else
{ // All done, cancel any pending events
@@ -214,6 +217,8 @@ void OnOffApplication::ScheduleStartEvent()
NS_DEBUG("OnOffApplication::ScheduleStartEvent ()");
Time offInterval = Seconds(m_offTime->GetValue());
NS_DEBUG("OnOffApplication::ScheduleStartEvent (): "
"start at " << offInterval);
m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this);
}

View File

@@ -91,24 +91,22 @@ CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr<Node> n1,
nd1->Attach (ch);
}
void
CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
int ndNum,
const Ipv4Address& addr1,
const Ipv4Mask& netmask1)
uint32_t
CsmaIpv4Topology::AddIpv4Address(
Ptr<Node> node,
uint32_t netDeviceNumber,
const Ipv4Address address,
const Ipv4Mask mask)
{
// Duplex link is assumed to be subnetted as a /30
// May run this unnumbered in the future?
Ipv4Mask netmask(netmask1);
Ptr<NetDevice> nd = node->GetDevice(netDeviceNumber);
Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
uint32_t ifIndex = ipv4->AddInterface (nd);
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
uint32_t index1 = ip1->AddInterface (nd1);
ip1->SetAddress (index1, addr1);
ip1->SetNetworkMask (index1, netmask);
ip1->SetUp (index1);
ipv4->SetAddress (ifIndex, address);
ipv4->SetNetworkMask (ifIndex, mask);
ipv4->SetUp (ifIndex);
return ifIndex;
}
void

View File

@@ -94,18 +94,23 @@ public:
/**
* \param n1 Node
* \param ndNum NetDevice number with which to associate address
* \param addr1 Ipv4 Address for ndNum of n1
* \param network network mask for ndNum of node n1
* \brief Create an Ipv4 interface for a net device and assign an
* Ipv4Address to that interface.
*
* \param node The node to which to add the new address and corresponding
* interface.
* \param netDeviceNumber The NetDevice index number with which to associate
* the address.
* \param address The Ipv4 Address for the interface.
* \param network The network mask for the interface
*
* Add an Ipv4Address to the Ipv4 interface associated with the
* ndNum CsmaIpv4NetDevices on the provided
* CsmaIpv4Channel
* ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel
*/
static void AddIpv4Address(Ptr<Node> n1, int ndNum,
const Ipv4Address& addr1,
const Ipv4Mask& netmask1);
static uint32_t AddIpv4Address(Ptr<Node> node,
uint32_t netDeviceNumber,
const Ipv4Address address,
const Ipv4Mask mask);
/**
* \param nd1 Node

View File

@@ -81,6 +81,14 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
hardwareDestination = GetDevice ()->GetBroadcast ();
found = true;
}
else if (dest.IsMulticast ())
{
NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast");
// XXX BUGBUG
// Need real multicast addresses
hardwareDestination = GetDevice ()->GetBroadcast ();
found = true;
}
else
{
NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup");

View File

@@ -246,12 +246,26 @@ Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
}
void
Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
Packet packet,
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
Ipv4L3Protocol::Lookup (
Ipv4Header const &ipHeader,
Packet packet,
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
{
NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet <<
&routeReply << ")");
NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader <<
", " << &packet << &routeReply << ")");
Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
}
void
Ipv4L3Protocol::Lookup (
uint32_t ifIndex,
Ipv4Header const &ipHeader,
Packet packet,
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
{
NS_DEBUG("Ipv4L3Protocol::Lookup (" << ifIndex << ", " << &ipHeader <<
", " << &packet << &routeReply << ")");
for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
m_routingProtocols.begin ();
@@ -259,7 +273,8 @@ Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
rprotoIter++)
{
NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route");
if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet,
routeReply))
return;
}
@@ -405,7 +420,9 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protoc
protocol << ", " << from << ")");
uint32_t index = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end ();
i++)
{
if ((*i)->GetDevice () == device)
{
@@ -423,7 +440,7 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protoc
return;
}
if (Forwarding (packet, ipHeader, device))
if (Forwarding (index, packet, ipHeader, device))
{
return;
}
@@ -521,10 +538,14 @@ Ipv4L3Protocol::SendRealOut (bool found,
}
bool
Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
Ipv4L3Protocol::Forwarding (
uint32_t ifIndex,
Packet const &packet,
Ipv4Header &ipHeader,
Ptr<NetDevice> device)
{
NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader <<
", " << device << ")");
NS_DEBUG("Ipv4L3Protocol::Forwarding (" << ifIndex << ", " << &packet <<
", " << &ipHeader << ", " << device << ")");
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
i != m_interfaces.end (); i++)
@@ -579,7 +600,7 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetD
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
NS_DEBUG("Ipv4L3Protocol::Forwarding (): Forwarding packet.");
Lookup (ipHeader, packet,
Lookup (ifIndex, ipHeader, packet,
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
//
// If this is a to a multicast address and this node is a member of the

View File

@@ -195,12 +195,19 @@ protected:
virtual void DoDispose (void);
private:
void Lookup (uint32_t ifIndex,
Ipv4Header const &ipHeader,
Packet packet,
Ipv4RoutingProtocol::RouteReplyCallback routeReply);
void SendRealOut (bool found,
Ipv4Route const &route,
Packet packet,
Ipv4Header const &ipHeader);
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
bool Forwarding (uint32_t ifIndex,
Packet const &packet,
Ipv4Header &ipHeader,
Ptr<NetDevice> device);
void ForwardUp (Packet p, Ipv4Header const&ip);
uint32_t AddIpv4Interface (Ipv4Interface *interface);
void SetupLoopback (void);

View File

@@ -196,7 +196,8 @@ Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
Ipv4MulticastRoute *
Ipv4StaticRouting::LookupStatic (
Ipv4Address origin,
Ipv4Address group)
Ipv4Address group,
uint32_t ifIndex)
{
for (MulticastRoutesI i = m_multicastRoutes.begin ();
i != m_multicastRoutes.end ();
@@ -207,7 +208,11 @@ Ipv4StaticRouting::LookupStatic (
origin == Ipv4Address::GetAny ()) &&
group == route->GetGroup ())
{
return *i;
if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY ||
ifIndex == route->GetInputInterface ())
{
return *i;
}
}
}
return 0;
@@ -312,9 +317,11 @@ Ipv4StaticRouting::RemoveRoute (uint32_t index)
}
bool
Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
Packet packet,
RouteReplyCallback routeReply)
Ipv4StaticRouting::RequestRoute (
uint32_t ifIndex,
Ipv4Header const &ipHeader,
Packet packet,
RouteReplyCallback routeReply)
{
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " <<
&packet << ", " << &routeReply << ")");
@@ -328,27 +335,35 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
// First, see if this is a multicast packet we have a route for. If we
// have a route, then send the packet down each of the specified interfaces.
//
Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
ipHeader.GetDestination ());
if (mRoute)
if (ipHeader.GetDestination ().IsMulticast ())
{
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route");
for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination");
Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
ipHeader.GetDestination (), ifIndex);
if (mRoute)
{
Packet p = packet;
Ipv4Route route =
Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (),
mRoute->GetOutputInterface(i));
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
"Send via interface " << mRoute->GetOutputInterface(i));
routeReply (true, route, p, ipHeader);
return true;
"Multicast route found");
for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
{
Packet p = packet;
Ipv4Route route =
Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (),
mRoute->GetOutputInterface(i));
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
"Send via interface " << mRoute->GetOutputInterface(i));
routeReply (true, route, p, ipHeader);
return true;
}
}
return false; // Let other routing protocols try to handle this
}
//
// See if this is a unicast packet we have a route for.
//
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route");
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination");
Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
if (route != 0)
{

View File

@@ -51,7 +51,8 @@ class Ipv4StaticRouting : public Ipv4RoutingProtocol
public:
Ipv4StaticRouting () : m_defaultRoute (0) {}
virtual bool RequestRoute (Ipv4Header const &ipHeader,
virtual bool RequestRoute (uint32_t ifIndex,
Ipv4Header const &ipHeader,
Packet packet,
RouteReplyCallback routeReply);
@@ -105,7 +106,8 @@ private:
typedef std::list<Ipv4MulticastRoute *>::iterator MulticastRoutesI;
Ipv4Route *LookupStatic (Ipv4Address dest);
Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group);
Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
uint32_t ifIndex);
HostRoutes m_hostRoutes;
NetworkRoutes m_networkRoutes;

View File

@@ -171,8 +171,11 @@ Ipv4Address::IsBroadcast (void) const
bool
Ipv4Address::IsMulticast (void) const
{
// XXX
return false;
//
// Multicast addresses are defined as ranging from 224.0.0.0 through
// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
//
return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
}
uint32_t

View File

@@ -70,6 +70,7 @@ public:
/**
* \brief Asynchronously requests a route for a given packet and IP header
*
* \param ifIndex The interface index on which the packet was received.
* \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
@@ -99,9 +100,12 @@ public:
* immediately after the IP header, although most routing do not
* insert any extra header.
*/
virtual bool RequestRoute (const Ipv4Header &ipHeader,
virtual bool RequestRoute (uint32_t ifIndex,
const Ipv4Header &ipHeader,
Packet packet,
RouteReplyCallback routeReply) = 0;
static const uint32_t IF_INDEX_ANY = 0xffffffff;
};
/**