INET Framework for OMNeT++/OMNEST
AnsaOSPFRoutingTableEntry.h
Go to the documentation of this file.
00001 #ifndef __INET_OSPFROUTINGTABLEENTRY_H
00002 #define __INET_OSPFROUTINGTABLEENTRY_H
00003 
00004 #include "IRoutingTable.h"
00005 #include "InterfaceTableAccess.h"
00006 #include "AnsaOSPFcommon.h"
00007 #include <memory.h>
00008 
00009 namespace AnsaOSPF {
00010 
00011 class RoutingTableEntry : public IPRoute
00012 {
00013 public:
00014     enum RoutingPathType {
00015         IntraArea     = 0,
00016         InterArea     = 1,
00017         Type1External = 2,
00018         Type2External = 3
00019     };
00020 
00021     typedef unsigned char RoutingDestinationType;
00022 
00023     // destinationType bitfield values
00024     static const unsigned char NetworkDestination = 0;
00025     static const unsigned char AreaBorderRouterDestination = 1;
00026     static const unsigned char ASBoundaryRouterDestination = 2;
00027 
00028 private:
00029     RoutingDestinationType  destinationType;
00030     // destinationID is IPRoute::host
00031     // addressMask is IPRoute::netmask
00032     OSPFOptions             optionalCapabilities;
00033     AreaID                  area;
00034     RoutingPathType         pathType;
00035     Metric                  cost;
00036     Metric                  type2Cost;
00037     const OSPFLSA*          linkStateOrigin;
00038     std::vector<NextHop>    nextHops;
00039     // IPRoute::interfacePtr comes from nextHops[0].ifIndex
00040     // IPRoute::gateway is nextHops[0].hopAddress
00041 
00042 public:
00043             RoutingTableEntry  (void);
00044             RoutingTableEntry  (const RoutingTableEntry& entry);
00045     virtual ~RoutingTableEntry(void) {}
00046 
00047     bool    operator== (const RoutingTableEntry& entry) const;
00048     bool    operator!= (const RoutingTableEntry& entry) const { return (!((*this) == entry)); }
00049 
00050     void                    SetDestinationType      (RoutingDestinationType type)   { destinationType = type; }
00051     RoutingDestinationType  GetDestinationType      (void) const                    { return destinationType; }
00052     void                    SetDestinationID        (IPAddress destID)              { host = destID; }
00053     IPAddress               GetDestinationID        (void) const                    { return host; }
00054     void                    SetAddressMask          (IPAddress destMask)            { netmask = destMask; }
00055     IPAddress               GetAddressMask          (void) const                    { return netmask; }
00056     void                    SetOptionalCapabilities(OSPFOptions options)           { optionalCapabilities = options; }
00057     OSPFOptions             GetOptionalCapabilities(void) const                    { return optionalCapabilities; }
00058     void                    SetArea                 (AreaID source)                 { area = source; }
00059     AreaID                  GetArea                 (void) const                    { return area; }
00060     void                    SetPathType             (RoutingPathType type);
00061     RoutingPathType         GetPathType             (void) const                    { return pathType; }
00062     void                    SetCost                 (Metric pathCost);
00063     Metric                  GetCost                 (void) const                    { return cost; }
00064     void                    SetType2Cost            (Metric pathCost);
00065     Metric                  GetType2Cost            (void) const                    { return type2Cost; }
00066     void                    SetLinkStateOrigin      (const OSPFLSA* lsa)            { linkStateOrigin = lsa; }
00067     const OSPFLSA*          GetLinkStateOrigin      (void) const                    { return linkStateOrigin; }
00068     void                    AddNextHop              (NextHop hop);
00069     void                    ClearNextHops           (void)                          { nextHops.clear(); }
00070     unsigned int            GetNextHopCount         (void) const                    { return nextHops.size(); }
00071     NextHop                 GetNextHop              (unsigned int index) const      { return nextHops[index]; }
00072 };
00073 
00074 } // namespace AnsaOSPF
00075 
00076 inline AnsaOSPF::RoutingTableEntry::RoutingTableEntry(void) :
00077     IPRoute(),
00078     destinationType(AnsaOSPF::RoutingTableEntry::NetworkDestination),
00079     area(AnsaOSPF::BackboneAreaID),
00080     pathType(AnsaOSPF::RoutingTableEntry::IntraArea),
00081     type2Cost(0),
00082     linkStateOrigin(NULL)
00083 {
00084     netmask = 0xFFFFFFFF;
00085     source  = IPRoute::OSPF;
00086     memset(&optionalCapabilities, 0, sizeof(OSPFOptions));
00087 }
00088 
00089 inline AnsaOSPF::RoutingTableEntry::RoutingTableEntry(const RoutingTableEntry& entry) :
00090     destinationType(entry.destinationType),
00091     optionalCapabilities(entry.optionalCapabilities),
00092     area(entry.area),
00093     pathType(entry.pathType),
00094     cost(entry.cost),
00095     type2Cost(entry.type2Cost),
00096     linkStateOrigin(entry.linkStateOrigin),
00097     nextHops(entry.nextHops)
00098 {
00099     host          = entry.host;
00100     netmask       = entry.netmask;
00101     gateway       = entry.gateway;
00102     interfacePtr  = entry.interfacePtr;
00103     type          = entry.type;
00104     source        = entry.source;
00105     metric        = entry.metric;
00106 }
00107 
00108 inline void AnsaOSPF::RoutingTableEntry::SetPathType(RoutingPathType type)
00109 {
00110     pathType = type;
00111     // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF...
00112     if (pathType == AnsaOSPF::RoutingTableEntry::Type2External) {
00113         metric = cost + type2Cost * 1000;
00114     } else {
00115         metric = cost;
00116     }
00117 }
00118 
00119 inline void AnsaOSPF::RoutingTableEntry::SetCost(Metric pathCost)
00120 {
00121     cost = pathCost;
00122     // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF...
00123     if (pathType == AnsaOSPF::RoutingTableEntry::Type2External) {
00124         metric = cost + type2Cost * 1000;
00125     } else {
00126         metric = cost;
00127     }
00128 }
00129 
00130 inline void AnsaOSPF::RoutingTableEntry::SetType2Cost(Metric pathCost)
00131 {
00132     type2Cost = pathCost;
00133     // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF...
00134     if (pathType == AnsaOSPF::RoutingTableEntry::Type2External) {
00135         metric = cost + type2Cost * 1000;
00136     } else {
00137         metric = cost;
00138     }
00139 }
00140 
00141 inline void AnsaOSPF::RoutingTableEntry::AddNextHop(AnsaOSPF::NextHop hop)
00142 {
00143     if (nextHops.size() == 0) {
00144         InterfaceEntry*    routingInterface = InterfaceTableAccess().get()->getInterfaceById(hop.ifIndex);
00145 
00146         interfacePtr = routingInterface;
00147         gateway = ULongFromIPv4Address(hop.hopAddress); // TODO: verify this isn't necessary
00148     }
00149     nextHops.push_back(hop);
00150 }
00151 
00152 inline bool AnsaOSPF::RoutingTableEntry::operator== (const RoutingTableEntry& entry) const
00153 {
00154     unsigned int hopCount = nextHops.size();
00155     unsigned int i        = 0;
00156 
00157     if (hopCount != entry.nextHops.size()) {
00158         return false;
00159     }
00160     for (i = 0; i < hopCount; i++) {
00161         if ((nextHops[i] != entry.nextHops[i]))
00162         {
00163             return false;
00164         }
00165     }
00166 
00167     return ((destinationType      == entry.destinationType)      &&
00168             (host                 == entry.host)                 &&
00169             (netmask              == entry.netmask)              &&
00170             (optionalCapabilities == entry.optionalCapabilities) &&
00171             (area                 == entry.area)                 &&
00172             (pathType             == entry.pathType)             &&
00173             (cost                 == entry.cost)                 &&
00174             (type2Cost            == entry.type2Cost)            &&
00175             (linkStateOrigin      == entry.linkStateOrigin));
00176 }
00177 
00178 inline std::ostream& operator<< (std::ostream& out, const AnsaOSPF::RoutingTableEntry& entry)
00179 {
00180     out << "Destination: "
00181         << entry.GetDestinationID().str()
00182         << "/"
00183         << entry.GetAddressMask().str()
00184         << " (";
00185     if (entry.GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) {
00186         out << "Network";
00187     } else {
00188         if ((entry.GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) {
00189             out << "AreaBorderRouter";
00190         }
00191         if ((entry.GetDestinationType() & (AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination | AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination)) != 0) {
00192             out << "+";
00193         }
00194         if ((entry.GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) {
00195             out << "ASBoundaryRouter";
00196         }
00197     }
00198     out << "), Area: "
00199         << entry.GetArea()
00200         << ", PathType: ";
00201     switch (entry.GetPathType()) {
00202         case AnsaOSPF::RoutingTableEntry::IntraArea:     out << "IntraArea";     break;
00203         case AnsaOSPF::RoutingTableEntry::InterArea:     out << "InterArea";     break;
00204         case AnsaOSPF::RoutingTableEntry::Type1External: out << "Type1External"; break;
00205         case AnsaOSPF::RoutingTableEntry::Type2External: out << "Type2External"; break;
00206         default:            out << "Unknown";       break;
00207     }
00208     out << ", Cost: "
00209         << entry.GetCost()
00210         << ", Type2Cost: "
00211         << entry.GetType2Cost()
00212         << ", Origin: [";
00213     PrintLSAHeader(entry.GetLinkStateOrigin()->getHeader(), out);
00214     out << "], NextHops: ";
00215 
00216     unsigned int hopCount = entry.GetNextHopCount();
00217     for (unsigned int i = 0; i < hopCount; i++) {
00218         char addressString[16];
00219         out << AddressStringFromIPv4Address(addressString, sizeof(addressString), entry.GetNextHop(i).hopAddress)
00220             << " ";
00221     }
00222 
00223     return out;
00224 }
00225 
00226 #endif // __INET_OSPFROUTINGTABLEENTRY_H