TWiki home TWiki > Simulation > IPv4Suite > IPSuiteLogOfChanges > IPSuiteChangesOld TWiki webs:
Main | TWiki | Know | Sandbox
Simulation . { Changes | Index | Search | Go }

IPSuite Change Log (2003 through March 2004)

Second round: thorough code revision (Feb-March 2004)

IPSuite mainly has to be revised because OMNeT++ has made some progress since the IPSuite was written, and now it can offer much better solutions to some common programming tasks. Msg files got introduced, error handling changed, and we have now more experience how things should (or should not) be done.

The focus is on some generic refactoring first, first in the network layer. Transport layer, apps, and L2 protocols come later. Adding of new features comes last. The original IPSuite was written with a sound architecture and in most places with careful programming, so most changes can be done almost automatically.

ProcessorManager removed

We now know that large-scale simulations can only be programmed using handleMessage(), because activity() just consumes too much memory. (Also, handleMessage() tends to force a clearer programming style and a more careful design.) ProcessorManager had to be removed because it is unsupportable with activity().

Parameter assignments moved from NED to omnetpp.ini.

In omnetpp.ini they are a lot easier to change, e.g. for a set of simulation experiments. The parameters in question were "..._delay" parameters and the ones defining QoS hooks (the latter was redesigned anyway, see following items).

    parameters:
      // processing delay times
      ipoutput_delay = 0.1 us,
      fragmentation_delay = 0.1 us,
      ipsend_delay = 0,
      localdeliver_delay = 0,
      prerouting_delay = 0,
      ...

Confusing and unnecessary parameters killed

Deleted otherwise very popular "nodename" and "nodenr" parameters because they weren't used for any meaningful purpose anywhere (just printed out in ev<<, but fullPath() is just as good for this purpose).

Excessive parameter passing in NED files removed

Some NED parameters were passed from simple module level up several compound module levels. I didn't find an obvious advantage for this parameter passing in many cases, so I removed these assignments (eliminated parameters from higher-level compound modules), and parameters should get values from omnetpp.ini, using wildcards.

Link layer separated from Network Layer

Network interfaces removed from the compound module NetworkLayers, and moved up to node level. MPLS immediately fell in place (between L2 and L3) and MPLS2IP got thrown out.

Also thrown out various flavours of router and host models that were very similar to each other.

Removed "hooks" while preserving QoS functionality

The problem with QoS hooks in the Network layer was that:

  1. All "core" modules (sendCore, localDeliverCore, preRoutingCore, routingCore, ipOutputCore) were implemented with activity(), which is a serious limitation in scalability. It would be good to get rid of all activity() functions in IPSuite
  2. they all used receiveOn() which has been deprecated for a while and got removed in 3.0, together with putAsideQueue they're based on.

When rewritten with handleMessage(), the current logic of "core" modules would result in a complex logic. It had to be simplified.

Decision: QoS hooks should NOT be separate modules at all. They should be just plain classes derived from an abstract base class, and used inside the "core" modules. This could be easily done, and we also kept the ability to select specific QoS behaviors from omnetpp.ini.

Thus, in the IPSuite modules the old "core+hook" compound modules were eliminated and just replaced by the "core" modules which had the "Core" dropped from their names. E.g PreRoutingCore became PreRouting, and the old PreRouting compound module was removed.

To illustrate the solution really briefly: to create a new QoS behavior, one has to subclass from the following class and redefine 2 functions:

/**
 * Abstract base class for enqueue hooks.
 */
class EnqueueHook
{
  public:
    /**
     * Called when a packet arrives and queue is not empty. 
     * Implementation of this function should enqueue the packet -- 
     * or just discard it. It can also do priority queueing or
     * discard other packets already in the queue -- anything.
     */
    virtual void enqueue(cMessage *msg, cQueue& queue) = 0;

    /**
     * Called when a packet arrives and the queue is empty. 
     * Implementation of this function should either return the same 
     * pointer, or drop the packet and return NULL.
     */
    virtual cMessage *dropIfNotNeeded(cMessage *msg) = 0;
};

Non-QoS implementation is just this:

class EnqueueWithoutQoS : public EnqueueHook
{
    void enqueue(cMessage *msg, cQueue& queue) {
        queue.insert(msg);
    }
    cMessage *dropIfNotNeeded(cMessage *msg) {
        return msg;
    }
};
Register_Class(EnqueueWithoutQoS); // needed to make class visible for createOne()

By creating other EnqueueHook subclasses one can probably implement any needed QoS behavior.

Modules that need QoS simply have to be derived from the module class QueueBaseWithQoS. Then it will automatically have a module parameter called "qosBehaviorClass", and QoS will automatically be handled by the base class QueueBaseWithQoS.

simple PreRouting 
  parameters:
     qosBehaviourClass: string;
   ...
endsimple

Via "qosBehaviourClass", QoS behavior can be specified from omnetpp.ini. In the simplest case you have to put this line into omnetpp.ini:

*.qosBehaviorClass = "EnqueueWithoutQoS"

Internally, QueueBaseWithQoS holds an EnqueueHook pointer, and instantiates the QoS class via

    enqHook = createOne(par("qosBehaviourClass"));

OutputQueue simplified

This compound module in the old form was quite complex (4 submodules), but (when not using QoS) acted effectively as a simple FIFO. Now it has been virtually eliminated -- it just consists of an in --> out connection (and no submodules at all). NWI_IDLE messages coming from the network interfaces are now ignored.

OutputQueue will be refined -- we'll see how much it'll be needed at all. Comments welcome.

Unified IP address representation

Got rid of various classes and typedefs that all represented IP addresses: IPAddrChar (was char *), IPAddressParameter (was another char *), IN_Addr (was a class). Now there's only IPAddress.

IN_Port (was a class) also eliminated -- replaced by typedef short PortNumber.

Cut sizeof(IPAddress) from 68 bytes (!!!!!) down to 4 bytes.

IPAddress header file renamed from "ip_address.h" to "IPAddress.h".

Q: IPAddressPrefix ("ip_address_prefix.h") seems to be pretty much unused -- can be removed? For now I moved it into Network/MPLS/ (which seems to refer to it at least). Merge its functionality into IPAddress?

Handling error conditions

It often made debugging and discovering errors hard that at some places the code "concealed" and tried to locally repair error conditions instead of properly reporting them -- or just printed the error via ev<< which is hard to notice while the simulation is running. This was changed to opp_error() in many places.

Replacing cMessage+cPar and hand-coded message classes with .msg files

Done so far: IPInterfacePacket, IPDatagram, ICMPMessage, UDPPacket, UDPInterfacePacket. Next will come MPLS and LDP messages.

cMessage-based ICMP message sending eliminated altogether (see next item).

Sending of ICMP errors

In the IPProcessing module, most modules (PreRouting, Routing, Fragmentation, IPOutput) were connected to ICMP via an errorOut gate, and on error condition they sent a cMessage (with cPars) to ICMP, to ask it to send an ICMP error packet. This mechanism was replaced by direct method call of the ICMP module, e.g. in PreRouting:

   icmpAccess.get()->sendErrorMessage(datagram, ICMP_PARAMETER_PROBLEM, 0);

Net result: all those modules got rid of their local sendErrorMessage() functions and errorOut gates; ICMP got rid of 4 input gates; connections on compound module level (IPProcessing) are more clear (only contain real data paths); operation is much faster (method call is a lot faster than assembling+sending cMessages). Code size keeps going down: e.g. PreRouting.cc now only contains 21 lines of code :)

ErrorHandling module

This modules was there at the top level of every host and router, its only task being receiving error packets from ICMP and printing them. Moved it down into IPProcessing, next to ICMP. Several NED files got simpler again (errorHandling submodule declarations, and corresponding connections and gates could be removed.)

Thinking about removing ErrorHandling altogether. Do we need such thing...?

RoutingTableAccess

Killed RoutingTableAccess, LIBTableAccess etc base classes from everywhere. They were a bad idea in the first place, it should not be a base class.

Introduced RoutingTableAccess, LIBTableAccess etc classes instead, which can be put into the module class as a private/protected data member:

   protected:
      RoutingTableAccess routingTableAccess;
      LIBTableAccess libTableAccess;

and used like this from the code:

    RoutingTable *rt = routingTableAccess.get();
    ...

The ...Access classes just specialize a common ModuleAccess class so their code is just a few lines.

RoutingTable module

UDPProcessing, UDPClient, UDP Server rewritten

MPLS/RSVP-TE/LDP models

Documentation

Moving/reformatting comments so that Doxygen can use them.


First round of changes: sound directory structure, documentation, adding MPLS (June-August 2003)

Starting from IPSuite-20021124, the following changes were made:

-- AndrasVarga - 20 May 2004

Topic IPSuiteChangesOld . { Edit | Attach | Ref-By | Printable | Diffs | r1.2 | > | r1.1 | More }
Revision r1.2 - 11 May 2005 - 12:54 GMT - AhmetSekercioglu
Parents: WebHome > IPv4Suite > IPSuiteLogOfChanges
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.