-
Notifications
You must be signed in to change notification settings - Fork 6
Examples
The source directory src/ccnx/examples contains all the working examples of using the CCNx module in NS3 scripts. Some of the examples are part of the ccns3Sim.git repository and some are in the ccns3Examples.git repository.
The related github project link:/PARC/ccns3Examples/wiki[ccns3Examples] has numerous examples of working with the code such as:
- incorporating new PIT, FIB, or Content Stores
- Using different routing protocols
- topology examples
Currently, we do not support the NS3 python bindings. It is not due to a lack of desire, just a lack of time!
- ccnx-simple
- ccnx-2node
- ccnx-2node-withperhopheaders
- ccnx-4node
- ccnx-6node
- ccnx-consumer-producer
- ccnx-content-store
- ccnx-csma-consumer-producer
- ccnx-csma-simple
- ccnx-layer-delays
- ccnx-lossy-link
- ccnx-multi-prefix-producer-consumer
- ccnx-nfp-routing
- ccnx-nfp-routing-12node
- ccnx-tracing
This is a 1-node example. A sink creates a CCNxPortal and calls RegsiterPrefix() to put a FIB entry for its name in the local forwarder. A source application creates its own CCNxPortal and sends several CCNxInterest messages to the sink. No ContentObjects are returned.
Same as ccnx-simple, except there are two nodes connected with an ns3::PointToPoint network connection. We use static routing from the source to the sink.
Uses a point-to-point topology. Sink will RegisterPrefix() on n0 which creates a route from n0 to the sink Portal. We add a static route on node n1 -> n0 for ccnx:/name=foo/name=sink.
sink source
| |
n0 ------ n1
5Mbps
2ms
The example shows how to use the normal NS3 PointToPointHelper to create links:
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
CCNxStackHelper ccnx;
ccnx.Install (nodes);
ccnx.AddInterfaces (devices);The important thing in this example is it shows how to add a static route from n1 to n0 so the Interest from the source to the sink can flow. Lines 20 and 25 retrieve the network interface device from nodes 0 and 1. Using these devices, we can add a neighbor in line 40 from n1 to n0. Line 40 adds the MAC address of n0's network interface as a neighbor on n1's device node1If0. Once we have the CCNxConnectionDevice object, we can use that to add a route on n1 via that connection in line 50.
This calling structure is cumbersome and requires too much manual work on the programmer's part. We will be adding a StaticRouteHelper to fix this problem.
10 Ptr<Node> node0 = nodes.Get (0);
15 Ptr<Node> node1 = nodes.Get (1);
20 Ptr<NetDevice> node0If0 = node0->GetDevice (0);
25 Ptr<NetDevice> node1If0 = node1->GetDevice (0);
30
35 Ptr<CCNxL3Protocol> node1_ccnx = node1->GetObject<CCNxL3Protocol> ();
40 Ptr<CCNxConnectionDevice> node1ToNode0Connection = node1_ccnx->AddNeighbor (node0If0->GetAddress (), node1If0);
45 Ptr<CCNxName> prefixName = Create<CCNxName> (prefixString);
50 node1_ccnx->GetForwarder ()->AddRoute (node1ToNode0Connection, prefixName);This example is essentially identical to ccnx-2node, but includes two per-hop TLV header in the Interest message.
static Ptr<CCNxPacket>
CreatePacket (uint32_t size, Ptr<CCNxName> name, CCNxMessage::MessageType msgType)
{
Ptr<CCNxBuffer> payload = Create<CCNxBuffer> (size, true);
Ptr<CCNxPacket> packet;
switch (msgType)
{
// omit ContentObject case
case CCNxMessage::Interest:
{
Ptr<CCNxInterest> interest = Create<CCNxInterest> (name, payload);
packet = CCNxPacket::CreateFromMessage (interest);
// Add per hop header entry
Ptr<CCNxInterestLifetime> interestLifetime = Create<CCNxInterestLifetime> (Create<CCNxTime>(3600));
packet->AddPerHopHeaderEntry(interestLifetime);
Ptr<CCNxCachetime> cachetime = Create<CCNxCachetime> (Create<CCNxTime>(3600));
packet->AddPerHopHeaderEntry(cachetime);
break;
}
// omit default case
}
return packet;
}
This is a https://github.com/PARC/ccns3Sim/blob/wiki/wikidocs/3node-topo.png[4 node topology], with multiple producers and a single consumer. The idea was to show how interests can be load balanced with the consumer not being affected. In this example both N0 and N1 are hosting producers with the same prefix. And consumer at n3 is requesting random interests with the prefix that can be served by either n0 or n1.
n0
\ 5 Mb/s, 2ms
\ 1.5Mb/s, 10ms
n2 -------------------------n3
/
/ 5 Mb/s, 2ms
n1
- We should expect the number of interests expressed should match with the content objects responses.
- Bad Packets implies that we could not decode it the content received was interest/content.
- Missing Interests implies we have some outstanding interests for whom content reception was timed out.
Consumer Interest Content Missing Bad Prefix
Node Id : Sent :Received :Interests :Packets :Name
3 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
3 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
Producer Interest Content Missing Bad Prefix
Node Id : Received : Sent :Content :Packets :Name
0 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
1 1935 1935 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
0 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
1 1935 1935 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
This is a https://github.com/PARC/ccns3Sim/blob/wiki/wikidocs/6node-topo.png[6 node topology] , with multiple producers (on n0 and n1) and a multiple consumers (n4 and n5). The idea here is to show how interests can get aggregated at n3 resulting in fewer interest requests forwarded to n2.
n0 n4
\ 5 Mb/s, 2ms /
\ 1.5Mb/s, 10ms /
n2 -------------------------n3
/ \
/ 5 Mb/s, 2ms \
n1 n5
- Upon building and executing this example the o/p to be expected is as follows. The number of interests sent and received by consumers on nodes 4 and 5 should match. In this example there are 2 sets of prefixes that interests are expressed for.
At the producer end, there will be multiple producers responding back to the interest from consumer.This is because node2 is forwarding the interests to both node0 and node1. When content objects arrive from both node0 and node1 at node3 only one of them will consume the PIT entry, discarding the content object that arrived later.
- Bad Packets implies that we could not decode it the content received was interest/content.
- Missing Content implies we have received an interest which cannot be served by the producer.
Consumer Interest Content Missing Bad Prefix
Node Id : Sent :Received :Interests :Packets :Name
4 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
5 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
4 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
5 1939 1939 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
Producer Interest Content Missing Bad Prefix
Node Id : Received : Sent :Content :Packets : Name
0 3687 3687 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
1 3679 3679 0 0 lci:/NAME=simple/NAME=producer/NAME=size64count10
0 3769 3769 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
1 3761 3761 0 0 lci:/NAME=simple/NAME=producer/NAME=size128count20
This is the same as the ccnx-2node example, except we install the CCNxConsumer and CCNxProducer applications on the source and sink. It also uses the NfpRoutingHelper for dynamic routing instead of the cumbersome method of adding static routes.
NfpRoutingHelper nfpHelper;
nfpHelper.Set ("HelloInterval", TimeValue (Seconds (5)));
ccnxStack.SetRoutingHelper (nfpHelper);The consumer/producer applications use a CCNxContentRepository to represent the ContentObject corpus of the example.
Ptr <const CCNxName> prefix = Create <CCNxName> ("ccnx:/name=ccnx/name=consumer/name=producer");
uint32_t size = 124;
uint32_t count = 1000;
Ptr <CCNxContentRepository> globalContentRepository = Create <CCNxContentRepository> (prefix,size,count);The repository is then serviced by one Producer app that will start immediately. Notice that we use the normal NS3 Application idiom, so applications are configured and created via a Helper and you can then set start and stop times on the application.
CCNxProducerHelper producerHelper (globalContentRepository);
ApplicationContainer producerApps = producerHelper.Install (nodes.Get (0));
producerApps.Start (Seconds (0.0));
producerApps.Stop (Seconds (13.0));The consumer app follows the same coding style. It is also created via a reference to the repository because it uses the repository to generate the names it uses in Interest messages.
CCNxConsumerHelper consumerHelper (globalContentRepository);
consumerHelper.SetAttribute ("RequestInterval", TimeValue (MilliSeconds (5)));
ApplicationContainer consumerApps = consumerHelper.Install (nodes.Get (1));
consumerApps.Start (Seconds (2.0));
consumerApps.Stop (Seconds (12.0));This is the same as the ccnx-consumer-producer example, except we enable the Content Store in the CCNx forwarder. The default behavior of CCNxStandardForwarder is to not enable the ContentStore.
The CCNxStandardContentStoreFactory uses the normal NS3 ns3::ObjectFactory mechanisms we can set parameters with the normal NS3 Attribute system. In this case, we can set the ObjectCapacity to be 10,000 ContentObjects. All ContentStores created from this factory will have that capacity. By installing the ContentStoreFactory in a forwarder, it enables the forwarder helper to call the factory for each forwarder it will create.
CCNxStandardForwarderHelper standardHelper;
CCNxStandardContentStoreFactory contentStoreFactory;
contentStoreFactory.Set("ObjectCapacity", IntegerValue(10000));
standardHelper.SetContentStoreFactory(contentStoreFactory);
CCNxStackHelper ccnxStack;
ccnxStack.SetForwardingHelper (standardHelper);This is the same as the ccnx-consumer-producer example, except we use a CSMA (Ethernet) network instead of point-to-point links:
CsmaHelper etherNet;
etherNet.SetChannelAttribute ("DataRate", DataRateValue (DataRate (1000000000)));
etherNet.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
etherNet.SetDeviceAttribute ("Mtu", UintegerValue (1500));
NetDeviceContainer devices = etherNet.Install (nodes);
// ... skip ...
ccnxStack.AddInterfaces (devices);The same as ccnx-2node, except we use a CSMA (Ethernet) link and enable PCAP tracing. This uses the normal NS3 pcap facility to dump the traffic to the named file ccnx-csma-broadcast-<nodeid>-<interfaceid>.pcap. You can then view the pcap files, for example, using tcpdump -tt -r.
CsmaHelper etherNet;
etherNet.SetChannelAttribute ("DataRate", DataRateValue (DataRate (1000000000)));
etherNet.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
etherNet.SetDeviceAttribute ("Mtu", UintegerValue (1500));
NetDeviceContainer devices = etherNet.Install (nodes);
// ... skip ...
ccnxStack.AddInterfaces (devices);
// ... skip ...
etherNet.EnablePcapAll ("ccnx-csma-broadcast", false);If you would prefer to see an ASCII packet dump, one could use the normal NS3 calls:
AsciiTraceHelper ascii;
etherNet.EnableAsciiAll (ascii.CreateFileStream ("ccnx-csma-1bcast.tr"));The same as ccnx-consumer-producer, except we introduce processing delays. See [ThePaper] for a detailed description of the delay model. We will add the following delays:
- forwarder: 10 usec + 1 usec/byte, up to 2 parallel forwarding operations
- PIT: 10 usec + 3 usec/name_bytes, up to 4 parallel lookups
- FIB: 8 usec + 7 usec/name_bytes, up to 2 parallel looksup
We do this by explicitly creating a PIT factory and FIB factory with the layer delay attributes set, then pass those to the CCNxForwarderHelper so it will create PIT and FIB tables with those attributes.
CCNxStandardForwarderHelper forwarderHelper;
forwarderHelper.SetLayerDelayConstant (MicroSeconds (10));
forwarderHelper.SetLayerDelaySlope (NanoSeconds (1));
forwarderHelper.SetLayerDelayServers (2);
CCNxStandardPitFactory pitFactory;
pitFactory.SetLayerDelayConstant (MicroSeconds (10));
pitFactory.SetLayerDelaySlope (NanoSeconds (3));
pitFactory.SetLayerDelayServers (4);
forwarderHelper.SetPitFactory (pitFactory);
CCNxStandardFibFactory fibFactory;
fibFactory.SetLayerDelayConstant (MicroSeconds (8));
fibFactory.SetLayerDelaySlope (NanoSeconds (7));
fibFactory.SetLayerDelayServers (2);
forwarderHelper.SetFibFactory (fibFactory);
ccnxStack.SetForwardingHelper (forwarderHelper);This example also hows how to print periodic statistics. In this case, we dump the forwarding table statistics every 5 seconds:
Ptr<OutputStreamWrapper> trace = Create<OutputStreamWrapper> (&std::cout);
forwarderHelper.PrintForwardingStatisticsAllNodesWithInterval(Seconds(5), trace);A small topology that illustrates how to use the NfpRouting protocol.
A small topology that illustrates how to use the NfpRouting protocol.
Uses a point-to-point topology. Sink is on n0, source is n10 for ccnx:/name=foo/name=sink.
-----------n11
| |
n4 -- n5 -- n6 --- n7 \ |
| | | x | n9 -- n10
n0 ----------- n1 n2 n3 --- n8 /
5Mbps | | |
2ms |------ LAN -----|
100 Mbps / 1 usec
Copyright (c) 2016, Xerox Corporation (Xerox) and Palo Alto Research Center (PARC). All rights reserved.