1399 bool finished =
false;
1400 std::vector<OSPFLSA *> treeVertices;
1401 OSPFLSA *justAddedVertex;
1402 std::vector<OSPFLSA *> candidateVertices;
1403 unsigned long i, j,
k;
1404 unsigned long lsaCount;
1422 for (i = 0; i < lsaCount; i++) {
1426 for (i = 0; i < lsaCount; i++) {
1434 LSAType vertexType =
static_cast<LSAType>(justAddedVertex->getHeader().getLsType());
1437 RouterLSA *routerVertex = check_and_cast<RouterLSA *>(justAddedVertex);
1438 if (routerVertex->getV_VirtualLinkEndpoint()) {
1442 unsigned int linkCount = routerVertex->getLinksArraySize();
1443 for (i = 0; i < linkCount; i++) {
1444 Link& link = routerVertex->getLinks(i);
1446 OSPFLSA *joiningVertex;
1462 if ((joiningVertex ==
nullptr) ||
1463 (joiningVertex->getHeader().getLsAge() ==
MAX_AGE) ||
1464 (!
hasLink(joiningVertex, justAddedVertex)))
1469 unsigned int treeSize = treeVertices.size();
1470 bool alreadyOnTree =
false;
1472 for (j = 0; j < treeSize; j++) {
1473 if (treeVertices[j] == joiningVertex) {
1474 alreadyOnTree =
true;
1478 if (alreadyOnTree) {
1482 unsigned long linkStateCost = routerVertex->getDistance() + link.getLinkCost();
1483 unsigned int candidateCount = candidateVertices.size();
1484 OSPFLSA *candidate =
nullptr;
1486 for (j = 0; j < candidateCount; j++) {
1487 if (candidateVertices[j] == joiningVertex) {
1488 candidate = candidateVertices[j];
1491 if (candidate !=
nullptr) {
1492 RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(candidate);
1493 unsigned long candidateDistance = routingInfo->getDistance();
1495 if (linkStateCost > candidateDistance) {
1498 if (linkStateCost < candidateDistance) {
1499 routingInfo->setDistance(linkStateCost);
1500 routingInfo->clearNextHops();
1502 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1503 unsigned int nextHopCount = newNextHops->size();
1504 for (k = 0; k < nextHopCount; k++) {
1505 routingInfo->addNextHop((*newNextHops)[k]);
1511 RouterLSA *joiningRouterVertex = check_and_cast<RouterLSA *>(joiningVertex);
1512 joiningRouterVertex->setDistance(linkStateCost);
1513 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1514 unsigned int nextHopCount = newNextHops->size();
1515 for (k = 0; k < nextHopCount; k++) {
1516 joiningRouterVertex->addNextHop((*newNextHops)[k]);
1519 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningRouterVertex);
1520 vertexRoutingInfo->setParent(justAddedVertex);
1522 candidateVertices.push_back(joiningRouterVertex);
1525 NetworkLSA *joiningNetworkVertex = check_and_cast<NetworkLSA *>(joiningVertex);
1526 joiningNetworkVertex->setDistance(linkStateCost);
1527 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1528 unsigned int nextHopCount = newNextHops->size();
1529 for (k = 0; k < nextHopCount; k++) {
1530 joiningNetworkVertex->addNextHop((*newNextHops)[k]);
1533 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningNetworkVertex);
1534 vertexRoutingInfo->setParent(justAddedVertex);
1536 candidateVertices.push_back(joiningNetworkVertex);
1543 NetworkLSA *networkVertex = check_and_cast<NetworkLSA *>(justAddedVertex);
1544 unsigned int routerCount = networkVertex->getAttachedRoutersArraySize();
1546 for (i = 0; i < routerCount; i++) {
1547 RouterLSA *joiningVertex =
findRouterLSA(networkVertex->getAttachedRouters(i));
1548 if ((joiningVertex ==
nullptr) ||
1549 (joiningVertex->getHeader().getLsAge() ==
MAX_AGE) ||
1550 (!
hasLink(joiningVertex, justAddedVertex)))
1555 unsigned int treeSize = treeVertices.size();
1556 bool alreadyOnTree =
false;
1558 for (j = 0; j < treeSize; j++) {
1559 if (treeVertices[j] == joiningVertex) {
1560 alreadyOnTree =
true;
1564 if (alreadyOnTree) {
1568 unsigned long linkStateCost = networkVertex->
getDistance();
1569 unsigned int candidateCount = candidateVertices.size();
1570 OSPFLSA *candidate =
nullptr;
1572 for (j = 0; j < candidateCount; j++) {
1573 if (candidateVertices[j] == joiningVertex) {
1574 candidate = candidateVertices[j];
1577 if (candidate !=
nullptr) {
1578 RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(candidate);
1579 unsigned long candidateDistance = routingInfo->getDistance();
1581 if (linkStateCost > candidateDistance) {
1584 if (linkStateCost < candidateDistance) {
1585 routingInfo->setDistance(linkStateCost);
1586 routingInfo->clearNextHops();
1588 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1589 unsigned int nextHopCount = newNextHops->size();
1590 for (k = 0; k < nextHopCount; k++) {
1591 routingInfo->addNextHop((*newNextHops)[k]);
1596 joiningVertex->setDistance(linkStateCost);
1597 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1598 unsigned int nextHopCount = newNextHops->size();
1599 for (k = 0; k < nextHopCount; k++) {
1600 joiningVertex->addNextHop((*newNextHops)[k]);
1603 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningVertex);
1604 vertexRoutingInfo->setParent(justAddedVertex);
1606 candidateVertices.push_back(joiningVertex);
1611 if (candidateVertices.empty()) {
1615 unsigned int candidateCount = candidateVertices.size();
1617 OSPFLSA *closestVertex = candidateVertices[0];
1619 for (i = 0; i < candidateCount; i++) {
1620 RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(candidateVertices[i]);
1621 unsigned long currentDistance = routingInfo->getDistance();
1623 if (currentDistance < minDistance) {
1624 closestVertex = candidateVertices[i];
1625 minDistance = currentDistance;
1628 if (currentDistance == minDistance) {
1629 if ((closestVertex->getHeader().getLsType() ==
ROUTERLSA_TYPE) &&
1632 closestVertex = candidateVertices[i];
1638 treeVertices.push_back(closestVertex);
1640 for (
auto it = candidateVertices.begin(); it != candidateVertices.end(); it++) {
1641 if ((*it) == closestVertex) {
1642 candidateVertices.erase(it);
1648 RouterLSA *routerLSA = check_and_cast<RouterLSA *>(closestVertex);
1649 if (routerLSA->getB_AreaBorderRouter() || routerLSA->getE_ASBoundaryRouter()) {
1650 RoutingTableEntry *entry =
new RoutingTableEntry(
ift);
1651 RouterID destinationID = routerLSA->getHeader().getLinkStateID();
1652 unsigned int nextHopCount = routerLSA->getNextHopCount();
1655 entry->setDestination(destinationID);
1656 entry->setLinkStateOrigin(routerLSA);
1659 entry->setCost(routerLSA->getDistance());
1660 if (routerLSA->getB_AreaBorderRouter()) {
1663 if (routerLSA->getE_ASBoundaryRouter()) {
1666 entry->setDestinationType(destinationType);
1667 entry->setOptionalCapabilities(routerLSA->getHeader().getLsOptions());
1668 for (i = 0; i < nextHopCount; i++) {
1669 entry->addNextHop(routerLSA->getNextHop(i));
1672 newRoutingTable.push_back(entry);
1681 if (backbone !=
nullptr) {
1683 if ((virtualIntf !=
nullptr) && (virtualIntf->getTransitAreaID() ==
areaID)) {
1684 IPv4AddressRange range;
1687 virtualIntf->setAddressRange(range);
1688 virtualIntf->setIfIndex(
ift, routerLSA->getNextHop(0).ifIndex);
1689 virtualIntf->setOutputCost(routerLSA->getDistance());
1690 Neighbor *virtualNeighbor = virtualIntf->getNeighbor(0);
1691 if (virtualNeighbor !=
nullptr) {
1692 unsigned int linkCount = routerLSA->getLinksArraySize();
1693 RouterLSA *toRouterLSA =
dynamic_cast<RouterLSA *
>(justAddedVertex);
1694 if (toRouterLSA !=
nullptr) {
1695 for (i = 0; i < linkCount; i++) {
1696 Link& link = routerLSA->getLinks(i);
1699 (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) &&
1702 virtualNeighbor->setAddress(IPv4Address(link.getLinkData()));
1709 NetworkLSA *toNetworkLSA =
dynamic_cast<NetworkLSA *
>(justAddedVertex);
1710 if (toNetworkLSA !=
nullptr) {
1711 for (i = 0; i < linkCount; i++) {
1712 Link& link = routerLSA->getLinks(i);
1715 (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()) &&
1718 virtualNeighbor->setAddress(IPv4Address(link.getLinkData()));
1732 NetworkLSA *networkLSA = check_and_cast<NetworkLSA *>(closestVertex);
1733 IPv4Address destinationID = (networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask());
1734 unsigned int nextHopCount = networkLSA->getNextHopCount();
1735 bool overWrite =
false;
1736 RoutingTableEntry *entry =
nullptr;
1737 unsigned long routeCount = newRoutingTable.size();
1738 IPv4Address longestMatch(0u);
1740 for (i = 0; i < routeCount; i++) {
1742 RoutingTableEntry *routingEntry = newRoutingTable[i];
1743 IPv4Address entryAddress = routingEntry->getDestination();
1744 IPv4Address entryMask = routingEntry->getNetmask();
1746 if ((entryAddress & entryMask) == (destinationID & entryMask)) {
1747 if ((destinationID & entryMask) > longestMatch) {
1748 longestMatch = (destinationID & entryMask);
1749 entry = routingEntry;
1754 if (entry !=
nullptr) {
1755 const OSPFLSA *entryOrigin = entry->getLinkStateOrigin();
1756 if ((entry->getCost() != networkLSA->getDistance()) ||
1757 (entryOrigin->getHeader().getLinkStateID() >= networkLSA->getHeader().getLinkStateID()))
1763 if ((entry ==
nullptr) || (overWrite)) {
1764 if (entry ==
nullptr) {
1765 entry =
new RoutingTableEntry(
ift);
1768 entry->setDestination(IPv4Address(destinationID));
1769 entry->setNetmask(networkLSA->getNetworkMask());
1770 entry->setLinkStateOrigin(networkLSA);
1773 entry->setCost(networkLSA->getDistance());
1775 entry->setOptionalCapabilities(networkLSA->getHeader().getLsOptions());
1776 for (i = 0; i < nextHopCount; i++) {
1777 entry->addNextHop(networkLSA->getNextHop(i));
1781 newRoutingTable.push_back(entry);
1786 justAddedVertex = closestVertex;
1788 }
while (!finished);
1790 unsigned int treeSize = treeVertices.size();
1791 for (i = 0; i < treeSize; i++) {
1792 RouterLSA *routerVertex =
dynamic_cast<RouterLSA *
>(treeVertices[i]);
1793 if (routerVertex ==
nullptr) {
1797 unsigned int linkCount = routerVertex->getLinksArraySize();
1798 for (j = 0; j < linkCount; j++) {
1799 Link& link = routerVertex->getLinks(j);
1804 unsigned long distance = routerVertex->getDistance() + link.getLinkCost();
1805 unsigned long destinationID = (link.getLinkID().getInt() & link.getLinkData());
1806 RoutingTableEntry *entry =
nullptr;
1807 unsigned long routeCount = newRoutingTable.size();
1808 unsigned long longestMatch = 0;
1810 for (k = 0; k < routeCount; k++) {
1812 RoutingTableEntry *routingEntry = newRoutingTable[
k];
1813 unsigned long entryAddress = routingEntry->getDestination().getInt();
1814 unsigned long entryMask = routingEntry->getNetmask().getInt();
1816 if ((entryAddress & entryMask) == (destinationID & entryMask)) {
1817 if ((destinationID & entryMask) > longestMatch) {
1818 longestMatch = (destinationID & entryMask);
1819 entry = routingEntry;
1825 if (entry !=
nullptr) {
1826 Metric entryCost = entry->getCost();
1828 if (distance > entryCost) {
1831 if (distance < entryCost) {
1836 entry->setCost(distance);
1837 entry->clearNextHops();
1838 entry->setLinkStateOrigin(routerVertex);
1840 if (distance == entryCost) {
1842 const OSPFLSA *lsOrigin = entry->getLinkStateOrigin();
1843 if (dynamic_cast<const RouterLSA *>(lsOrigin) || dynamic_cast<const NetworkLSA *>(lsOrigin)) {
1844 if (lsOrigin->getHeader().getLinkStateID() < routerVertex->getHeader().getLinkStateID()) {
1845 entry->setLinkStateOrigin(routerVertex);
1849 throw cRuntimeError(
"Can not cast class '%s' to RouterLSA or NetworkLSA", lsOrigin->getClassName());
1853 unsigned int nextHopCount = newNextHops->size();
1854 for (k = 0; k < nextHopCount; k++) {
1855 entry->addNextHop((*newNextHops)[k]);
1864 entry =
new RoutingTableEntry(
ift);
1866 entry->setDestination(IPv4Address(destinationID));
1867 entry->setNetmask(IPv4Address(link.getLinkData()));
1868 entry->setLinkStateOrigin(routerVertex);
1871 entry->setCost(distance);
1873 entry->setOptionalCapabilities(routerVertex->getHeader().getLsOptions());
1875 unsigned int nextHopCount = newNextHops->size();
1876 for (k = 0; k < nextHopCount; k++) {
1877 entry->addNextHop((*newNextHops)[k]);
1881 newRoutingTable.push_back(entry);
void setDistance(unsigned long d)
Definition: LSA.h:55
std::vector< NetworkLSA * > networkLSAs
Definition: OSPFArea.h:49
unsigned long Metric
Definition: OSPFcommon.h:64
Definition: OSPFInterface.h:66
Definition: OSPFRoutingTableEntry.h:39
Interface * getInterface(unsigned char ifIndex)
Definition: OSPFArea.cc:205
std::vector< RouterLSA * > routerLSAs
Definition: OSPFArea.h:47
RouterID getRouterID() const
Definition: OSPFRouter.h:72
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
bool installRouterLSA(OSPFRouterLSA *lsa)
Definition: OSPFArea.cc:261
unsigned char RoutingDestinationType
Definition: OSPFRoutingTableEntry.h:45
Definition: OSPFPacket_m.h:378
static const unsigned char NETWORK_DESTINATION
Definition: OSPFRoutingTableEntry.h:48
static const unsigned char AS_BOUNDARY_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:50
std::vector< NextHop > * calculateNextHops(OSPFLSA *destination, OSPFLSA *parent) const
Definition: OSPFArea.cc:1887
Definition: OSPFPacket_m.h:246
Area(IInterfaceTable *ift, AreaID id=BACKBONE_AREAID)
Definition: OSPFArea.cc:26
static const unsigned char AREA_BORDER_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:49
bool hasLink(OSPFLSA *fromLSA, OSPFLSA *toLSA) const
Definition: OSPFArea.cc:2124
Definition: OSPFPacket_m.h:377
RouterLSA * spfTreeRoot
Definition: OSPFArea.h:55
IPv4Address address
Definition: OSPFcommon.h:79
#define LS_INFINITY
Definition: TED.cc:32
LinkType
Enum generated from inet/routing/ospfv2/OSPFPacket.msg:115 by nedtool.
Definition: OSPFPacket_m.h:375
unsigned long getDistance() const
Definition: LSA.h:56
Area * getAreaByID(AreaID areaID)
Returns the pointer to the Area identified by the input areaID, if it's on the Area list...
Definition: OSPFRouter.cc:72
Definition: OSPFInterface.h:43
#define MAX_AGE
Definition: OSPFcommon.h:36
bool transitCapability
Definition: OSPFArea.h:52
IInterfaceTable * ift
Definition: OSPFArea.h:40
Definition: OSPFPacket_m.h:245
LSAType
Enum generated from inet/routing/ospfv2/OSPFPacket.msg:84 by nedtool.
Definition: OSPFPacket_m.h:244
IPv4AddressRange getAddressRange(unsigned int index) const
Definition: OSPFArea.h:67
RouterLSA * originateRouterLSA()
Definition: OSPFArea.cc:751
Router * parentRouter
Definition: OSPFArea.h:57
static const IPv4Address ALLONES_ADDRESS
255.255.255.255
Definition: IPv4Address.h:105
const double k
Definition: QAM16Modulation.cc:24
RouterLSA * findRouterLSA(LinkStateID linkStateID)
Definition: OSPFArea.cc:328
IPv4Address RouterID
Definition: OSPFcommon.h:137
AreaID areaID
Definition: OSPFArea.h:41
Definition: OSPFPacket_m.h:376
Interface * findVirtualLink(RouterID routerID)
Definition: OSPFArea.cc:248
NetworkLSA * findNetworkLSA(LinkStateID linkStateID)
Definition: OSPFArea.cc:350
bool floodLSA(OSPFLSA *lsa, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Definition: OSPFArea.cc:726