IPv6 manual
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Mon, 08 Jul 2013 20:21:40 +0200
changeset 9910 e9807cf4a7a5
parent 9909 e8571e4f5394
child 9911 90def6afa747
IPv6 manual
src/internet/doc/internet-stack.rst
src/internet/doc/ipv6.rst
src/internet/model/ipv6-extension.cc
--- a/src/internet/doc/internet-stack.rst	Sun Jul 07 14:20:41 2013 -0700
+++ b/src/internet/doc/internet-stack.rst	Mon Jul 08 20:21:40 2013 +0200
@@ -14,48 +14,83 @@
 IPv6, Neighbor Discovery, and other related protocols.
 
 Internet Nodes are not subclasses of class Node; they are simply Nodes that have
-had a bunch of IPv4-related objects aggregated to them. They can be put together
+had a bunch of IP-related objects aggregated to them. They can be put together
 by hand, or via a helper function :cpp:func:`InternetStackHelper::Install ()`
 which does the following to all nodes passed in as arguments:::
 
     void
     InternetStackHelper::Install (Ptr<Node> node) const
     {
-      if (node->GetObject<Ipv4> () != 0)
+      if (m_ipv4Enabled)
         {
-          NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating "
-                          "an InternetStack to a node with an existing Ipv4 object");
-          return;
+          /* IPv4 stack */
+          if (node->GetObject<Ipv4> () != 0)
+            {
+              NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating " 
+                              "an InternetStack to a node with an existing Ipv4 object");
+              return;
+            }
+
+          CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
+          CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
+          CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
+          // Set routing
+          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+          Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
+          ipv4->SetRoutingProtocol (ipv4Routing);
         }
 
-      CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
-      CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
-      CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
-      CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
-      node->AggregateObject (m_tcpFactory.Create<Object> ());
-      Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
-      node->AggregateObject (factory);
-      // Set routing
-      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
-      Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
-      ipv4->SetRoutingProtocol (ipv4Routing);
+      if (m_ipv6Enabled)
+        {
+          /* IPv6 stack */
+          if (node->GetObject<Ipv6> () != 0)
+            {
+              NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating " 
+                              "an InternetStack to a node with an existing Ipv6 object");
+              return;
+            }
+
+          CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv6L3Protocol");
+          CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv6L4Protocol");
+          // Set routing
+          Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+          Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create (node);
+          ipv6->SetRoutingProtocol (ipv6Routing);
+
+          /* register IPv6 extensions and options */
+          ipv6->RegisterExtensions ();
+          ipv6->RegisterOptions ();
+        }
+
+      if (m_ipv4Enabled || m_ipv6Enabled)
+        {
+          /* UDP and TCP stacks */
+          CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
+          node->AggregateObject (m_tcpFactory.Create<Object> ());
+          Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
+          node->AggregateObject (factory);
+        }
     }
 
 Where multiple implementations exist in |ns3| (TCP, IP routing), these objects
 are added by a factory object (TCP) or by a routing helper (m_routing).
 
 Note that the routing protocol is configured and set outside this
-function. By default, the following protocols are added to Ipv4:::
+function. By default, the following protocols are added:::
 
-    InternetStackHelper::InternetStackHelper ()
+    void InternetStackHelper::Initialize ()
     {
       SetTcp ("ns3::TcpL4Protocol");
-      static Ipv4StaticRoutingHelper staticRouting;
-      static Ipv4GlobalRoutingHelper globalRouting;
-      static Ipv4ListRoutingHelper listRouting;
+      Ipv4StaticRoutingHelper staticRouting;
+      Ipv4GlobalRoutingHelper globalRouting;
+      Ipv4ListRoutingHelper listRouting;
+      Ipv6ListRoutingHelper listRoutingv6;
+      Ipv6StaticRoutingHelper staticRoutingv6;
       listRouting.Add (staticRouting, 0);
       listRouting.Add (globalRouting, -10);
+      listRoutingv6.Add (staticRoutingv6, 0);
       SetRoutingHelper (listRouting);
+      SetRoutingHelper (listRoutingv6);
     }
 
 By default, IPv4 and IPv6 are enabled.
@@ -63,14 +98,14 @@
 Internet Node structure
 +++++++++++++++++++++++
 
-An IPv4-capable Node (an |ns3| Node augmented by aggregation to have one or more
+An IP-capable Node (an |ns3| Node augmented by aggregation to have one or more
 IP stacks) has the following internal structure.
 
 Layer-3 protocols
 ~~~~~~~~~~~~~~~~~
 
 At the lowest layer, sitting above the NetDevices, are the "layer 3" protocols,
-including IPv4, IPv6, and ARP. The class
+including IPv4, IPv6, ARP and so on. The class
 :cpp:class:`Ipv4L3Protocol` is an implementation class whose public interface is
 typically class :cpp:class:`Ipv4`, but the
 Ipv4L3Protocol public API is also used internally at present.
@@ -211,11 +246,11 @@
   local address, destination port, destination address) associated with the
   socket, and a receive callback for the socket.
 
-Ipv4-capable node interfaces
-++++++++++++++++++++++++++++
+IP-capable node interfaces
+++++++++++++++++++++++++++
 
 Many of the implementation details, or internal objects themselves, of
-Ipv4-capable Node objects are not exposed at the simulator public API. This
+IP-capable Node objects are not exposed at the simulator public API. This
 allows for different implementations; for instance, replacing the native |ns3|
 models with ported TCP/IP stack code. 
  
--- a/src/internet/doc/ipv6.rst	Sun Jul 07 14:20:41 2013 -0700
+++ b/src/internet/doc/ipv6.rst	Mon Jul 08 20:21:40 2013 +0200
@@ -1,7 +1,405 @@
 .. include:: replace.txt
 
-IPv6 
+IPv6
 ----
 
-*Placeholder chapter*
+This chapter describes the |ns3| IPv6 model capabilities and limitations along with its
+usage and examples.
+
+IPv6 model description
+**********************
+
+The IPv6 model is loosely patterned after the Linux implementation;
+the implementation is not complete as some features of IPv6 are not of
+much interest to simulation studies, and some features of IPv6 are simply
+not modeled yet in |ns3|.
+
+The base class :cpp:class:`Ipv6` 
+defines a generic API, while the class :cpp:class:`Ipv6L3Protocol` is the actual class
+implementing the protocol. The actual classes used by the IPv6 stack are located mainly 
+in the directory ``src/internet``. 
+
+The implementation of IPv6 is contained in the following files:
+
+::
+
+    src/internet/model/icmpv6-header.{cc,h}
+    src/internet/model/icmpv6-l4-protocol.{cc,h}
+    src/internet/model/ipv6.{cc,h}
+    src/internet/model/ipv6-address-generator.{cc,h}
+    src/internet/model/ipv6-autoconfigured-prefix.{cc,h}
+    src/internet/model/ipv6-end-point.{cc,h}
+    src/internet/model/ipv6-end-point-demux.{cc,h}
+    src/internet/model/ipv6-extension.{cc,h}
+    src/internet/model/ipv6-extension-demux.{cc,h}
+    src/internet/model/ipv6-extension-header.{cc,h}
+    src/internet/model/ipv6-header.{cc,h}
+    src/internet/model/ipv6-interface.{cc,h}
+    src/internet/model/ipv6-interface-address.{cc,h}
+    src/internet/model/ipv6-l3-protocol.{cc,h}
+    src/internet/model/ipv6-list-routing.{cc,h}
+    src/internet/model/ipv6-option.{cc,h}
+    src/internet/model/ipv6-option-demux.{cc,h}
+    src/internet/model/ipv6-option-header.{cc,h}
+    src/internet/model/ipv6-packet-info-tag.{cc,h}
+    src/internet/model/ipv6-pmtu-cache.{cc,h}
+    src/internet/model/ipv6-raw-socket-factory.{cc,h}
+    src/internet/model/ipv6-raw-socket-factory-impl.{cc,h}
+    src/internet/model/ipv6-raw-socket-impl.{cc,h}
+    src/internet/model/ipv6-route.{cc,h}
+    src/internet/model/ipv6-routing-protocol.{cc,h}
+    src/internet/model/ipv6-routing-table-entry.{cc,h}
+    src/internet/model/ipv6-static-routing.{cc,h}
+    src/internet/model/ndisc-cache.{cc,h}
+    src/network/utils/inet6-socket-address.{cc,h}
+    src/network/utils/ipv6-address.{cc,h}
+
+Also some helpers are involved with IPv6:
+
+::
+
+    src/internet/helper/internet-stack-helper.{cc,h}
+    src/internet/helper/ipv6-address-helper.{cc,h}
+    src/internet/helper/ipv6-interface-container.{cc,h}
+    src/internet/helper/ipv6-list-routing-helper.{cc,h}
+    src/internet/helper/ipv6-routing-helper.{cc,h}
+    src/internet/helper/ipv6-static-routing-helper.{cc,h}
+
+The model files can be roughly divided into:
+
+* protocol models (e.g., ipv6, ipv6-l3-protocol, icmpv6-l4-protocol, etc.)
+* routing models (i.e., anything with 'routing' in its name)
+* sockets and interfaces (e.g., ipv6-raw-socket, ipv6-interface, ipv6-end-point, etc.)
+* address-related things
+* headers, option headers, extension headers, etc.
+* accessory classes (e.g., ndisc-cache)
+
+
+Usage
+*****
+
+The following description is based on using the typical helpers found in the example code.
+
+IPv6 does not need to be activated in a node. it is automatically added to the 
+available protocols once the Internet Stack is installed.
+
+In order to *not* install IPv6 along with IPv4, it is possible to use
+:cpp:class:`ns3::InternetStackHelper` method `SetIpv6StackInstall (bool enable)` 
+before installing the InternetStack in the nodes.
+
+Note that to have an IPv6-only network (i.e., to not install the IPv4 stack in a node)
+one should use :cpp:class:`ns3::InternetStackHelper` method `SetIpv4StackInstall (bool enable)` 
+before the stack installation.
+
+As an example, in the following code node 0 will have both IPv4 and IPv6, node 1 only 
+only IPv6 and node 2 only IPv4:
+
+::
+
+    NodeContainer n;
+    n.Create (3);
+
+    InternetStackHelper internet;
+    InternetStackHelper internetV4only;
+    InternetStackHelper internetV6only;
+
+    internetV4only.SetIpv6StackInstall (false);
+    internetV6only.SetIpv4StackInstall (false);
+    
+    internet.Install (n.Get (0));
+    internetV6only.Install (n.Get (1));
+    internetV4only.Install (n.Get (2));
+   
+
+
+IPv6 addresses assignment
+=========================
+
+In order to use IPv6 on a network, the first thing to do is assigning IPv6 addresses.
+
+Any IPv6-enabled |ns3| node will have at least one NetDevice: the :cpp:class:`ns3::LoopbackNetDevice`.
+The loopback device address is ``::1``.
+All the other NetDevices will have one or more IPv6 addresses:
+
+* One link-local address: ``fe80::interface ID``, where ``interface ID`` is derived from the NetDevice MAC address.
+* Zero or more global addresses, e.g., ``2001:db8::1``.
+
+Typically the first address on an interface will be the link-local one, with the global 
+address(es) being the following ones.
+
+IPv6 global addresses might be:
+
+* manually assigned
+* auto-generated
+
+|ns3| can use both methods, and it's quite important to understand the implications of both.
+
+Manually assigned IPv6 adddresses
++++++++++++++++++++++++++++++++++
+
+This is probably the easiest and most used method. As an example:
+
+::
+
+    Ptr<Node> n0 = CreateObject<Node> ();
+    Ptr<Node> n1 = CreateObject<Node> ();
+    NodeContainer net (n0, n1);
+    CsmaHelper csma;
+    NetDeviceContainer ndc = csma.Install (net); 
+    
+    NS_LOG_INFO ("Assign IPv6 Addresses.");
+    Ipv6AddressHelper ipv6;
+    ipv6.SetBase (Ipv6Address ("2001:db8::"), Ipv6Prefix (64));
+    Ipv6InterfaceContainer ic = ipv6.Assign (ndc);
+
+This method will add two global IPv6 addresses to the nodes. Note that, as usual for IPv6,
+all the nodes will also have a link-local address. Typically the first address on an 
+interface will be the link-local one, with the global address(es) being the following ones.
+
+Auto-generated IPv6 adddresses
+##############################
+
+This is accomplished by relying on the RADVD protocol, implemented by the class
+:cpp:class:`Radvd`. At the time there is no helper for this application, and the
+use is rather difficult (see ``examples/ipv6/radvd.cc``).
+
+Upon using this method, the nodes will acquire dynamically (i.e., during the simulation)
+one (or more) global address(es) according to the RADVD configuration. 
+These addresses will be bases on the RADVD announced prefix and the node's EUI-64.
+
+Random-generated IPv6 adddresses
+################################
+
+While IPv6 real nodes will use randomly generated addresses to protect privacy, |ns3|
+does NOT have this capability. This feature haven't been so far considered as interesting
+for simulation.
+
+Duplicate Address Detection (DAD)
+#################################
+
+Nodes will perform DAD (it can be disabled using an :cpp:class:`Icmpv6L4Protocol` attribute).
+Upon receiving a DAD, however, nodes will not react to it. As is: DAD reaction is 
+incomplete so far. 
+The main reason relies on the missing random-generated address capability. Moreover, 
+since |ns3| nodes will usually be well-behaving, therea should't be any Duplicate Address.
+This might be changed in the future, so as to avoid issues with real-world 
+integrated simulations.
+
+Host and Router behaviour in IPv6 and |ns3|
+===========================================
+
+In IPv6 there is a clear distinction between *routers* and *hosts*. As one might expect,
+routers can forward packets from an interface to another interface, while hosts drop
+packets not directed to them.
+
+Unfortunately, forwarding is not the only thing affected by this distinction, and forwarding
+itself might be fine-tuned, e.g., to forward packets incoming from an interface and drop 
+packets from another interface.
+
+In |ns3| a node is configured to be an *host* by default. There are two main ways to change 
+this behaviour:
+
+* Using :cpp:class:`ns3::Ipv6InterfaceContainer` `SetForwarding(uint32_t i, bool router)` where ``i`` is the interface index in the container.
+* Changing the :cpp:class:`ns3::Ipv6` attribute ``IpForward``.
 
+Either one can be used during the simulation.
+
+A fine-grained setup can be accomplished by using :cpp:class:`ns3::Ipv6Interface` `SetForwarding (bool forward);`
+which allows to change the behaviour on a per-interface-basis.
+
+Note that the node-wide configuration only serves as a convenient method to enable/disable the 
+:cpp:class:`ns3::Ipv6Interface` specific setting. An Ipv6Interface added to a node
+with forwarding enabled will be set to be forwarding as well.
+This is really important when a node has interfaces added during the simulation. 
+
+According to the :cpp:class:`ns3::Ipv6Interface` forwarding state, the following happens:
+
+* Forwarding OFF
+
+ * The node will NOT reply to Router Solicitation
+ * The node will react to Router Advertisement
+ * The node will periodically send Router Solicitation
+ * Routing protocols MUST DROP packets not directed to the node
+
+* Forwarding ON
+
+ * The node will reply to Router Solicitation
+ * The node will NOT react to Router Advertisement
+ * The node will NOT send Router Solicitation
+ * Routing protocols MUST forward packets
+
+The behaviour is matching ip-sysctl.txt (http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt)
+with the difference that it's not possible to override the behaviour using esoteric settings 
+(e.g., forwarding but accept router advertisements, accept_ra=2, or forwarding but send router solicitations
+forwarding=2).
+
+Consider carefully the implications of packet forwarding. As an example, a node will NOT send
+ICMPv6 PACKET_TOO_BIG messages from an interface with frowarding off. This is completely normal,
+as the Routing protocol will drop the packet before attempting to forward it.
+
+
+Helpers
+=======
+
+Typically the helpers used in IPv6 setup are:
+
+* :cpp:class:`ns3::InternetStackHelper`
+* :cpp:class:`ns3::Ipv6AddressHelper`
+* :cpp:class:`ns3::Ipv6InterfaceContainer`
+
+The use is almost identical to the corresponding IPv4 case, e.g.:
+
+::
+
+    NodeContainer n;
+    n.Create (4);
+    
+    NS_LOG_INFO ("Create IPv6 Internet Stack");
+    InternetStackHelper internetv6;
+    internetv6.Install (n);
+    
+    NS_LOG_INFO ("Create channels.");
+    CsmaHelper csma;
+    NetDeviceContainer d = csma.Install (n);
+    
+    NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+    Ipv6AddressHelper ipv6;
+    ipv6.SetBase (Ipv6Address ("2001:db8::"), Ipv6Prefix (64));
+    Ipv6InterfaceContainer iic = ipv6.Assign (d);
+
+Additionally, a common task is to enable forwarding on one of the nodes and to
+setup a default route toward it in the other nodes, e.g.:
+
+::
+
+    iic.SetForwarding (0, true);
+    iic.SetDefaultRouteInAllNodes (0);
+
+This will enable forwarding on the node *0* and will setup a default route in 
+:cpp:class:`ns3::Ipv6StaticRouting` on all the other nodes. Note that this 
+requires that Ipv6StaticRouting is present in the nodes. 
+
+The IPv6 routing helpers enable the user to perform specific tasks on the
+particular routing algorith and to print the routing tables. 
+
+
+Attributes
+==========
+
+Many classes in the |ns3| IPv6 implementation contain attributes. The most
+useful ones are:
+
+* :cpp:class:`ns3::Ipv6`
+ 
+ * `IpForward`, boolean, default false. Globally enable or disable IP forwarding for all current and future IPv6 devices.
+ * `MtuDiscover`, boolean, default true. If disabled, every interface will have its MTU set to 1280 bytes.
+
+* :cpp:class:`ns3::Ipv6L3Protocol`
+
+ * `DefaultTtl`, uint8_t, default 64. The TTL value set by default on all outgoing packets generated on this node.
+ * `SendIcmpv6Redirect`, boolean, default true. Send the ICMPv6 Redirect when appropriate.
+ 
+* :cpp:class:`ns3::Icmpv6L4Protocol`
+
+ * `DAD`, boolean, default true. Always do DAD (Duplicate Address Detection) check.
+ 
+* :cpp:class:`ns3::NdiscCache`
+
+ * `UnresolvedQueueSize`, uint32_t, default 3. Size of the queue for packets pending an NA reply.
+ 
+Output
+======
+
+The IPv6 stack provides some useful trace sources:
+
+* :cpp:class:`ns3::Ipv6L3Protocol`
+
+ * `Tx`, Send IPv6 packet to outgoing interface.
+ * `Rx`, Receive IPv6 packet from incoming interface.
+ * `Drop`, Drop IPv6 packet.
+
+* :cpp:class:`ns3::Ipv6Extension`
+
+ * `Drop`, Drop IPv6 packet.
+
+The latest trace source is generated when a packet contains an unknown option blocking its processing.
+
+Mind that :cpp:class:`ns3::NdiscCache` could drop packets as well, and they are not logged 
+in a trace source (yet). This might generate some confusion in the sent/received packets counters.
+
+Advanced Usage
+==============
+
+IPv6 maximum transmission unit (MTU) and fragmentation
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+|ns3| NetDevices define the MTU according to the L2 simulated Device. IPv6 requires
+that the minimum MTU is 1280 bytes, so all NetDevices are required to support at least
+this MTU. This is the link-MTU.
+
+In order to support different MTUs in a source-destination path, |ns3| IPv6 model can
+perform fragmentation.
+This can be either triggered by receiving a packet bigger than the link-MTU from the L4
+protocols (UDP, TCP, etc.), or by receving an ICMPv6 PACKET_TOO_BIG message.
+The model mimics RFC 1981, with the following notable exceptions:
+
+* L4 protocols are not informed of the Path MTU change
+* TCP can not change its Segment Size according to the Path-MTU.
+
+Both limitations are going to be removed in due time.
+
+The Path-MTU cache is currently based on the source-destination IPv6 addresses. Further
+classifications (e.g., flow label) are possible but not yet implemented.
+
+The Path-MTU default validity time is 10 minutes. After the cache entry expiration, the
+Path-MTU information is removed and the next packet will (eventually) trigger a new ICMPv6
+PACKET_TOO_BIG message.
+Note that 1) this is consistent with the RFC specification and 2) L4 protocols are 
+responsible for retransmitting the packets.
+
+Examples
+========
+
+The examples for IPv6 are in the directory ``examples/ipv6``. These examples focus on
+the most interesting IPv6 peculiarities, such as fragmentation, redirect and so on.
+
+Moreover, most TCP and UDP examples located in ``examples/udp``, ``examples/tcp``, etc. 
+have a command-line option to use IPv6 instead of IPv4.
+
+Troubleshooting
+===============
+
+There are just a few pitfalls to avoid while using |ns3| IPv6.
+
+Routing loops
++++++++++++++
+
+Since the only (so far) routing scheme available for IPv6 is :cpp:class:`ns3::Ipv6StaticRouting`,
+default router have to be setup manually. When there are two or more routers in a network 
+(e.g., node A and node B), avoid using the helper function `SetDefaultRouteInAllNodes` 
+for more than one router.
+
+The consequence would be to install a default route to B in A and a default route pointing to 
+A in B, generating a loop. 
+
+Global address leakage
+++++++++++++++++++++++
+
+Remember that addresses in IPv6 are *global* by definition. When using IPv6 with an emulation
+|ns3| capability, avoid at all costs address leakage toward the global Internet. 
+It is advisable to setup an external firewall to prevent leakage.
+
+2001:DB8::/32 addresses
++++++++++++++++++++++++
+
+IPv6 standard (RFC 3849) defines the ``2001:DB8::/32`` address class for the *documentation*.
+This manual uses this convention. The addresses in this class are, however, only usable in
+a document, and routers should discard them.
+
+Validation
+**********
+
+The IPv6 protocols has not yet been extensively validated against real implementations.
+The actual tests involve mainly performing checks of the .pcap trace files with Wireshark, 
+and the results are positive.
+
--- a/src/internet/model/ipv6-extension.cc	Sun Jul 07 14:20:41 2013 -0700
+++ b/src/internet/model/ipv6-extension.cc	Mon Jul 08 20:21:40 2013 +0200
@@ -54,7 +54,7 @@
                    UintegerValue (0),
                    MakeUintegerAccessor (&Ipv6Extension::GetExtensionNumber),
                    MakeUintegerChecker<uint8_t> ())
-    .AddTraceSource ("Drop", "Drop ipv6 packet",
+    .AddTraceSource ("Drop", "Drop IPv6 packet",
                      MakeTraceSourceAccessor (&Ipv6Extension::m_dropTrace))
   ;
   return tid;