INET Framework for OMNeT++/OMNEST
ansaOspfRoutingTableEntry6.h
Go to the documentation of this file.
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_ */