[Click] Click defines in ns3

Sascha Alexander Jopen jopen at informatik.uni-bonn.de
Sat Jan 26 14:28:17 EST 2013


Hi,

this is another version of the click defines for ns3 patchset. It makes
use of simclick_sim_command to fetch the defines from ns3 at click
router instantiation time. This way ns2 or older ns3 variants are not
affected, they only do not provide defines.

This patchset is to be applied on top of the rng support patchset.
Please  review this one for inclusion into click and ns3.

Sascha

On 23.01.2013 17:36, Sascha Alexander Jopen wrote:
> Hey,
> 
> with the current implementation on the ns3 side, using
> simclick_click_command is only possible after an instance of the click
> router has been created (Ipv4ClickRouting::DoStart ()). However, we
> already need the defines at this time to instantiate the router.
> I'll try to rearrange this and implement defines the way you suggested,
> keeping the API stable.
> 
> Sascha
> 
> On 23.01.2013 16:46, Eddie Kohler wrote:
>> Hey,
>>
>> I'm always bummed out by API changes that require people to keep two
>> packages precisely up to date and will therefore request some changes.
>>
>> (1) Add a new SIMCLICK comamnd constant, SIMCLICK_DEFINE or
>> SIMCLICK_CREATE_DEFINE, your choice.
>> (2) Change simclick_click_command so that SIMCLICK_SUPPORTS reports
>> true for SIMCLICK_DEFINE
>> (3) Implement definition support via SIMCLICK_DEFINE, which will
>> require changes to click and to ns.
>>
>> Make sense?
>> Eddie
>>
>>
>> On Wed, Jan 23, 2013 at 6:56 AM, Sascha Alexander Jopen
>> <jopen at informatik.uni-bonn.de> wrote:
>>> Hi,
>>>
>>> i think this has nothing to do with the Click defines patchset. Please
>>> use a new thread for your questions.
>>>
>>> How packet processing is done in your application depends on the type
>>> and format of your packets. There are standard elements in click to deal
>>> with Ethernet or IP packets, for example. See
>>> http://read.cs.ucla.edu/click/elements
>>> For processing of application layer data, you have to write your own
>>> elements. See http://www.read.cs.ucla.edu/gitweb?p=click;a=blob;f=FAQ
>>> and http://www.read.cs.ucla.edu/click/learning
>>>
>>> Regards,
>>> Sascha
>>>
>>> On 23.01.2013 11:46, karthick m wrote:
>>>> Hi sascha,
>>>>
>>>>             I am implementing my own publish subscribe architecture using
>>>> click router. For that i need to work on packets. Say a publisher is
>>>> sending a publish packet, i have to see the packet data and process packet
>>>> according to the data and route it.  The problem is that, i do not find any
>>>> element which does packet processing for example. Could you please give me
>>>> a pointer to it. Thanks in advance.
>>>>
>>>
>>>
>>> --
>>> Dipl.-Inform. Sascha Jopen
>>>
>>> University of Bonn                     Tel.:   +49-228-73-54219
>>> Institute of Computer Science 4        Fax:    +49-228-73-4571
>>> Friedrich-Ebert-Allee 144              E-mail: jopen at cs.uni-bonn.de
>>> D-53113 Bonn, Germany
>>> _______________________________________________
>>> click mailing list
>>> click at amsterdam.lcs.mit.edu
>>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
> 
> 


-- 
Dipl.-Inform. Sascha Jopen

University of Bonn                     Tel.:   +49-228-73-54219
Institute of Computer Science 4        Fax:    +49-228-73-4571
Friedrich-Ebert-Allee 144              E-mail: jopen at cs.uni-bonn.de
D-53113 Bonn, Germany
-------------- next part --------------
diff --git a/include/click/simclick.h b/include/click/simclick.h
index b421641..bc9f4d6 100644
--- a/include/click/simclick.h
+++ b/include/click/simclick.h
@@ -107,6 +107,7 @@ int simclick_gettimeofday(struct timeval* tv);
 #define SIMCLICK_IF_PROMISC		12 // int ifid
 #define SIMCLICK_IPPREFIX_FROM_NAME	13 // const char *ifname, char *buf, int len
 #define SIMCLICK_GET_RANDOM_INT		14 // uint32_t *result, uint32_t max
+#define SIMCLICK_GET_DEFINES		15 // char *buf, size_t *size
 
 int simclick_sim_command(simclick_node_t *sim, int cmd, ...);
 int simclick_click_command(simclick_node_t *sim, int cmd, ...);
diff --git a/ns/nsclick.cc b/ns/nsclick.cc
index 0d682c0..3ebc61c 100644
--- a/ns/nsclick.cc
+++ b/ns/nsclick.cc
@@ -120,6 +120,29 @@ int simclick_click_create(simclick_node_t *simnode, const char* router_file) {
     ErrorHandler *errh = ErrorHandler::default_handler();
     int before = errh->nerrors();
 
+    // Get the defines from the simulator, if supported.
+    if (simclick_sim_command(simnode, SIMCLICK_SUPPORTS, SIMCLICK_GET_DEFINES)) {
+        size_t defines_size = 512;
+        char *defines = (char *) malloc(defines_size);
+        if ((simclick_sim_command(simnode, SIMCLICK_GET_DEFINES, defines, &defines_size) == -1)) {
+            // Our buffer was too small, resize and try again.
+            defines = (char *) realloc(defines, defines_size);
+            simclick_sim_command(simnode, SIMCLICK_GET_DEFINES, defines, &defines_size);
+        }
+
+        // Process defines for click file parsing.
+        size_t defines_offset = 0;
+        while (defines_offset < defines_size) {
+            char *key = defines + defines_offset;
+            char *value = key + strlen(key) + 1;
+            defines_offset += (size_t) (value + strlen(value) + 1 - defines);
+            if (!click_lexer()->global_scope().define(key, value, false)) {
+                errh->error("parameter %s multiply defined", key);
+            }
+        }
+        free(defines);
+    }
+
     Router *r = click_read_router(router_file, false, errh, false);
     simnode->clickinfo = r;
     if (!r)
-------------- next part --------------
diff -r 774f8d9ab488 src/click/examples/nsclick-defines.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/click/examples/nsclick-defines.cc	Sat Jan 26 20:02:30 2013 +0100
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ * Authors: Sascha Jopen <jopen at cs.uni-bonn.de>
+ */
+
+
+#include "ns3/core-module.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/click-internet-stack-helper.h"
+#include <map>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("NsclickRouting");
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create a node.");
+  NodeContainer n;
+  n.Create (1);
+
+//
+// Install Click on the nodes
+//
+  std::map<std::string, std::string> defines;
+// Strings, especially with blanks in it, have to be enclosed in quotation
+// marks, like in click configuration files.
+  defines["OUTPUT"] = "\"Hello World!\"";
+  
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (n, "src/click/examples/nsclick-defines.click");
+  clickinternet.SetRoutingTableElement (n, "rt");
+  clickinternet.SetDefines(n, defines);
+  clickinternet.Install (n);
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds (20.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
diff -r 774f8d9ab488 src/click/examples/nsclick-defines.click
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/click/examples/nsclick-defines.click	Sat Jan 26 20:02:30 2013 +0100
@@ -0,0 +1,9 @@
+define($OUTPUT "This is a default value for OUTPUT");
+define($UNDEFINED "UNDEFINED is an undefined variable");
+
+// It is mandatory to use an IPRouteTable element with ns-3-click
+rt :: LinearIPLookup ();
+Idle -> rt;
+
+output :: Message($OUTPUT);
+undefined :: Message($UNDEFINED);
diff -r 774f8d9ab488 src/click/examples/wscript
--- a/src/click/examples/wscript	Sat Jan 26 15:54:08 2013 +0100
+++ b/src/click/examples/wscript	Sat Jan 26 20:02:30 2013 +0100
@@ -20,3 +20,7 @@
    obj = bld.create_ns3_program('nsclick-routing',
                                 ['click', 'csma', 'internet', 'applications'])
    obj.source = 'nsclick-routing.cc'
+
+   obj = bld.create_ns3_program('nsclick-defines',
+                                ['click'])
+   obj.source = 'nsclick-defines.cc'
diff -r 774f8d9ab488 src/click/helper/click-internet-stack-helper.cc
--- a/src/click/helper/click-internet-stack-helper.cc	Sat Jan 26 15:54:08 2013 +0100
+++ b/src/click/helper/click-internet-stack-helper.cc	Sat Jan 26 20:02:30 2013 +0100
@@ -125,6 +125,21 @@
 }
 
 void
+ClickInternetStackHelper::SetDefines (NodeContainer c, std::map<std::string, std::string> defines)
+{
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+	  SetDefines (*i, defines);
+    }
+}
+
+void
+ClickInternetStackHelper::SetDefines (Ptr<Node> node, std::map<std::string, std::string> defines)
+{
+  m_nodeToDefinesMap.insert (std::make_pair (node, defines));
+}
+
+void
 ClickInternetStackHelper::SetRoutingTableElement (NodeContainer c, std::string rt)
 {
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
@@ -193,6 +208,13 @@
           ipv4Routing->SetClickFile (it->second);
         }
 
+      std::map<Ptr<Node>, std::map<std::string, std::string> >::const_iterator definesIt;
+      definesIt = m_nodeToDefinesMap.find (node);
+      if (definesIt != m_nodeToDefinesMap.end ())
+        {
+          ipv4Routing->SetDefines (definesIt->second);
+        }
+
       it = m_nodeToRoutingTableElementMap.find (node);
       if (it != m_nodeToRoutingTableElementMap.end ())
         {
diff -r 774f8d9ab488 src/click/helper/click-internet-stack-helper.h
--- a/src/click/helper/click-internet-stack-helper.h	Sat Jan 26 15:54:08 2013 +0100
+++ b/src/click/helper/click-internet-stack-helper.h	Sat Jan 26 20:02:30 2013 +0100
@@ -143,6 +143,20 @@
   void SetClickFile (Ptr<Node> node, std::string clickfile);
 
   /**
+   * \brief Set defines to be used for a group of nodes.
+   * \param c NodeContainer of nodes
+   * \param defines Defines mapping to be used
+   */
+  void SetDefines (NodeContainer c, std::map<std::string, std::string> defines);
+
+  /**
+   * \brief Set defines to be used for a node.
+   * \param node Node for which the defines are to be set
+   * \param defines Defines mapping to be used
+   */
+  void SetDefines (Ptr<Node> node, std::map<std::string, std::string> defines);
+
+  /**
    * \brief Set a Click routing table element for a group of nodes.
    * \param c NodeContainer of nodes
    * \param rt Click Routing Table element name
@@ -219,6 +233,11 @@
   std::map < Ptr<Node>, std::string  > m_nodeToClickFileMap;
 
   /**
+   * \brief Node to Click defines mapping
+   */
+  std::map < Ptr<Node>, std::map<std::string, std::string>  > m_nodeToDefinesMap;
+
+  /**
    * \brief Node to Routing Table Element mapping
    */
   std::map < Ptr<Node>, std::string  > m_nodeToRoutingTableElementMap;
diff -r 774f8d9ab488 src/click/model/ipv4-click-routing.cc
--- a/src/click/model/ipv4-click-routing.cc	Sat Jan 26 15:54:08 2013 +0100
+++ b/src/click/model/ipv4-click-routing.cc	Sat Jan 26 20:02:30 2013 +0100
@@ -65,6 +65,10 @@
     m_ipv4 (0)
 {
   m_random = CreateObject<UniformRandomVariable> ();
+  m_simNode = new simclick_node_t;
+  timerclear (&m_simNode->curtime);
+
+  AddSimNodeToClickMapping ();
 }
 
 Ipv4ClickRouting::~Ipv4ClickRouting ()
@@ -83,11 +87,6 @@
       m_nodeName = name.str ();
     }
 
-  m_simNode = new simclick_node_t;
-  timerclear (&m_simNode->curtime);
-
-  AddSimNodeToClickMapping ();
-
   NS_ASSERT (m_clickFile.length () > 0);
 
   // Even though simclick_click_create() will halt programme execution
@@ -138,6 +137,18 @@
 }
 
 void
+Ipv4ClickRouting::SetDefines (std::map<std::string, std::string> defines)
+{
+  m_defines = defines;
+}
+
+std::map<std::string, std::string>
+Ipv4ClickRouting::GetDefines (void)
+{
+  return m_defines;
+}
+
+void
 Ipv4ClickRouting::SetClickRoutingTableElement (std::string name)
 {
   m_clickRoutingTableElement = name;
@@ -614,7 +625,7 @@
     case SIMCLICK_SUPPORTS:
       {
         int othercmd = va_arg (val, int);
-        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_RANDOM_INT);
+        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
         break;
       }
 
@@ -757,6 +768,48 @@
         NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
         break;
       }
+
+    case SIMCLICK_GET_DEFINES:
+      {
+        char *buf = va_arg (val, char *);
+        size_t *size = va_arg (val, size_t *);
+        uint32_t required = 0;
+
+        // Try to fill the buffer with up to size bytes.
+        // If this is not enough space, write the required buffer size into
+        // the size variable and return an error code.
+        // Otherwise return the bytes actually writte into the buffer in size.
+
+        // Append key/value pair, seperated by \0.
+        std::map<std::string, std::string> defines = clickInstance->GetDefines ();
+        std::map<std::string, std::string>::const_iterator it = defines.begin ();
+        while (it != defines.end ())
+          {
+            size_t available = *size - required;
+            if (it->first.length() + it->second.length() + 2 <= available)
+              {
+                simstrlcpy(buf + required, available, it->first);
+                required += it->first.length() + 1;
+                available -= it->first.length() + 1;
+                simstrlcpy(buf + required, available, it->second);
+                required += it->second.length() + 1;
+              }
+            else
+              {
+                required += it->first.length() + it->second.length() + 2;
+              }
+            it++;
+          }
+        if (required > *size)
+          {
+            retval = -1;
+          }
+        else
+          {
+            retval = 0;
+          }
+        *size = required;
+      }
     }
   return retval;
 }
diff -r 774f8d9ab488 src/click/model/ipv4-click-routing.h
--- a/src/click/model/ipv4-click-routing.h	Sat Jan 26 15:54:08 2013 +0100
+++ b/src/click/model/ipv4-click-routing.h	Sat Jan 26 20:02:30 2013 +0100
@@ -79,6 +79,12 @@
   void SetClickFile (std::string clickfile);
 
   /**
+  * \brief Click defines to be used by the node's Click Instance.
+  * \param defines mapping of defines for .click configuration file parsing
+  */
+  void SetDefines (std::map<std::string, std::string> defines);
+
+  /**
    * \brief Name of the node as to be used by Click. Required for Click Dumps.
    * \param name Name to be assigned to the node.
    */
@@ -132,6 +138,12 @@
 
 public:
   /**
+   * \brief Provides for SIMCLICK_GET_DEFINES
+   * \return The defines mapping for .click configuration file parsing
+   */
+  std::map<std::string, std::string> GetDefines (void);
+
+  /**
    * \brief Provides for SIMCLICK_IFID_FROM_NAME
    * \param ifname The name of the interface
    * \return The interface ID which corresponds to ifname
@@ -247,6 +259,7 @@
 
 private:
   std::string m_clickFile;
+  std::map < std::string, std::string > m_defines;
   std::string m_nodeName;
   std::string m_clickRoutingTableElement;
 


More information about the click mailing list