INET Framework for OMNeT++/OMNEST
AnsaInterfaceTable Class Reference

#include <AnsaInterfaceTable.h>

Inheritance diagram for AnsaInterfaceTable:
IInterfaceTable INotifiable

List of all members.

Public Member Functions

 AnsaInterfaceTable ()
virtual ~AnsaInterfaceTable ()
virtual std::string getFullPath () const
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
virtual void addInterface (InterfaceEntry *entry, cModule *ifmod)
virtual void deleteInterface (InterfaceEntry *entry)
virtual int getNumInterfaces ()
virtual InterfaceEntrygetInterface (int pos)
virtual InterfaceEntrygetInterfaceById (int id)
virtual InterfaceEntrygetInterfaceByNodeOutputGateId (int id)
virtual InterfaceEntrygetInterfaceByNodeInputGateId (int id)
virtual InterfaceEntrygetInterfaceByNetworkLayerGateIndex (int index)
virtual InterfaceEntrygetInterfaceByName (const char *name)
virtual InterfaceEntrygetFirstLoopbackInterface ()
InterfaceEntrygetFirstInterface ()

Protected Types

typedef std::vector
< InterfaceEntry * > 
InterfaceVector

Protected Member Functions

virtual void updateDisplayString ()
virtual void discoverConnectingGates (InterfaceEntry *entry, cModule *ifmod)
virtual void interfaceChanged (InterfaceEntry *entry, int category)
virtual void invalidateTmpInterfaceList ()
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *)

Protected Attributes

NotificationBoardnb
InterfaceVector idToInterface
int tmpNumInterfaces
InterfaceEntry ** tmpInterfaceList

Detailed Description

Represents the interface table. This object has one instance per host or router. It has methods to manage the interface table, so one can access functionality similar to the "ifconfig" command.

See the NED documentation for general overview.

This is a simple module without gates, it requires function calls to it (message handling does nothing). Methods are provided for reading and updating the interface table.

Interfaces are dynamically registered: at the start of the simulation, every L2 module adds its own InterfaceEntry to the table; after that, IPv4's IRoutingTable and IPv6's RoutingTable6 (an possibly, further L3 protocols) add protocol-specific data on each InterfaceEntry (see IPv4InterfaceData, IPv6InterfaceData, and InterfaceEntry::setIPv4Data(), InterfaceEntry::setIPv6Data())

Interfaces are represented by InterfaceEntry objects.

When interfaces need to be reliably and efficiently identified from other modules, interfaceIds should be used. They are better suited than pointers because when an interface gets removed (see deleteInterface()), it is often impossible/impractical to invalidate all pointers to it, and also because pointers are not necessarily unique (a new InterfaceEntry may get allocated exactly at the address of a previously deleted one). Interface Ids are unique (Ids of removed interfaces are not issued again), stale Ids can be detected, and they are also invariant to insertion/deletion.

Clients can get notified about interface changes by subscribing to the following notifications in NotificationBoard: NF_INTERFACE_CREATED, NF_INTERFACE_DELETED, NF_INTERFACE_STATE_CHANGED, NF_INTERFACE_CONFIG_CHANGED. State change gets fired for up/down events; all other changes fire as config change.

See also:
InterfaceEntry

Definition at line 67 of file AnsaInterfaceTable.h.


Member Typedef Documentation

typedef std::vector<InterfaceEntry *> AnsaInterfaceTable::InterfaceVector [protected]

Definition at line 74 of file AnsaInterfaceTable.h.


Constructor & Destructor Documentation

Definition at line 43 of file AnsaInterfaceTable.cc.

{
    for (int i=0; i < (int)idToInterface.size(); i++)
        delete idToInterface[i];
    delete [] tmpInterfaceList;
}

Member Function Documentation

void AnsaInterfaceTable::addInterface ( InterfaceEntry entry,
cModule *  ifmod 
) [virtual]

Adds an interface. The second argument should be a module which belongs to the physical interface (e.g. PPP or EtherMac) -- it will be used to discover and fill in getNetworkLayerGateIndex(), getNodeOutputGateId(), and getNodeInputGateId() in InterfaceEntry. It should be NULL if this is a virtual interface (e.g. loopback).

Implements IInterfaceTable.

Definition at line 138 of file AnsaInterfaceTable.cc.

{
    // check name is unique
    if (getInterfaceByName(entry->getName())!=NULL)
        opp_error("addInterface(): interface '%s' already registered", entry->getName());

    // insert
    entry->setInterfaceId(INTERFACEIDS_START + idToInterface.size());
    entry->setInterfaceTable(this);
    idToInterface.push_back(entry);
    invalidateTmpInterfaceList();

    // fill in networkLayerGateIndex, nodeOutputGateId, nodeInputGateId
    if (ifmod)
        discoverConnectingGates(entry, ifmod);

    nb->fireChangeNotification(NF_INTERFACE_CREATED, entry);
}

Deletes the given interface from the table. Indices of existing interfaces (see getInterface(int)) may change. It is an error if the given interface is not in the table.

Implements IInterfaceTable.

Definition at line 194 of file AnsaInterfaceTable.cc.

{
    int id = entry->getInterfaceId();
    if (entry != getInterfaceById(id))
        opp_error("deleteInterface(): interface '%s' not found in interface table", entry->getName());

    nb->fireChangeNotification(NF_INTERFACE_DELETED, entry);  // actually, only going to be deleted

    idToInterface[id - INTERFACEIDS_START] = NULL;
    delete entry;
    invalidateTmpInterfaceList();
}
void AnsaInterfaceTable::discoverConnectingGates ( InterfaceEntry entry,
cModule *  ifmod 
) [protected, virtual]

Definition at line 157 of file AnsaInterfaceTable.cc.

Referenced by addInterface().

{
    // ifmod is something like "host.eth[1].mac"; climb up to find "host.eth[1]" from it
    cModule *host = getParentModule();
    while (ifmod && ifmod->getParentModule()!=host)
        ifmod = ifmod->getParentModule();
    if (!ifmod)
        opp_error("addInterface(): specified module is not in this host/router");

    // find gates connected to host / network layer
    cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL;
    for (GateIterator i(ifmod); !i.end(); i++)
    {
        cGate *g = i();
        if (!g) continue;

        // find the host/router's gates that internally connect to this interface
        if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->getOwnerModule()==host)
            entry->setNodeOutputGateId(g->getNextGate()->getId());
        if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->getOwnerModule()==host)
            entry->setNodeInputGateId(g->getPreviousGate()->getId());

        // find the gate index of networkLayer/networkLayer6/mpls that connects to this interface
        if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->isName("ifIn"))
            nwlayerInGate = g->getNextGate();
        if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->isName("ifOut"))
            nwlayerOutGate = g->getPreviousGate();
    }

    // consistency checks
    // note: we don't check nodeOutputGateId/nodeInputGateId, because wireless interfaces
    // are not connected to the host
    if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->getIndex()!=nwlayerOutGate->getIndex())
        opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index");
    entry->setNetworkLayerGateIndex(nwlayerInGate->getIndex());
}

Definition at line 274 of file AnsaInterfaceTable.cc.

Referenced by AnsaOspfRouting6::getOspfRouter(), AnsaOspfRouting6::initialize(), and AnsaOspfRouting6::loadInterfaceConfig().

{
   Enter_Method_Silent();
   int n = idToInterface.size();
   for (int i=0; i<n; i++)
       if (idToInterface[i])
           return idToInterface[i];
   return NULL;
}

Returns the first interface with the isLoopback flag set. (If there's no loopback, it returns NULL -- but this should never happen because InterfaceTable itself registers a loopback interface on startup.)

Implements IInterfaceTable.

Definition at line 264 of file AnsaInterfaceTable.cc.

{
    Enter_Method_Silent();
    int n = idToInterface.size();
    for (int i=0; i<n; i++)
        if (idToInterface[i] && idToInterface[i]->isLoopback())
            return idToInterface[i];
    return NULL;
}
virtual std::string AnsaInterfaceTable::getFullPath ( ) const [inline, virtual]

Module path name

Implements IInterfaceTable.

Definition at line 97 of file AnsaInterfaceTable.h.

Returns the InterfaceEntry specified by an index 0..numInterfaces-1. Throws an error if index is out of range.

Note that this index is NOT the same as interfaceId! Indices are not guaranteed to stay the same after interface addition/deletion, so cannot be used to reliably identify the interface. Use interfaceId to refer to interfaces from other modules or from messages/packets.

Implements IInterfaceTable.

Definition at line 112 of file AnsaInterfaceTable.cc.

Referenced by AnsaOspfRouting6::addWatches().

{
    int n = getNumInterfaces(); // also fills tmpInterfaceList
    if (pos<0 || pos>=n)
        opp_error("getInterface(): interface index %d out of range 0..%d", pos, n-1);

    if (!tmpInterfaceList)
    {
        // collect non-NULL elements into tmpInterfaceList[]
        tmpInterfaceList = new InterfaceEntry *[n];
        int k = 0;
        int maxId = idToInterface.size();
        for (int i=0; i<maxId; i++)
            if (idToInterface[i])
                tmpInterfaceList[k++] = idToInterface[i];
    }

    return tmpInterfaceList[pos];
}

Returns an interface by its Id. Ids are guaranteed to be invariant to interface deletions/additions. Returns NULL if there is no such interface (This allows detecting stale IDs without raising an error.)

Implements IInterfaceTable.

Definition at line 132 of file AnsaInterfaceTable.cc.

Referenced by AnsaOspf6::RoutingTableEntry::AddNextHop(), and deleteInterface().

{
    id -= INTERFACEIDS_START;
    return (id<0 || id>=(int)idToInterface.size()) ? NULL : idToInterface[id];
}
InterfaceEntry * AnsaInterfaceTable::getInterfaceByName ( const char *  name) [virtual]

Returns an interface given by its name. Returns NULL if not found.

Implements IInterfaceTable.

Definition at line 252 of file AnsaInterfaceTable.cc.

Referenced by addInterface(), and AnsaOspfRouting6::loadInterfaceConfig().

{
    Enter_Method_Silent();
    if (!name)
        return NULL;
    int n = idToInterface.size();
    for (int i=0; i<n; i++)
        if (idToInterface[i] && !strcmp(name, idToInterface[i]->getName()))
            return idToInterface[i];
    return NULL;
}

Returns an interface given by its getNetworkLayerGateIndex(). Returns NULL if not found.

Implements IInterfaceTable.

Definition at line 241 of file AnsaInterfaceTable.cc.

{
    // linear search is OK because normally we have don't have many interfaces and this func is rarely called
    Enter_Method_Silent();
    int n = idToInterface.size();
    for (int i=0; i<n; i++)
        if (idToInterface[i] && idToInterface[i]->getNetworkLayerGateIndex()==index)
            return idToInterface[i];
    return NULL;
}

Returns an interface given by its getNodeInputGateId(). Returns NULL if not found.

Implements IInterfaceTable.

Definition at line 230 of file AnsaInterfaceTable.cc.

{
    // linear search is OK because normally we have don't have many interfaces and this func is rarely called
    Enter_Method_Silent();
    int n = idToInterface.size();
    for (int i=0; i<n; i++)
        if (idToInterface[i] && idToInterface[i]->getNodeInputGateId()==id)
            return idToInterface[i];
    return NULL;
}

Returns an interface given by its getNodeOutputGateId(). Returns NULL if not found.

Implements IInterfaceTable.

Definition at line 219 of file AnsaInterfaceTable.cc.

{
    // linear search is OK because normally we have don't have many interfaces and this func is rarely called
    Enter_Method_Silent();
    int n = idToInterface.size();
    for (int i=0; i<n; i++)
        if (idToInterface[i] && idToInterface[i]->getNodeOutputGateId()==id)
            return idToInterface[i];
    return NULL;
}

Returns the number of interfaces.

Implements IInterfaceTable.

Definition at line 96 of file AnsaInterfaceTable.cc.

Referenced by AnsaOspfRouting6::addWatches(), getInterface(), AnsaOspfRouting6::initialize(), and updateDisplayString().

{
    if (tmpNumInterfaces == -1)
    {
        // count non-NULL elements
        int n = 0;
        int maxId = idToInterface.size();
        for (int i=0; i<maxId; i++)
            if (idToInterface[i])
                n++;
        tmpNumInterfaces = n;
    }

    return tmpNumInterfaces;
}
void AnsaInterfaceTable::handleMessage ( cMessage *  msg) [protected, virtual]

Raises an error.

Definition at line 82 of file AnsaInterfaceTable.cc.

{
    opp_error("This module doesn't process messages");
}
void AnsaInterfaceTable::initialize ( int  stage) [protected, virtual]

Definition at line 50 of file AnsaInterfaceTable.cc.

{
    if (stage==0)
    {
        // get a pointer to the NotificationBoard module
        nb = NotificationBoardAccess().get();

        // register a loopback interface
        //vypnut
        //InterfaceEntry *ie = new InterfaceEntry();
        //ie->setName("lo0");
        //ie->setMtu(3924);
        //ie->setLoopback(true);
        //addInterface(ie, NULL);
    }
    else if (stage==1)
    {
        WATCH_PTRVECTOR(idToInterface);
        updateDisplayString();
    }
}
void AnsaInterfaceTable::interfaceChanged ( InterfaceEntry entry,
int  category 
) [protected, virtual]

Implements IInterfaceTable.

Definition at line 214 of file AnsaInterfaceTable.cc.

{
    nb->fireChangeNotification(category, entry);
}
void AnsaInterfaceTable::invalidateTmpInterfaceList ( ) [protected, virtual]

Definition at line 207 of file AnsaInterfaceTable.cc.

Referenced by addInterface(), and deleteInterface().

virtual int AnsaInterfaceTable::numInitStages ( ) const [inline, protected, virtual]

Definition at line 100 of file AnsaInterfaceTable.h.

{return 2;}
void AnsaInterfaceTable::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [virtual]

Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.

Implements INotifiable.

Definition at line 87 of file AnsaInterfaceTable.cc.

{
    // nothing needed here at the moment
    Enter_Method_Silent();
    printNotificationBanner(category, details);
}
void AnsaInterfaceTable::updateDisplayString ( ) [protected, virtual]

Definition at line 72 of file AnsaInterfaceTable.cc.

Referenced by initialize().

{
    if (!ev.isGUI())
        return;

    char buf[80];
    sprintf(buf, "%d interfaces", getNumInterfaces());
    getDisplayString().setTagArg("t",0,buf);
}

Member Data Documentation


The documentation for this class was generated from the following files: