[Top] [Contents] [Index] [ ? ]

ns-3 Manual (html version)

For a pdf version of this manual, see http://www.nsnam.org/docs/manual.pdf.

This is an ns-3 reference manual. Primary documentation for the ns-3 project is available in four forms:

This document is written in GNU Texinfo and is to be maintained in revision control on the ns-3 code server. Both PDF and HTML versions should be available on the server. Changes to the document should be discussed on the ns-developers@isi.edu mailing list.

This software is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This software 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, see http://www.gnu.org/licenses/.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1. Ipv4 refactoring overview

This section describes proposed changes for ns-3.5. We hope to implement and review these changes and merge shortly after ns-3.4 is released.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Goals

The overall goal is to refactor the IP layer and API in ns-3 to address several issues with the current design.

For instance, the current API makes it difficult to build a Linux-like routing subsystem that includes a route cache, or to assign multiple IP addresses to an interface.

Another major goal is to get the IPv6 code merged and make sure that it resembles the IPv4 design.

The overall goal is to align with Linux in general, with the following:

The current prototype of this effort (http://code.nsnam.org/tomh/ns-3-ip) has grown beyond what is reasonable for a single merge event, so we would like to attack this in phases. This document describes the big picture design (our intended end design) and describes the proposed steps for review and merging.

These phases are described in more detail below, but first we summarize the overall proposal. The proposed changes can be grouped as changes to the 1) internal routing architecture and external routing API, and 2) architecture and API for handling IP addresses associated with Net Devices. We provide a brief big-picture description of these two grouping below.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Routing

figures/routing-old

Figure 1.1: Overview of current routing

Figure fig:routing-old shows the existing routing architecture. The API for configuring the IPv4 layer, including all routing, is part of the Ipv4 abstract base class. From an implementation perspective, the Ipv4L3Protocol class keeps track of a list of Ipv4RoutingProtocols. The existing calls to add static routes (from class Ipv4) end up in an Ipv4StaticRouting(), the routes added by the global routing end up in a Ipv4GlobalRouting(), OLSR (if used) is yet another Ipv4RoutingProtocol, etc. When forwarding a packet, the Lookup() method in Ipv4L3Protocol will walk the list of routing protocols until a route is found, and will call Ipv4L3Protocol::SendRealOut() when done. This architecture supports on-demand routing.

For locally outbound packets, RequestIfIndex() is called; this is a synchronous call that allows the transport protocol to find the source address, and later it is called again at the IP layer to find the right outgoing interface.

Note in this diagram that class Ipv4 provides the routing API, and the routing API used for configuring routes is later mapped to a static routing object. Note also that Ipv4L3Protocol holds a list of routing protocols and is responsible for walking the list. The bold dashed arrows in the diagram show that routing API calls in class Ipv4 are handled in Ipv4L3Protocol which may ultimately call one of the Ipv4RoutingProtocols in the list.

figures/routing-new

Figure 1.2: Overview of proposed routing architecture

Figure fig:routing-new shows the proposed overall routing architecture. The class Ipv4RoutingProtocol() remains, but the names and signatures of the methods are changed from RequestIfIndex and RequestRoute() to RouteOutput and RouteInput, respectively. This name and signature change mirrors the Linux approach. Another change is that Ipv4L3Protocol does not hold the list of protocols; instead, this list is held by a specialized Ipv4RoutingProtocol called Ipv4ListRoutingProtocol. The Ipv4ListRoutingProtocol exports the previous API for AddRoutingProtocol().

Internally, RouteOutput() is still a synchronous call, but a reference counted Ipv4Route is returned, and this value is passed down the stack so that the IP layer does not have to query the routing again (similar to how an skb caches a dst_cache entry). The Ipv4Route class is designed to be forward compatible with Linux's dst_cache structure, in case someone wants to support a Linux-like caching implementation.

The default Ipv4RoutingProtocol implementation will inherit from the abstract base classes Ipv4StaticRouting, Ipv4ListRouting, and Ipv4MulticastRouting (more on these below). At simulation setup time, an Ipv4RoutingProtocol object must be created and added to Ipv4 via Ipv4::SetRoutingProtocol(). Exactly one Ipv4RoutingProtocol object must be added. If multiple protocols are to be added (e.g. currently with AddRoutingProtocol()), the Ipv4RoutingProtocol pointer should be cast to Ipv4ListRoutingProtocol and AddRoutingProtocol() can be called.

For packets traveling outbound, the transport protocol will query the Ipv4RoutingProtocol for a route using the Ipv4RoutingProtocol::RouteOutput() call. It can obtain a pointer to this via Ipv4::GetRoutingProtocol(). A Ptr to Ipv4Route object is returned. This is analagous to a dst_cache entry in Linux. The Ipv4Route is carried down to the Ipv4L3Protocol to avoid a second lookup there. However, some cases (e.g. Ipv4 raw sockets) will require a call to RouteOutput() from Ipv4L3Protocol.

For packets coming inbound, that may be forwarded or delivered locally, the following steps occur. Ipv4Receive calls Ipv4RoutingProtocol::RouteInput(). This passes the packet ownership to the Ipv4RoutingProtocol object. There are four callbacks associated with this call:

Ipv4RoutingProtocol must eventually call one of these callbacks for each packet that it takes responsibility for. This is basically how the input routing process works in Linux.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.1 Static unicast routing

Ipv4StaticRoutingProtocol objects support basic configuration for unicast routing. For unicast routing, the various ways that unicast routes are added (netlink, ioctls, eventually map to a few function calls in the kernel:

We support these three basic configuration primitives in the Ipv4RoutingProtocol object. However, the class that is passed back and forth is not an Ipv4Route but a separate class RtMessage (exact name is to be determined; this piece not yet implemented). For starters, we will move static routing methods out of class Ipv4 to class Ipv4StaticRouting, and later change the methods as needed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.2 Multicast routing

In Linux, the kernel maintains a list of virtual interfaces. These are called "vifs" and can be thought of analogously to our Ipv4Interface classes– they are classes that hold per-interface multicast state such as TTL threshold. In Linux, they also serve to provide an abstraction so multicast forwarding doesn't have to worry about whether the interface is a tunneling or real device. So, we maintain class MulticastVif for this purpose, and any Ipv4RoutingProtocol that inherits from Ipv4MulticastRoutingProtocol owns this list.

In Linux, multicast routing APIs for user-space applications are supported by a special type of multicast routing socket. For ns-3, it is not necessary to use an actual socket to communicate with the "kernel" but we can try to align the API to the API used by the multicast routing socket.

A key concept is that of a virtual interface (vif). This abstraction of a NetDevice can store multicast specific information about the device, and abstracts whether the device is a real or tunnel device in the kernel.

The following methods need to be supported by Ipv4RoutingProtocol, to map to the configuration possibilities of a multicast routing socket:

In addition, there needs to be some kind of RouteRequest-like callback that Ipv4RoutingProtocol can call, to resolve packets for which there is no cache entry. This is analogous to Linxu ipmr_cache_unresolved().


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.3 Ipv4RoutingProtocol specialization

figures/routing-specialization

Figure 1.3: Ipv4RoutingProtocol specialization

The point of this architecture is to support a few different routing implementations, as depicted in Figure 11-2. A class Ipv4ListRoutingProtocol (implementation class Ipv4ListRoutingImpl) provides the existing list routing approach in ns-3. Its API is the same as base class Ipv4RoutingProtocol except for the addition of Ipv4ListRoutingProtocol::AddRoutingProtocol().

In the future, this arrangement should also allow someone to implement a Linux-like implementation with routing cache, or a Click modular router, but those are out of scope for now..


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.4 Multicast host operation

In user-space, multicast may be configured on a per-socket basis. This control is performd in a real system by passing the following IP socket options:

In the kernel, the kernel maintains a list of sockets that are members of a multicast group. The first such socket will trigger IGMP joins for the multicast group. When the last socket leaves the group, it will trigger an IGMP leave.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.4.1 API changes

The following API changes related to multicast host operation are against ns-3.4 and earlier releases.

Existing (retained):

Attribute UdpSocket::IpMulticastTtl

Note: The type of this attribute and the IpTtl attribute has been changed from uint32_t to uint8_t

New:

virtual int UdpSocket::MulticastJoinGroup(uint32_t interface, const Address &groupAddress) = 0;
virtual int UdpSocket::MulticastLeaveGroup (uint32_t interface, const Address &groupAddress) = 0;

We also need two more socket attributes to complete the typical API:

Removed:

The below helper functions are slightly wrong in that they specify source-specific multicast groups only. They may be useful in the future to provide additional helper API to allow socket-independent joins (would also need a matching Leave() call). It is also questionable whether they belong in a static multicast route helper.

  void StaticMulticastRouteHelper::JoinMulticastGroup (Ptr<Node> n, Ipv4Address source, Ipv4Address group);
  void StaticMulticastRouteHelper::JoinMulticastGroup (std::string nName, Ipv4Address source, Ipv4Address group);

The above two methods call into Ipv4::JoinMulticastGroup, which also should be removed.

  virtual void Ipv4::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;
  virtual void Ipv4::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;

Note: This proposal suggests that we do not support anymore the behavior that an outgoing multicast packet is originated on all interfaces. Doing so is somewhat incompatible with how routing lookups are done in the transport layer, and is not what real systems do.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.4.2 How implemented

The source address selection in Udp is performed as follows:

I do not know yet how to implement IpMulticastLoop. Perhaps a packet tag that tells the Ipv4 layer originating the datagram to also copy and send to loopback.

The Ipv4 layer needs to manage IGMP messages. So, a Udp socket that joins or leaves a multicast group needs to indicate this somehow to some entity in the Ipv4 layer. This is enabled by two new public methods in class Ipv4:

  virtual int Ipv4::MulticastJoinGroup (uint32_t interface, const Ipv4Address &groupAddress) = 0;
  virtual int Ipv4::MulticastLeaveGroup (uint32_t interface, const Ipv4Address &groupAddress) = 0;

Careful readers will note that the above methods are similar to the previous methods in Ipv4 that are being removed. However, the naming is improved (aligned with Linux mcast_join_group() and mcast_leave_group()) and the signature is different (source address now omitted).

In addition, the forwarding process will need to know whether to deliver locally a received multicast datagram; it uses the following public method in class Ipv4, analogous to Linux mcast_check_group():

  virtual bool Ipv4::MulticastCheckGroup (uint32_t interface, const Ipv4Address &groupAddress) = 0;

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Interfaces


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3.1 Interface naming

Deconflict NetDevice::ifIndex and Ipv4::ifIndex (bug 85) by changing references to IPv4 interfaces from "ifIndex" to "interface".

This is in the ~tomh/ns-3-ip-interfaces repo


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3.2 Handling multiple addresses

Ipv4 interfaces should have a list of addresses, not just a single address. (bug 188)

class Ipv4InterfaceAddress: This is a new class to parallel Linux struct in_ifaddr. It holds IP addressing information, including mask, broadcast address, scope, whether primary or secondary, etc.

+  virtual uint32_t AddAddress (uint32_t interface, Ipv4InterfaceAddress address) = 0;
+  virtual Ipv4InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
+  virtual uint32_t GetNAddresses (uint32_t interface) const = 0;

This convenience function was removed:

-  virtual uint32_t GetIfIndexByAddress (Ipv4Address addr,
-    Ipv4Mask mask = Ipv4Mask("255.255.255.255"));

A few public methods were renamed because they were poorly named:

-  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr,
+  virtual int32_t GetInterfaceForAddress (Ipv4Address address,
     Ipv4Mask mask) const = 0;
-  virtual int32_t FindInterfaceForDevice(Ptr<NetDevice> nd) const = 0;
+  virtual int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const = 0;

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3.3 Ipv4Interface and Loopback

(To do)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 Miscellaneous


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.1 Remove class Ipv4Impl


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.2 Tags rework

Some problems with the existing tags have been identified. Mathieu posted this to the list on March 23.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.3 Virtual devices


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.4 Helper API

Users should be able to trace (either debug print, or redirect to a trace file) the routing table in a format such as used in an Unix implementation:

# netstat -nr (or # route -n)
Kernel IP routing table
Destination   Gateway      Genmask         Flags  MSS Window  irtt Iface
127.0.0.1     *            255.255.255.255 UH       0 0          0 lo
172.16.1.0    *            255.255.255.0   U        0 0          0 eth0
172.16.2.0    172.16.1.1   255.255.255.0   UG       0 0          0 eth0

# ip route show
192.168.99.0/24 dev eth0  scope link 
127.0.0.0/8 dev lo  scope link 
default via 192.168.99.254 dev eth0

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.5 Arp needs a public interface.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.6 Global routing refactoring

Global unicast routing needs to be more efficient (the implementation).

Global computation of multicast routing should be implemented as well. This would ignore group membership and ensure that a copy of every sourced multicast datagram would be delivered to each node. This might be implemented as an RPF mechanism that functioned on-demand by querying the forwarding table, and perhaps optimized by a small multicast forwarding cache. It is a bit trickier to implement over wireless links where the input interface is the same as the output interface; other aspects of the packet must be considered and the forwarding logic slightly changed to allow for forwarding out the same interface.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5 Merge plan


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.1 Phase 1

  1. Olsr refactoring: mathieu/ns-3-olsr (mathieu/ns-3-olsr repo)
  2. base class Ipv4RoutingProtocol API change (tomh/ns-3-ip-routing repo)
  3. Ipv4 interface and interface address changes (tomh/ns-3-ip-interfaces repo)
  4. Create ABCs for List, Multicast, Static Routing Protocols, move existing Ipv4 API there (do not try to improve APIs yet)
  5. Ipv4RoutingHelper
  6. Tags rework: mathieu/ns-3-tags repo

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.1.1 Ipv4RoutingHelper sketch

class Ipv4RoutingHelper
{
public:
  virtual Ptr<Ipv4RoutingProtocol> Create (void) = 0;
};

class InternetStackHelper
{
public:
  void Install (NodeContainer nodes, const Ipv4RoutingProtocolHelper
&helper);
};

class ListIpv4RoutingHelper {
public:
  // The Default function constructs, a list helper with a 
  // static routing protocol with priority 0.
  // The default constructor builds a routing helper which
  // is empty
  static ListIpv4RoutingHelper Default (void);
  void Add (int priority, std::string type,
            std::string n0, const AttributeValue &v0,
            ...);
  virtual Ptr<Ipv4RoutingPRotocol> Create (void) = 0;
};


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.2 Phase 2: Clean implementations


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.3 Phase 3: Improve routing and helper APIs


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.4 Phase 4: Misc.

Global Routing scalability, etc.


[Top] [Contents] [Index] [ ? ]

Table of Contents


[Top] [Contents] [Index] [ ? ]

About This Document

This document was generated by Tom Henderson on April, 8 2009 using texi2html 1.78.

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ < ] Back Previous section in reading order 1.2.2
[ > ] Forward Next section in reading order 1.2.4
[ << ] FastBack Beginning of this chapter or previous chapter 1
[ Up ] Up Up section 1.2
[ >> ] FastForward Next chapter 2
[Top] Top Cover (top) of document  
[Contents] Contents Table of contents  
[Index] Index Index  
[ ? ] About About (help)  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:


This document was generated by Tom Henderson on April, 8 2009 using texi2html 1.78.