[Ns-developers] ns-3-nsc sysctl attribute support

Mathieu Lacage mathieu.lacage at sophia.inria.fr
Mon Jul 7 09:41:07 PDT 2008


hi florian,

On Mon, 2008-07-07 at 17:23 +0200, Florian Westphal wrote:
> Hello ns-3 developers,
> 
> I've added a /sbin/sysctl like interface to NSC. It allows to change and
> query an existing sysctl value while only using strings:
> 
> int sysctl_set(const char *name, const char *value);
> int sysctl_get(const char *name, char *value, size_t len);
> 
> To retrieve a list of available sysctls, this method was added:
> 
> int sysctl_getnum(size_t idx, char *name, size_t len);
> 
> It will return -1 if the given index is out of range, so one can
> iterate through the list, e.g.:
>  char buf[256]
>  for (i=0; sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i++)
>     puts(buf);

ok. I would have expected to be able to query for the number of sysctls
but, I suspect that this kind of API aligns with kernel-API style,
right ?


> Internally, the nsc stack cradle glue has a list of all known sysctl
> values (patch http://git.breakpoint.cc/cgi-bin/gitweb.cgi?p=fw/nsc-fw.git;a=commitdiff;h=2f4fb096e18b78919edebff34adeeccb9de7d0de),
> and the new code is merely a 'front-end' to the existing nsc sysctl-interface (i.e. the stacks sysctl(2) system call).
> 
> The advantage is that we avoid hooking into (most likely volatile) stack code. Also, this should be easy
> to maintain since we'd only need to update the internal sysctl table.
> On the other hand, its not yet clear if this interface is sufficient to support attributes
> on the ns-3 side of things. My initial idea was to build an attribute tree when the stack
> is being initialized (the following patch doesn't work at all, i'm quoting it because
> it might be easier to follow what i tried to do from actual code than explanations):

Ok. Clearly, the code you showed below won't work, mostly because
mutating the TypeId of an object after it was created does not work
unless you override ObjectBase::GetInstanceTypeId, and even if you do
this, it is not trivial to get it right mostly because the ns3 object
system was never designed to allow mutating object types.

[code elided]

Here is an untested but potentially working solution.

First, we need an attribute accessor which can remember the name of the
attribute it is accessing to pass it down to Nsc:

class NscStackStringAccessor : public AttributeAccessor
{
public:
  NscStackStringAccessor (std::string name) : m_name (name) {}

  virtual bool Set (ObjectBase * object, const AttributeValue & val)
const {
    const StringValue *value = dynamic_cast<const StringValue *> (&val);
    if (value == 0)
      {
        return false;
      }
    NscNscStack *obj = dynamic_cast<Ns3NscStack *> (object);
    if (obj == 0)
      {
        return false;
      }
    obj->Set (m_name, value->Get ());
  }
  virtual bool Get (const ObjectBase * object, AttributeValue &val)
const {
    const StringValue *value = dynamic_cast<const StringValue *> (&val);
    if (value == 0)
      {
        return false;
      }
    NscNscStack *obj = dynamic_cast<Ns3NscStack *> (object);
    if (obj == 0)
      {
        return false;
      }
    value->Set (obj->Get (m_name));
  }
  virtual bool HasGetter (void) const {
    return true;
  }
  virtual bool HasSetter (void) const {
    return true;
  }
};

Then, you need an object which represents the underlying nsc stack,
which is aggregated to a Node object, and which provides access to the
sysctls of the nsc stack through attributes.

class Ns3NscStack : public Object
{
public:
  TypeId GetTypeId (void);
  virtual TypeId GetInstanceTypeId (void);

  void SetStack (INetStack *stack) {m_stack = stack;}

private:
  class friend NscStackStringAccessor;
  void Set (std::string name, std::string value) {m_stack->sysctl_set
(name, value);}
  std::string Get (std::string name) const {m_stack->sysctl_get
(name, ...);}

  INetStack m_stack;
};

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

TypeId 
Ns3NscStack::GetInstanceTypeId (void)
{
  if (m_stack == 0)
    {
      // if we have no stack, we are a normal NscStack without any
attributes.
      return GetTypeId ();
    }
  std::string name = "ns3::Ns3NscStack<" + m_stack->get_name () + ">";
  TypeId tid;
  if (TypeId::LookupByNameFailSafe (name, &tid))
    {
      // if the relevant TypeId has already been registered, no need to
do it again.
      return tid;
    }
  else
    {
      // Now, we register a new TypeId for this stack which will look
like a subclass of the Ns3NscStack. The class Ns3NscStack is effectively
mutating into a subclass of itself from the point of view of the TypeId
system _here_
      tid = TypeId (name);
      tid.SetParent<Ns3NscStack> ();
      char buf[256]
      for (int i=0; m_stack->sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i
++)
        {
          char value[256];
          m_stack->sysctl_get (name, value);
          tid.AddAttribute (name, "Help text", 
                            StringValue (value),
                            Create<NscStackStringAccessor> (name),
                            MakeStringChecker ());
        }
      return tid;
    }
}


> To avoid ending this mail in a too depressing manner: the Linux 2.6.26 port is now able to
> run SCTP again. Now, how should that be integrated in ns-3?

cool.

> 
> Its easy to turn nsc-tcp into an nsc-sctp by changing
> -const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
> +const uint8_t NscTcpL4Protocol::PROT_NUMBER = 132;
> in nsc-tcp-l4-protocol.cc
> 
> and
> -  m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket();
> +  m_nscTcpSocket = tcp->m_nscStack->new_sctp_socket();
> in nsc-tcp-socket-impl.cc.
> 
> My suggestion would be to first separate nsc-tcp and the nsc stack initialization
> (i.e. try to put all the stack initialization and tcp unrelated things into a different file)

sounds good.

> and then see about how the socket side of things can be done (I'd like to avoid copying the code,
> maybe it would be best to add a nsc-socket-impl.cc and then have nsc-{tcp,sctp}-socket-impl.cc
> delegate most of the work to it...)

sounds good. 

regards,
Mathieu



More information about the Ns-developers mailing list