# HG changeset patch # User Craig Dowell # Date 1187032081 25200 # Node ID 3aef7d7a71c2f49f2a9c917cc04db050d5891cb3 # Parent 3760d52ef5d1ed4dcdc4f486719334575c503179 more multicast plumbing diff -r 3760d52ef5d1 -r 3aef7d7a71c2 examples/csma-multicast.cc --- a/examples/csma-multicast.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/examples/csma-multicast.cc Mon Aug 13 12:08:01 2007 -0700 @@ -65,7 +65,7 @@ { // 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 @@ #endif DebugComponentEnable("Me"); - DebugComponentEnable("OnOffApplication"); - DebugComponentEnable("UdpSocket"); + DebugComponentEnable("CsmaChannel"); + DebugComponentEnable("CsmaNetDevice"); DebugComponentEnable("UdpL4Protocol"); - DebugComponentEnable("Ipv4L3Protocol"); - DebugComponentEnable("Ipv4StaticRouting"); - DebugComponentEnable("CsmaNetDevice"); - DebugComponentEnable("CsmaChannel"); - DebugComponentEnable("Ipv4Interface"); - DebugComponentEnable("ArpIpv4Interface"); - DebugComponentEnable("Ipv4LoopbackInterface"); // 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 @@ 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")); + uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, + netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), + Ipv4Mask ("255.255.255.0")); + + uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, + netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), + Ipv4Mask ("255.255.255.0")); - CsmaIpv4Topology::AddIpv4Address ( - n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); - - CsmaIpv4Topology::AddIpv4Address ( - n3, n3ifIndex, 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 @@ ipv4 = n0->QueryInterface (Ipv4::iid); std::vector outputInterfaces (1); - outputInterfaces[0] = n0ifIndex; + outputInterfaces[0] = ifIndexNode0; ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, outputInterfaces); ipv4 = n1->QueryInterface (Ipv4::iid); - ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ipv4 = n2->QueryInterface (Ipv4::iid); - ipv4->JoinMulticastGroup (multicastSource, multicastGroup); + // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); ipv4 = n3->QueryInterface (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 ooff = Create ( @@ -181,10 +191,12 @@ 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 diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/applications/onoff-application.cc --- a/src/applications/onoff-application.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/applications/onoff-application.cc Mon Aug 13 12:08:01 2007 -0700 @@ -199,9 +199,12 @@ 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(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 @@ 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); } diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/devices/csma/csma-ipv4-topology.cc --- a/src/devices/csma/csma-ipv4-topology.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/devices/csma/csma-ipv4-topology.cc Mon Aug 13 12:08:01 2007 -0700 @@ -91,24 +91,22 @@ nd1->Attach (ch); } -void -CsmaIpv4Topology::AddIpv4Address(Ptr n1, - int ndNum, - const Ipv4Address& addr1, - const Ipv4Mask& netmask1) +uint32_t +CsmaIpv4Topology::AddIpv4Address( + Ptr 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 nd = node->GetDevice(netDeviceNumber); - Ptr nd1 = n1->GetDevice(ndNum); + Ptr ipv4 = node->QueryInterface (Ipv4::iid); + uint32_t ifIndex = ipv4->AddInterface (nd); - Ptr ip1 = n1->QueryInterface (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 diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/devices/csma/csma-ipv4-topology.h --- a/src/devices/csma/csma-ipv4-topology.h Sun Aug 12 22:43:25 2007 -0700 +++ b/src/devices/csma/csma-ipv4-topology.h Mon Aug 13 12:08:01 2007 -0700 @@ -94,18 +94,23 @@ /** - * \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 n1, int ndNum, - const Ipv4Address& addr1, - const Ipv4Mask& netmask1); + static uint32_t AddIpv4Address(Ptr node, + uint32_t netDeviceNumber, + const Ipv4Address address, + const Ipv4Mask mask); /** * \param nd1 Node diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/arp-ipv4-interface.cc --- a/src/internet-node/arp-ipv4-interface.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/internet-node/arp-ipv4-interface.cc Mon Aug 13 12:08:01 2007 -0700 @@ -81,6 +81,14 @@ 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"); diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-l3-protocol.cc --- a/src/internet-node/ipv4-l3-protocol.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/internet-node/ipv4-l3-protocol.cc Mon Aug 13 12:08:01 2007 -0700 @@ -246,12 +246,26 @@ } 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 @@ 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 @@ 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 @@ return; } - if (Forwarding (packet, ipHeader, device)) + if (Forwarding (index, packet, ipHeader, device)) { return; } @@ -521,10 +538,14 @@ } bool -Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr device) +Ipv4L3Protocol::Forwarding ( + uint32_t ifIndex, + Packet const &packet, + Ipv4Header &ipHeader, + Ptr 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 @@ 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 diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-l3-protocol.h --- a/src/internet-node/ipv4-l3-protocol.h Sun Aug 12 22:43:25 2007 -0700 +++ b/src/internet-node/ipv4-l3-protocol.h Mon Aug 13 12:08:01 2007 -0700 @@ -195,12 +195,19 @@ 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 device); + bool Forwarding (uint32_t ifIndex, + Packet const &packet, + Ipv4Header &ipHeader, + Ptr device); void ForwardUp (Packet p, Ipv4Header const&ip); uint32_t AddIpv4Interface (Ipv4Interface *interface); void SetupLoopback (void); diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-static-routing.cc --- a/src/internet-node/ipv4-static-routing.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/internet-node/ipv4-static-routing.cc Mon Aug 13 12:08:01 2007 -0700 @@ -196,7 +196,8 @@ 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 @@ 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 @@ } 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 @@ // 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) { diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/internet-node/ipv4-static-routing.h --- a/src/internet-node/ipv4-static-routing.h Sun Aug 12 22:43:25 2007 -0700 +++ b/src/internet-node/ipv4-static-routing.h Mon Aug 13 12:08:01 2007 -0700 @@ -51,7 +51,8 @@ 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 @@ typedef std::list::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; diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/node/ipv4-address.cc --- a/src/node/ipv4-address.cc Sun Aug 12 22:43:25 2007 -0700 +++ b/src/node/ipv4-address.cc Mon Aug 13 12:08:01 2007 -0700 @@ -171,8 +171,11 @@ 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 diff -r 3760d52ef5d1 -r 3aef7d7a71c2 src/node/ipv4.h --- a/src/node/ipv4.h Sun Aug 12 22:43:25 2007 -0700 +++ b/src/node/ipv4.h Mon Aug 13 12:08:01 2007 -0700 @@ -70,6 +70,7 @@ /** * \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 @@ * 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; }; /**