Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
187d091
Added Traffic Control Layer
natale-p Oct 7, 2015
eb9a024
Internet depends on traffic-control
natale-p Oct 7, 2015
262931f
Made public ProtocolHandlerEntry struct in node.h
natale-p Oct 7, 2015
80baa0f
Aggregate TrafficControlLayer on any Internet-enabled node
natale-p Oct 7, 2015
9285b11
Aggregate TCLayer by default on tests
natale-p Oct 7, 2015
cbafa49
Register callbacks on TCLayer and NetDevices, RX side
natale-p Oct 7, 2015
11f20e7
Use traffic-control to send packets
natale-p Oct 7, 2015
0c814e4
Initial support for multiple transmission queues inside NetDevices
stavallo Nov 19, 2015
ef2c685
WifiNetDevices can return the number of transmission queues based on …
stavallo Nov 19, 2015
bb27480
Flow control Part I: NetDeviceQueues can be started, stopped and woken
stavallo Oct 20, 2015
610f9c7
PointToPointNetDevice: Add support for flow control
stavallo Nov 12, 2015
251787d
NetDevices return the index of the transmission queue they select for…
stavallo Nov 20, 2015
bd130e8
Make Queue store QueueItem objects
stavallo Jan 5, 2016
2bf15fb
Add the QueueDisc base class
stavallo Oct 23, 2015
6e6ba99
The traffic control layer enqueues packets in the queue disc
stavallo Dec 4, 2015
4dd14d5
Defer the addition of the IP header until the packet is extracted fro…
stavallo Jan 6, 2016
9881fe5
Ipv4Header: Add GetVersion and make DscpTypeToString static
stavallo Jan 8, 2016
106f8f2
Add the pfifo_fast queue disc
stavallo Jan 9, 2016
7d99326
Add a queue disc helper to ease the installation of queue discs
stavallo Dec 2, 2015
d850946
Add a traffic control example
pasquimp Nov 25, 2015
0815e6b
Add a pfifo_fast test suite
pasquimp Dec 14, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added Traffic Control Layer
  • Loading branch information
natale-p authored and stavallo committed Jan 15, 2016
commit 187d0915a77950de9c1e210c90b8f900f1a3c79c
1 change: 1 addition & 0 deletions doc/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
* - spectrum
* - stats
* - tap-bridge
* - traffic-control
* - test
* - topology-read
* - uan
Expand Down
1 change: 1 addition & 0 deletions doc/models/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SOURCES = \
$(SRC)/wimax/doc/wimax.rst \
$(SRC)/uan/doc/uan.rst \
$(SRC)/topology-read/doc/topology.rst \
$(SRC)/traffic-control/doc/traffic-control.rst \
$(SRC)/spectrum/doc/spectrum.rst \
$(SRC)/stats/doc/adaptor.rst \
$(SRC)/stats/doc/aggregator.rst \
Expand Down
1 change: 1 addition & 0 deletions doc/models/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ This document is written in `reStructuredText <http://docutils.sourceforge.net/r
spectrum
sixlowpan
topology
traffic-control
uan
wave
wifi
Expand Down
119 changes: 119 additions & 0 deletions src/traffic-control/doc/traffic-control.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
Traffic Control
---------------

.. heading hierarchy:
------------- Chapter
************* Section (#.#)
============= Subsection (#.#.#)
############# Paragraph (no number)

This layer has been designed to be between NetDevices (L2) and any network
protocol (e.g. IP). It is responsible to analyze packets and to perform actions
on them: the most common is scheduling, but many others are planned / implemented.

Brief description of the old node/device/protocol interactions
**************************************************************

The main question that we would like to answer in the following paragraphs is:
how a ns-3 node can send/receive packets?

If we analyze any example out there, the ability of the node to receive/transmit
packets derives from the interaction of two helper:

* L2 Helper (something derived from NetDevice)
* L3 Helper (usually from Internet module)

L2 Helper main operations
=========================

Any good L2 Helper will do the following operations:

* Create n netdevices (n>1)
* Attach a channel between these devices
* Call Node::AddDevice ()

Obviously the last point is the most important.

Node::AddDevice (network/model/node.cc:128) assigns an interface index to the
device, calls NetDevice::SetNode, sets the receive callback of the device to
Node::NonPromiscReceiveFromDevice. Then, it schedules NetDevice::Initialize() method at
Seconds(0.0), then notify the registered DeviceAdditionListener handlers (not used BY ANYONE).

Node::NonPromiscReceiveFromDevice calls Node::ReceiveFromDevice.

Node::ReceiveFromDevice iterates through ProtocolHandlers, which are callbacks
which accept as signature:

ProtocolHandler (Ptr<NetDevice>, Ptr<const Packet>, protocol, from_addr, to_addr, packetType).

If device, protocol number and promiscuous flag corresponds, the handler is
invoked.

Who is responsible to set ProtocolHandler ? We will analyze that in the next
section.

L3 Helper
=========

We have only internet which provides network protocol (IP). That module splits
the operations between two helpers: InternetStackHelper and Ipv{4,6}AddressHelper.

InternetStackHelper::Install (internet/helper/internet-stack-helper.cc:423)
creates and aggregates protocols {ArpL3,Ipv4L3,Icmpv4}Protocol. It creates the
routing protocol, and if Ipv6 is enabled it adds {Ipv6L3,Icmpv6L4}Protocol. In
any case, it instantiates and aggregates an UdpL4Protocol object, along with a
PacketSocketFactory.
Ultimately, it creates the required objects and aggregates them to the node.

Let's assume an Ipv4 environment (things are the same for Ipv6).

Ipv4AddressHelper::Assign (src/internet/helper/ipv4-address-helper.cc:131)
registers the handlers. The process is a bit long. The method is called with
a list of NetDevice. For each of them, the node and Ipv4L3Protocol pointers are
retrieved; if an Ipv4Interface is already registered for the device, on that the
address is set. Otherwise, the method Ipv4L3Protocol::AddInterface is called,
before adding the address.

IP interfaces
=============

In Ipv4L3Protocol::AddInterface (src/internet/model/ipv4-l3-protocol.cc:300)
two protocol handlers are installed: one that react to ipv4 protocol number,
and one that react to arp protocol number (Ipv4L3Protocol::Receive and
ArpL3Protocol::Receive, respectively). The interface is then created,
initialized, and returned.

Ipv4L3Protocol::Receive (src/internet/model/ipv4-l3-protocol.cc:472) iterates
through the interface. Once it finds the Ipv4Interface which has the same device
as the one passed as argument, invokes the rxTrace callback. If the interface is
down, the packet is dropped. Then, it removes the header and trim any residual
frame padding. If checksum is not OK, it drops the packet. Otherwise, forward
the packet to the raw sockets (not used). Then, it ask the routing protocol what
is the destiny of that packet. The choices are: Ipv4L3Protocol::{IpForward,
IpMulticastForward,LocalDeliver,RouteInputError}.

Introducing Traffic Control Layer
*********************************

The layer is responsible to take actions to schedule or filter the traffic for
both INPUT and OUTPUT directions (called also RX and TX). To interact
with the IP layer and the NetDevice layer, we edited in the following manner
the IPv{4,6}Interface and IPv{4,6}L3Protocol.

Transmitting packets
====================

The IPv{4,6} interfaces uses the aggregated object TrafficControlLayer to send
down packets, instead of calling NetDevice::Send() directly. After the analysis
and the process of the packet, when the backpressure mechanism allows it,
TrafficControlLayer will call the Send() method on the right NetDevice.

Receiving packets
=================

The callback chain that (in the past) involved IPv{4,6}L3Protocol and NetDevices,
through ReceiveCallback, is extended to involve TrafficControlLayer. When an
IPv{4,6}Interface is added in the IPv{4,6}L3Protocol, the callback chain is
configured to have the following packet exchange:

NetDevice --> Node --> TrafficControlLayer --> IPv{4,6}L3Protocol
7 changes: 7 additions & 0 deletions src/traffic-control/examples/wscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-

def build(bld):
pass
# obj = bld.create_ns3_program('traffic-control-example', ['traffic-control'])
# obj.source = 'traffic-control-example.cc'

116 changes: 116 additions & 0 deletions src/traffic-control/model/traffic-control-layer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2015 Natale Patriciello <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "traffic-control-layer.h"
#include "ns3/log.h"
#include "ns3/packet.h"

namespace ns3 {

NS_LOG_COMPONENT_DEFINE ("TrafficControlLayer");

NS_OBJECT_ENSURE_REGISTERED (TrafficControlLayer);

TypeId
TrafficControlLayer::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TrafficControlLayer")
.SetParent<Object> ()
.SetGroupName ("TrafficControl")
.AddConstructor<TrafficControlLayer> ()
;
return tid;
}

TypeId
TrafficControlLayer::GetInstanceTypeId (void) const
{
return GetTypeId ();
}

TrafficControlLayer::TrafficControlLayer ()
: Object ()
{
NS_LOG_FUNCTION_NOARGS ();
}

void
TrafficControlLayer::RegisterProtocolHandler (Node::ProtocolHandler handler,
uint16_t protocolType, Ptr<NetDevice> device)
{
NS_LOG_FUNCTION (this << protocolType << device);

struct Node::ProtocolHandlerEntry entry;
entry.handler = handler;
entry.protocol = protocolType;
entry.device = device;
entry.promiscuous = false;

m_handlers.push_back (entry);

NS_LOG_DEBUG ("Handler for NetDevice: " << device << " registered for protocol " <<
protocolType << ".");
}

void
TrafficControlLayer::Receive (Ptr<NetDevice> device, Ptr<const Packet> p,
uint16_t protocol, const Address &from, const Address &to,
NetDevice::PacketType packetType)
{
NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);

bool found = false;

for (Node::ProtocolHandlerList::iterator i = m_handlers.begin ();
i != m_handlers.end (); i++)
{
if (i->device == 0
|| (i->device != 0 && i->device == device))
{
if (i->protocol == 0
|| i->protocol == protocol)
{
NS_LOG_DEBUG ("Found handler for packet " << p << ", protocol " <<
protocol << " and NetDevice " << device <<
". Send packet up");
i->handler (device, p, protocol, from, to, packetType);
found = true;
}
}
}

if (! found)
{
NS_FATAL_ERROR ("Handler for protocol " << p << " and device " << device <<
" not found. It isn't forwarded up; it dies here.");
}
}

void
TrafficControlLayer::Send (Ptr<NetDevice> device, Ptr<Packet> packet,
const Address &dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (this << device << packet << dest << protocolNumber);

NS_LOG_DEBUG ("Send packet to device " << device << " protocol number " <<
protocolNumber);

device->Send (packet, dest, protocolNumber);
}

} // namespace ns3
Loading