docs: New example on how to use custom strategy with 2-bottleneck topology
diff --git a/docs/source/_static/code-samples/custom-strategy.cc b/docs/source/_static/code-samples/custom-strategy.cc
deleted file mode 100644
index 3b1cea1..0000000
--- a/docs/source/_static/code-samples/custom-strategy.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-// custom-strategy.cc
-
-#include "custom-strategy.h"
-#include "ns3/ndn-fib.h"
-#include "ns3/ndn-fib-entry.h"
-#include "ns3/ndn-pit-entry.h"
-#include "ns3/ndn-interest.h"
-
-namespace ns3 {
-namespace ndn {
-namespace fw {
-
-NS_OBJECT_ENSURE_REGISTERED(CustomStrategy);
-
-LogComponent CustomStrategy::g_log = LogComponent (CustomStrategy::GetLogName ().c_str ());
-
-std::string
-CustomStrategy::GetLogName ()
-{
- return "ndn.fw.CustomStrategy";
-}
-
-TypeId
-CustomStrategy::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::ndn::fw::CustomStrategy")
- .SetGroupName ("Ndn")
- .SetParent <BaseStrategy> ()
- .AddConstructor <CustomStrategy> ()
-
- // .AddAttribute ("Attribute", "Attribute spec",
- // StringValue ("DefaultValue"),
- // MakeStringAccessor (&BaseStrategy::m_variable),
- // MakeStringChecker ())
- ;
- return tid;
-}
-
-CustomStrategy::CustomStrategy ()
- : m_counter (0)
-{
-}
-
-bool
-CustomStrategy::DoPropagateInterest (Ptr<Face> inFace,
- Ptr<const InterestHeader> header,
- Ptr<const Packet> origPacket,
- Ptr<pit::Entry> pitEntry)
-{
- typedef fib::FaceMetricContainer::type::index<fib::i_metric>::type FacesByMetric;
- FacesByMetric &faces = pitEntry->GetFibEntry ()->m_faces.get<fib::i_metric> ();
- FacesByMetric::iterator faceIterator = faces.begin ();
-
- int propagatedCount = 0;
-
- // forward to best-metric face
- if (faceIterator != faces.end ())
- {
- if (TrySendOutInterest (inFace, faceIterator->m_face, header, origPacket, pitEntry))
- propagatedCount ++;
-
- faceIterator ++;
- }
-
- // forward to second-best-metric face
- if (faceIterator != faces.end ())
- {
- if (TrySendOutInterest (inFace, faceIterator->m_face, header, origPacket, pitEntry))
- propagatedCount ++;
-
- faceIterator ++;
- }
- return propagatedCount > 0;
-}
-
-void
-CustomStrategy::DidSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<const Packet> origPacket,
- Ptr<pit::Entry> pitEntry)
-{
- m_counter ++;
-}
-
-void
-CustomStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
-{
- for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
- face != pitEntry->GetOutgoing ().end ();
- face ++)
- {
- m_counter --;
- }
-
- BaseStrategy::WillEraseTimedOutPendingInterest (pitEntry);
-}
-
-
-void
-CustomStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
- Ptr<pit::Entry> pitEntry)
-{
- for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
- face != pitEntry->GetOutgoing ().end ();
- face ++)
- {
- m_counter --;
- }
-
- BaseStrategy::WillSatisfyPendingInterest (inFace, pitEntry);
-}
-
-
-} // namespace fw
-} // namespace ndn
-} // namespace ns3
diff --git a/docs/source/_static/code-samples/custom-strategy.h b/docs/source/_static/code-samples/custom-strategy.h
deleted file mode 100644
index 4a4476d..0000000
--- a/docs/source/_static/code-samples/custom-strategy.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-
-// custom-strategy.h
-
-#ifndef CUSTOM_STRATEGY_H
-#define CUSTOM_STRATEGY_H
-
-#include "ns3/log.h"
-#include "ns3/ndn-forwarding-strategy.h"
-#include "ns3/ndn-l3-protocol.h"
-
-namespace ns3 {
-namespace ndn {
-namespace fw {
-
-typedef ForwardingStrategy BaseStrategy;
-
-class CustomStrategy:
- public BaseStrategy
-{
-public:
- static TypeId
- GetTypeId ();
-
- static std::string
- GetLogName ();
-
- CustomStrategy ();
-
-protected:
- virtual bool
- DoPropagateInterest (Ptr<Face> incomingFace,
- Ptr<const InterestHeader> header,
- Ptr<const Packet> origPacket,
- Ptr<pit::Entry> pitEntry);
-
-public:
- virtual void
- DidSendOutInterest (Ptr<Face> outFace,
- Ptr<const InterestHeader> header,
- Ptr<const Packet> origPacket,
- Ptr<pit::Entry> pitEntry);
-
- virtual void
- WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);
-
- virtual void
- WillSatisfyPendingInterest (Ptr<Face> inFace,
- Ptr<pit::Entry> pitEntry);
-
-protected:
- static LogComponent g_log;
-
-// private:
-// std::string m_variable;
-
-private:
- uint32_t m_counter;
-};
-
-
-
-} // namespace fw
-} // namespace ndn
-} // namespace ns3
-
-#endif // CUSTOM_STRATEGY_H
diff --git a/docs/source/examples.rst b/docs/source/examples.rst
index c1161d3..ddb4b26 100644
--- a/docs/source/examples.rst
+++ b/docs/source/examples.rst
@@ -105,6 +105,7 @@
.. literalinclude:: ../../examples/topologies/topo-grid-3x3.txt
:language: bash
:linenos:
+ :lines: 1-2,19-
:emphasize-lines: 8,24
@@ -175,6 +176,7 @@
.. literalinclude:: ../../examples/topologies/topo-6-node.txt
:language: bash
:linenos:
+ :lines: 1-2,15-
:emphasize-lines: 3,13
.. literalinclude:: ../../examples/ndn-congestion-topo-plugin.cc
@@ -184,3 +186,72 @@
:emphasize-lines: 15,21-22,29-34,41-47,52-62
.. :lines: 20-25,53-
+
+To run this scenario and see what is happening, use the following command::
+
+ NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-topo-plugin
+
+.. _11-node 2-bottleneck topology with custom forwarding strategy:
+
+11-node 2-bottleneck topology with custom forwarding strategy
+-------------------------------------------------------------
+
+To effectively use the example :ref:`custom strategy <Writing your own custom strategy>`, we need to make sure that FIB entries contain at least two entries.
+In the current version of ndnSIM, this can be accomplished using manual route configuration.
+
+The following example illustrates how the strategy can be used in simulation scenario.
+
+Let us first define a meaningful topology:
+
+.. aafig::
+ :aspect: 60
+ :scale: 120
+
+ /------\ 0 0 /------\
+ | c1 |<-----+ +----->| p1 |
+ \------/ \ / \------/
+ \ /-----\ /
+ /------\ 0 \ +==>| r12 |<==+ / 0 /------\
+ | c2 |<--+ \ / \-----/ \ / +-->| p2 |
+ \------/ \ \ | | / / \------/
+ \ | | 1Mbps links | | /
+ \ 1 v0 v5 1v 2v 3 /
+ +->/------\ /------\<-+
+ 2| r1 |<===============>| r2 |4
+ +->\------/4 0\------/<-+
+ / 3^ ^5 \
+ / | | \
+ /------\ 0 / / \ \ 0 /------\
+ | c3 |<--+ / \ +-->| p3 |
+ \------/ / \ \------/
+ / "All consumer-router and" \
+ /------\ 0 / "router-producer links are" \ 0 /------\
+ | c4 |<-----+ "10Mbps" +---->| p4 |
+ \------/ \------/
+
+ "Numbers near nodes denote face IDs. Face ID is assigned based on the order of link"
+ "definitions in the topology file"
+
+The corresponding topology file (``topo-11-node-two-bottlenecks.txt``):
+
+.. literalinclude:: ../../examples/topologies/topo-11-node-two-bottlenecks.txt
+ :language: bash
+ :linenos:
+ :lines: 1-2,28-
+
+Example simulation (``ndn-congestion-alt-topo-plugin.cc``) scenario that utilizes CustomStrategy forwarding strategy:
+
+.. literalinclude:: ../../examples/ndn-congestion-alt-topo-plugin.cc
+ :language: c++
+ :linenos:
+ :lines: 21-28,61-
+ :emphasize-lines: 16,21,49-50,65-79
+
+
+To run this scenario and see what is happening, use the following command::
+
+ NS_LOG=ndn.Consumer:ndn.Producer ./waf --run=ndn-congestion-alt-topo-plugin
+
+You can also run using visualizer module to verify that both bottleneck links are utilized::
+
+ ./waf --run=ndn-congestion-alt-topo-plugin --visualize
diff --git a/docs/source/fw.rst b/docs/source/fw.rst
index 21e3531..dd4176b 100644
--- a/docs/source/fw.rst
+++ b/docs/source/fw.rst
@@ -6,6 +6,8 @@
A new forwarding strategy can be implement completely different processing or override just specific actions/events of the :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`.
Please refer to :ndnsim:`API documentation <ndn::ForwardingStrategy>` of the forwarding strategy interface, which lists all default actions/events.
+.. _Writing your own custom strategy:
+
Writing your own custom strategy
++++++++++++++++++++++++++++++++
@@ -14,15 +16,16 @@
The follwoing are template strategy h/cc files:
-.. literalinclude:: _static/code-samples/custom-strategy.h
+.. literalinclude:: ../../examples/custom-strategies/custom-strategy.h
:language: c++
:linenos:
:lines: 1-36,51-55,59-
-.. literalinclude:: _static/code-samples/custom-strategy.cc
+.. literalinclude:: ../../examples/custom-strategies/custom-strategy.cc
:language: c++
:linenos:
:lines: 1-40,42-50,75-76,115-
+ :emphasize-lines: 21,27
After having the template, we can fill the necesasry functionality.
@@ -30,7 +33,7 @@
That is, if node has two or more alternative paths to forward the Interests, this Interest will be forwarded to the best two neighbors.
The following implementation of CustomStrategy::DoPropagateInterest accomplishes the task:
-.. literalinclude:: _static/code-samples/custom-strategy.cc
+.. literalinclude:: ../../examples/custom-strategies/custom-strategy.cc
:language: c++
:linenos:
:lines: 45-75
@@ -54,12 +57,19 @@
The highlighted ares of the following code demonstrates how it can be impelmented:
-.. literalinclude:: _static/code-samples/custom-strategy.h
+.. literalinclude:: ../../examples/custom-strategies/custom-strategy.h
:language: c++
:linenos:
:emphasize-lines: 37-50,56-58
-.. literalinclude:: _static/code-samples/custom-strategy.cc
+.. literalinclude:: ../../examples/custom-strategies/custom-strategy.cc
:language: c++
:linenos:
- :emphasize-lines: 41,51-74,77-114
+ :emphasize-lines: 41,77-114
+
+
+Example of using custom strategy
+++++++++++++++++++++++++++++++++
+
+Please refer to :ref:`this example <11-node 2-bottleneck topology with custom forwarding strategy>`.
+