|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // This program is free software: you can redistribute it and/or modify 00003 // it under the terms of the GNU Lesser General Public License as published by 00004 // the Free Software Foundation, either version 3 of the License, or 00005 // (at your option) any later version. 00006 // 00007 // This program is distributed in the hope that it will be useful, 00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 // GNU Lesser General Public License for more details. 00011 // 00012 // You should have received a copy of the GNU Lesser General Public License 00013 // along with this program. If not, see http://www.gnu.org/licenses/. 00014 // 00015 00016 #ifndef ANSAOSPFROUTINGTABLEENTRY6_H_ 00017 #define ANSAOSPFROUTINGTABLEENTRY6_H_ 00018 00019 #include "RoutingTable6.h" 00020 #include "AnsaInterfaceTableAccess.h" 00021 #include "ansaOspfCommon6.h" 00022 00023 namespace AnsaOspf6 { 00024 00025 class RoutingTableEntry : public IPv6Route { 00026 public: 00027 enum RoutingPathType { 00028 IntraArea = 0, 00029 InterArea = 1, 00030 Type1External = 2, 00031 Type2External = 3 00032 }; 00033 00034 typedef unsigned char RoutingDestinationType; 00035 00036 // destinationType bitfield values 00037 static const unsigned char NetworkDestination = 0; 00038 static const unsigned char AreaBorderRouterDestination = 1; 00039 static const unsigned char ASBoundaryRouterDestination = 2; 00040 00041 private: 00042 RoutingDestinationType destinationType; 00043 OspfOptions6 optionalCapabilities; 00044 AreaID area; 00045 RoutingPathType pathType; 00046 Metric cost; 00047 Metric type2Cost; 00048 const OspfLsa6* linkStateOrigin; 00049 std::vector<NextHop> nextHops; 00050 00051 public: 00052 RoutingTableEntry (void); 00053 RoutingTableEntry (const RoutingTableEntry& entry); 00054 virtual ~RoutingTableEntry (void) {} 00055 00056 bool operator== (const RoutingTableEntry& entry) const; 00057 bool operator!= (const RoutingTableEntry& entry) const { return (!((*this) == entry)); } 00058 00059 void SetDestinationType (RoutingDestinationType type) { destinationType = type; } 00060 RoutingDestinationType GetDestinationType (void) const { return destinationType; } 00061 void SetDestinationPrefix (IPv6Address destID) { _destPrefix = destID; } 00062 IPv6Address GetDestinationPrefix (void) const { return _destPrefix; } 00063 void SetPrefixLength (short prefixLen) { _length = prefixLen; } 00064 short GetPrefixLength (void) const { return _length; } 00065 void SetOptionalCapabilities (OspfOptions6 options) { optionalCapabilities = options; } 00066 OspfOptions6 GetOptionalCapabilities (void) const { return optionalCapabilities; } 00067 void SetArea (AreaID source) { area = source; } 00068 AreaID GetArea (void) const { return area; } 00069 void SetPathType (RoutingPathType type); 00070 RoutingPathType GetPathType (void) const { return pathType; } 00071 void SetCost (Metric pathCost); 00072 Metric GetCost (void) const { return cost; } 00073 void SetType2Cost (Metric pathCost); 00074 Metric GetType2Cost (void) const { return type2Cost; } 00075 void SetLinkStateOrigin (const OspfLsa6* lsa) { linkStateOrigin = lsa; } 00076 const OspfLsa6* GetLinkStateOrigin (void) const { return linkStateOrigin; } 00077 void AddNextHop (NextHop hop); 00078 void ClearNextHops (void) { nextHops.clear(); } 00079 unsigned int GetNextHopCount (void) const { return nextHops.size(); } 00080 NextHop GetNextHop (unsigned int index) const { return nextHops[index]; } 00081 }; 00082 00083 } 00084 00085 inline AnsaOspf6::RoutingTableEntry::RoutingTableEntry(void) : 00086 IPv6Route(IPv6Address::UNSPECIFIED_ADDRESS, 0, IPv6Route::ROUTING_PROT), 00087 destinationType(AnsaOspf6::RoutingTableEntry::NetworkDestination), 00088 area(AnsaOspf6::BackboneAreaID), 00089 pathType(AnsaOspf6::RoutingTableEntry::IntraArea), 00090 type2Cost(0), 00091 linkStateOrigin(NULL) { 00092 00093 memset(&optionalCapabilities, 0, sizeof(OspfOptions6)); 00094 } 00095 00096 inline AnsaOspf6::RoutingTableEntry::RoutingTableEntry(const RoutingTableEntry& entry) : 00097 IPv6Route(entry._destPrefix, entry._length, entry._src), 00098 destinationType(entry.destinationType), 00099 optionalCapabilities(entry.optionalCapabilities), 00100 area(entry.area), 00101 pathType(entry.pathType), 00102 cost(entry.cost), 00103 type2Cost(entry.type2Cost), 00104 linkStateOrigin(entry.linkStateOrigin), 00105 nextHops(entry.nextHops) { 00106 00107 _nextHop = entry._nextHop; 00108 _interfaceID = entry._interfaceID; 00109 _metric = entry._metric; 00110 } 00111 00112 inline void AnsaOspf6::RoutingTableEntry::SetPathType(RoutingPathType type) { 00113 pathType = type; 00114 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00115 if (pathType == AnsaOspf6::RoutingTableEntry::Type2External){ 00116 _metric = cost + type2Cost * 1000; 00117 }else{ 00118 _metric = cost; 00119 } 00120 } 00121 00122 inline void AnsaOspf6::RoutingTableEntry::SetCost(Metric pathCost) { 00123 cost = pathCost; 00124 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00125 if (pathType == AnsaOspf6::RoutingTableEntry::Type2External){ 00126 _metric = cost + type2Cost * 1000; 00127 }else{ 00128 _metric = cost; 00129 } 00130 } 00131 00132 inline void AnsaOspf6::RoutingTableEntry::SetType2Cost(Metric pathCost) { 00133 type2Cost = pathCost; 00134 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00135 if (pathType == AnsaOspf6::RoutingTableEntry::Type2External){ 00136 _metric = cost + type2Cost * 1000; 00137 }else{ 00138 _metric = cost; 00139 } 00140 } 00141 00142 inline void AnsaOspf6::RoutingTableEntry::AddNextHop(AnsaOspf6::NextHop hop) { 00143 if (nextHops.size() == 0){ 00144 InterfaceEntry* routingInterface = AnsaInterfaceTableAccess().get()->getInterfaceById(hop.ifIndex); 00145 _interfaceID = routingInterface->getInterfaceId(); 00146 _nextHop = hop.hopAddress; 00147 } 00148 nextHops.push_back(hop); 00149 } 00150 00151 inline bool AnsaOspf6::RoutingTableEntry::operator==(const RoutingTableEntry& entry) const { 00152 unsigned int hopCount = nextHops.size(); 00153 unsigned int i = 0; 00154 00155 if (hopCount != entry.nextHops.size()){ 00156 return false; 00157 } 00158 for (i = 0; i < hopCount; i++){ 00159 if ((nextHops[i] != entry.nextHops[i])){ 00160 return false; 00161 } 00162 } 00163 00164 return ( (destinationType == entry.destinationType) 00165 && (_destPrefix == entry._destPrefix) 00166 && (_length == entry._length) 00167 && (optionalCapabilities == entry.optionalCapabilities) 00168 && (area == entry.area) 00169 && (pathType == entry.pathType) 00170 && (cost == entry.cost) 00171 && (type2Cost == entry.type2Cost) 00172 && (linkStateOrigin == entry.linkStateOrigin)); 00173 } 00174 00175 inline std::ostream& operator<<(std::ostream& out, const AnsaOspf6::RoutingTableEntry& entry) { 00176 out << "Destination: " 00177 << entry.GetDestinationPrefix().str() 00178 << "/" 00179 << entry.GetPrefixLength() 00180 << " ("; 00181 00182 if (entry.GetDestinationType() == AnsaOspf6::RoutingTableEntry::NetworkDestination) { 00183 out << "Network"; 00184 } else { 00185 if ((entry.GetDestinationType() 00186 & AnsaOspf6::RoutingTableEntry::AreaBorderRouterDestination) != 0) { 00187 out << "AreaBorderRouter"; 00188 } 00189 if ((entry.GetDestinationType() 00190 & ( AnsaOspf6::RoutingTableEntry::ASBoundaryRouterDestination 00191 | AnsaOspf6::RoutingTableEntry::AreaBorderRouterDestination)) != 0) { 00192 out << "+"; 00193 } 00194 if ((entry.GetDestinationType() 00195 & AnsaOspf6::RoutingTableEntry::ASBoundaryRouterDestination) != 0) { 00196 out << "ASBoundaryRouter"; 00197 } 00198 } 00199 00200 out << "), Area: " 00201 << entry.GetArea() 00202 << ", PathType: "; 00203 00204 switch (entry.GetPathType()){ 00205 case AnsaOspf6::RoutingTableEntry::IntraArea: 00206 out << "IntraArea"; 00207 break; 00208 case AnsaOspf6::RoutingTableEntry::InterArea: 00209 out << "InterArea"; 00210 break; 00211 case AnsaOspf6::RoutingTableEntry::Type1External: 00212 out << "Type1External"; 00213 break; 00214 case AnsaOspf6::RoutingTableEntry::Type2External: 00215 out << "Type2External"; 00216 break; 00217 default: 00218 out << "Unknown"; 00219 break; 00220 } 00221 00222 out << ", Cost: " 00223 << entry.GetCost() 00224 << ", Type2Cost: " 00225 << entry.GetType2Cost() 00226 << ", Origin: ["; 00227 00228 PrintLsaHeader6(entry.GetLinkStateOrigin()->getHeader(), out); 00229 out << "], NextHops: "; 00230 00231 unsigned int hopCount = entry.GetNextHopCount(); 00232 for (unsigned int i = 0; i < hopCount; i++) { 00233 out << entry.GetNextHop(i).hopAddress << " "; 00234 } 00235 00236 return out; 00237 } 00238 00239 #endif /* ANSAOSPFROUTINGTABLEENTRY6_H_ */