|
INET Framework for OMNeT++/OMNEST
|
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