1401 bool finished =
false;
1402 std::vector<Ospfv2Lsa *> treeVertices;
1403 Ospfv2Lsa *justAddedVertex;
1404 std::vector<Ospfv2Lsa *> candidateVertices;
1423 for (uint32_t i = 0; i <
routerLSAs.size(); i++)
1434 auto vertexType =
static_cast<Ospfv2LsaType>(justAddedVertex->getHeader().getLsType());
1437 RouterLsa *routerVertex = check_and_cast<RouterLsa *>(justAddedVertex);
1438 if (routerVertex->getV_VirtualLinkEndpoint()) {
1442 unsigned int linkCount = routerVertex->getLinksArraySize();
1443 for (uint32_t i = 0; i < linkCount; i++) {
1444 const auto& link = routerVertex->getLinks(i);
1446 Ospfv2Lsa *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 (uint32_t 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 Ospfv2Lsa *candidate =
nullptr;
1486 for (uint32_t 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 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1504 routingInfo->addNextHop(*it);
1509 RouterLsa *joiningRouterVertex = check_and_cast<RouterLsa *>(joiningVertex);
1510 joiningRouterVertex->setDistance(linkStateCost);
1511 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1512 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1513 joiningRouterVertex->addNextHop(*it);
1515 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningRouterVertex);
1516 vertexRoutingInfo->setParent(justAddedVertex);
1518 candidateVertices.push_back(joiningRouterVertex);
1521 NetworkLsa *joiningNetworkVertex = check_and_cast<NetworkLsa *>(joiningVertex);
1522 joiningNetworkVertex->setDistance(linkStateCost);
1523 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1524 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1525 joiningNetworkVertex->addNextHop(*it);
1527 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningNetworkVertex);
1528 vertexRoutingInfo->setParent(justAddedVertex);
1530 candidateVertices.push_back(joiningNetworkVertex);
1537 NetworkLsa *networkVertex = check_and_cast<NetworkLsa *>(justAddedVertex);
1538 unsigned int routerCount = networkVertex->getAttachedRoutersArraySize();
1540 for (uint32_t i = 0; i < routerCount; i++) {
1541 RouterLsa *joiningVertex =
findRouterLSA(networkVertex->getAttachedRouters(i));
1542 if ((joiningVertex ==
nullptr) ||
1543 (joiningVertex->getHeader().getLsAge() ==
MAX_AGE) ||
1544 (!
hasLink(joiningVertex, justAddedVertex)))
1549 unsigned int treeSize = treeVertices.size();
1550 bool alreadyOnTree =
false;
1552 for (uint32_t j = 0; j < treeSize; j++) {
1553 if (treeVertices[j] == joiningVertex) {
1554 alreadyOnTree =
true;
1558 if (alreadyOnTree) {
1562 unsigned long linkStateCost = networkVertex->getDistance();
1563 unsigned int candidateCount = candidateVertices.size();
1564 Ospfv2Lsa *candidate =
nullptr;
1566 for (uint32_t j = 0; j < candidateCount; j++) {
1567 if (candidateVertices[j] == joiningVertex) {
1568 candidate = candidateVertices[j];
1571 if (candidate !=
nullptr) {
1572 RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(candidate);
1573 unsigned long candidateDistance = routingInfo->getDistance();
1575 if (linkStateCost > candidateDistance) {
1578 if (linkStateCost < candidateDistance) {
1579 routingInfo->setDistance(linkStateCost);
1580 routingInfo->clearNextHops();
1582 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1583 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1584 routingInfo->addNextHop(*it);
1588 joiningVertex->setDistance(linkStateCost);
1589 std::vector<NextHop> *newNextHops =
calculateNextHops(joiningVertex, justAddedVertex);
1590 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1591 joiningVertex->addNextHop(*it);
1593 RoutingInfo *vertexRoutingInfo = check_and_cast<RoutingInfo *>(joiningVertex);
1594 vertexRoutingInfo->setParent(justAddedVertex);
1596 candidateVertices.push_back(joiningVertex);
1601 if (candidateVertices.empty()) {
1605 unsigned int candidateCount = candidateVertices.size();
1607 Ospfv2Lsa *closestVertex = candidateVertices[0];
1609 for (uint32_t i = 0; i < candidateCount; i++) {
1610 RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(candidateVertices[i]);
1611 unsigned long currentDistance = routingInfo->getDistance();
1613 if (currentDistance < minDistance) {
1614 closestVertex = candidateVertices[i];
1615 minDistance = currentDistance;
1618 if (currentDistance == minDistance) {
1619 if ((closestVertex->getHeader().getLsType() ==
ROUTERLSA_TYPE) &&
1622 closestVertex = candidateVertices[i];
1628 treeVertices.push_back(closestVertex);
1630 for (
auto it = candidateVertices.begin(); it != candidateVertices.end(); it++) {
1631 if ((*it) == closestVertex) {
1632 candidateVertices.erase(it);
1638 RouterLsa *routerLSA = check_and_cast<RouterLsa *>(closestVertex);
1639 if (routerLSA->getB_AreaBorderRouter() || routerLSA->getE_ASBoundaryRouter()) {
1640 Ospfv2RoutingTableEntry *entry =
new Ospfv2RoutingTableEntry(
ift);
1641 RouterId destinationID = routerLSA->getHeader().getLinkStateID();
1642 unsigned int nextHopCount = routerLSA->getNextHopCount();
1645 entry->setDestination(destinationID);
1646 entry->setLinkStateOrigin(routerLSA);
1649 entry->setCost(routerLSA->getDistance());
1650 if (routerLSA->getB_AreaBorderRouter()) {
1653 if (routerLSA->getE_ASBoundaryRouter()) {
1656 entry->setDestinationType(destinationType);
1657 entry->setOptionalCapabilities(routerLSA->getHeader().getLsOptions());
1658 for (uint32_t i = 0; i < nextHopCount; i++) {
1659 entry->addNextHop(routerLSA->getNextHop(i));
1662 newRoutingTable.push_back(entry);
1671 if (backbone !=
nullptr) {
1672 Ospfv2Interface *virtualIntf = backbone->
findVirtualLink(destinationID);
1673 if ((virtualIntf !=
nullptr) && (virtualIntf->getTransitAreaId() ==
areaID)) {
1674 Ipv4AddressRange range;
1677 virtualIntf->setAddressRange(range);
1678 virtualIntf->setIfIndex(
ift, routerLSA->getNextHop(0).ifIndex);
1679 virtualIntf->setOutputCost(routerLSA->getDistance());
1680 Neighbor *virtualNeighbor = virtualIntf->getNeighbor(0);
1681 if (virtualNeighbor !=
nullptr) {
1682 unsigned int linkCount = routerLSA->getLinksArraySize();
1683 RouterLsa *toRouterLSA =
dynamic_cast<RouterLsa *
>(justAddedVertex);
1684 if (toRouterLSA !=
nullptr) {
1685 for (uint32_t i = 0; i < linkCount; i++) {
1686 const auto& link = routerLSA->getLinks(i);
1689 (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) &&
1692 virtualNeighbor->setAddress(Ipv4Address(link.getLinkData()));
1699 NetworkLsa *toNetworkLSA =
dynamic_cast<NetworkLsa *
>(justAddedVertex);
1700 if (toNetworkLSA !=
nullptr) {
1701 for (uint32_t i = 0; i < linkCount; i++) {
1702 const auto& link = routerLSA->getLinks(i);
1705 (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()) &&
1708 virtualNeighbor->setAddress(Ipv4Address(link.getLinkData()));
1722 NetworkLsa *networkLSA = check_and_cast<NetworkLsa *>(closestVertex);
1723 Ipv4Address destinationID = (networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask());
1724 unsigned int nextHopCount = networkLSA->getNextHopCount();
1725 bool overWrite =
false;
1726 Ospfv2RoutingTableEntry *entry =
nullptr;
1727 unsigned long routeCount = newRoutingTable.size();
1728 Ipv4Address longestMatch(0u);
1730 for (uint32_t i = 0; i < routeCount; i++) {
1732 Ospfv2RoutingTableEntry *routingEntry = newRoutingTable[i];
1733 Ipv4Address entryAddress = routingEntry->getDestination();
1734 Ipv4Address entryMask = routingEntry->getNetmask();
1736 if ((entryAddress & entryMask) == (destinationID & entryMask)) {
1737 if ((destinationID & entryMask) > longestMatch) {
1738 longestMatch = (destinationID & entryMask);
1739 entry = routingEntry;
1744 if (entry !=
nullptr) {
1745 const Ospfv2Lsa *entryOrigin = entry->getLinkStateOrigin();
1746 if ((entry->getCost() != networkLSA->getDistance()) ||
1747 (entryOrigin->getHeader().getLinkStateID() >= networkLSA->getHeader().getLinkStateID()))
1753 if ((entry ==
nullptr) || (overWrite)) {
1754 if (entry ==
nullptr) {
1755 entry =
new Ospfv2RoutingTableEntry(
ift);
1758 entry->setDestination(Ipv4Address(destinationID));
1759 entry->setNetmask(networkLSA->getNetworkMask());
1760 entry->setLinkStateOrigin(networkLSA);
1763 entry->setCost(networkLSA->getDistance());
1765 entry->setOptionalCapabilities(networkLSA->getHeader().getLsOptions());
1766 for (uint32_t i = 0; i < nextHopCount; i++) {
1767 entry->addNextHop(networkLSA->getNextHop(i));
1771 newRoutingTable.push_back(entry);
1776 justAddedVertex = closestVertex;
1778 }
while (!finished);
1782 bool onTree =
false;
1783 for (
auto& node : treeVertices) {
1784 if (node == routerLSA) {
1792 routerLSA->setParent(
nullptr);
1797 bool onTree =
false;
1798 for (
auto& node : treeVertices) {
1799 if (node == networkLSA) {
1807 networkLSA->setParent(
nullptr);
1811 for (uint32_t i = 0; i < treeVertices.size(); i++) {
1812 RouterLsa *routerVertex =
dynamic_cast<RouterLsa *
>(treeVertices[i]);
1813 if (routerVertex ==
nullptr)
1816 for (uint32_t j = 0; j < routerVertex->getLinksArraySize(); j++) {
1817 const auto& link = routerVertex->getLinks(j);
1821 unsigned long destinationID = (link.getLinkID().getInt() & link.getLinkData());
1822 Ospfv2RoutingTableEntry *entry =
nullptr;
1823 unsigned long longestMatch = 0;
1825 for (
auto routingEntry : newRoutingTable) {
1827 unsigned long entryAddress = routingEntry->getDestination().getInt();
1828 unsigned long entryMask = routingEntry->getNetmask().getInt();
1830 if ((entryAddress & entryMask) == (destinationID & entryMask)) {
1831 if ((destinationID & entryMask) > longestMatch) {
1832 longestMatch = (destinationID & entryMask);
1833 entry = routingEntry;
1839 unsigned long distance = routerVertex->getDistance() + link.getLinkCost();
1841 if (entry !=
nullptr) {
1842 Metric entryCost = entry->getCost();
1844 if (distance > entryCost)
1846 else if (distance < entryCost) {
1847 entry->setCost(distance);
1848 entry->clearNextHops();
1849 entry->setLinkStateOrigin(routerVertex);
1851 else if (distance == entryCost) {
1853 const Ospfv2Lsa *lsOrigin = entry->getLinkStateOrigin();
1854 if (
dynamic_cast<const RouterLsa *
>(lsOrigin) ||
dynamic_cast<const NetworkLsa *
>(lsOrigin)) {
1855 if (lsOrigin->getHeader().getLinkStateID() < routerVertex->getHeader().getLinkStateID())
1856 entry->setLinkStateOrigin(routerVertex);
1859 throw cRuntimeError(
"Can not cast class '%s' to RouterLsa or NetworkLsa", lsOrigin->getClassName());
1863 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1864 entry->addNextHop(*it);
1868 entry =
new Ospfv2RoutingTableEntry(
ift);
1870 entry->setDestination(Ipv4Address(destinationID));
1871 entry->setNetmask(Ipv4Address(link.getLinkData()));
1872 entry->setLinkStateOrigin(routerVertex);
1875 entry->setCost(distance);
1877 entry->setOptionalCapabilities(routerVertex->getHeader().getLsOptions());
1879 for (
auto it = newNextHops->begin(); it != newNextHops->end(); ++it)
1880 entry->addNextHop(*it);
1883 newRoutingTable.push_back(entry);