|
249 |
RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const |
249 |
RoutingProtocol::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const |
250 |
{ |
250 |
{ |
251 |
std::ostream* os = stream->GetStream(); |
251 |
std::ostream* os = stream->GetStream(); |
252 |
*os << "Destination\tNextHop\t\tInterface\tDistance\n"; |
252 |
*os << "Destination\t\tNextHop\t\tInterface\tDistance\n"; |
253 |
|
253 |
|
254 |
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); |
254 |
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); |
255 |
iter != m_table.end (); iter++) |
255 |
iter != m_table.end (); iter++) |
256 |
{ |
256 |
{ |
257 |
*os << iter->first << "\t"; |
257 |
*os << iter->first << "\t\t"; |
258 |
*os << iter->second.nextAddr << "\t"; |
258 |
*os << iter->second.nextAddr << "\t\t"; |
259 |
if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "") |
259 |
if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "") |
260 |
{ |
260 |
{ |
261 |
*os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t"; |
261 |
*os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t"; |
|
268 |
*os << iter->second.distance << "\t"; |
268 |
*os << iter->second.distance << "\t"; |
269 |
*os << "\n"; |
269 |
*os << "\n"; |
270 |
} |
270 |
} |
|
|
271 |
// Also print the HNA routing table |
272 |
*os << " HNA Routing Table:\n"; |
273 |
m_hnaRoutingTable->PrintRoutingTable(stream); |
271 |
} |
274 |
} |
272 |
|
275 |
|
273 |
void RoutingProtocol::DoStart () |
276 |
void RoutingProtocol::DoStart () |
|
1105 |
// 5. For each tuple in the association set, |
1108 |
// 5. For each tuple in the association set, |
1106 |
// If there is no entry in the routing table with: |
1109 |
// If there is no entry in the routing table with: |
1107 |
// R_dest_addr == A_network_addr/A_netmask |
1110 |
// R_dest_addr == A_network_addr/A_netmask |
|
|
1111 |
// and if the announced network is not announced by the node itself, |
1108 |
// then a new routing entry is created. |
1112 |
// then a new routing entry is created. |
1109 |
const AssociationSet &associationSet = m_state.GetAssociationSet (); |
1113 |
const AssociationSet &associationSet = m_state.GetAssociationSet(); |
1110 |
for (AssociationSet::const_iterator it = associationSet.begin (); |
1114 |
for (AssociationSet::const_iterator it = associationSet.begin(); |
1111 |
it != associationSet.end (); it++) |
1115 |
it != associationSet.end(); it++) { |
1112 |
{ |
|
|
1113 |
AssociationTuple const &tuple = *it; |
1116 |
AssociationTuple const &tuple = *it; |
|
|
1117 |
|
1118 |
// Test if HNA associations received from other gateways |
1119 |
// are also announced by this node. In such a case, no route |
1120 |
// is created for this association tuple (go to the next one). |
1121 |
bool goToNextAssociationTuple = false; |
1122 |
const Associations &localHnaAssociations = m_state.GetAssociations(); |
1123 |
NS_LOG_DEBUG("Nb local associations: " << localHnaAssociations.size()); |
1124 |
for (Associations::const_iterator assocIterator = localHnaAssociations.begin(); |
1125 |
assocIterator != localHnaAssociations.end(); assocIterator++) { |
1126 |
Association const &localHnaAssoc = *assocIterator; |
1127 |
if (localHnaAssoc.networkAddr == tuple.networkAddr && |
1128 |
localHnaAssoc.netmask == tuple.netmask) { |
1129 |
NS_LOG_DEBUG("HNA association received from another GW is part of local HNA associations: no route added for network " << tuple.networkAddr << "/" << tuple.netmask); |
1130 |
goToNextAssociationTuple = true; |
1131 |
} |
1132 |
} |
1133 |
if (goToNextAssociationTuple) continue; |
1134 |
|
1114 |
RoutingTableEntry gatewayEntry; |
1135 |
RoutingTableEntry gatewayEntry; |
1115 |
|
1136 |
|
1116 |
bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry); |
1137 |
bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry); |
|
1823 |
std::vector<olsr::MessageHeader::Hna::Association> |
1844 |
std::vector<olsr::MessageHeader::Hna::Association> |
1824 |
&associations = hna.associations; |
1845 |
&associations = hna.associations; |
1825 |
|
1846 |
|
1826 |
if (m_routingTableAssociation != 0) |
1847 |
// Add all local HNA associations to the HNA message |
1827 |
{ |
1848 |
const Associations &localHnaAssociations = m_state.GetAssociations(); |
1828 |
// Add (NetworkAddr, Netmask) entries from Associated Routing Table to HNA message. |
1849 |
for (Associations::const_iterator it = localHnaAssociations.begin(); |
1829 |
for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++) |
1850 |
it != localHnaAssociations.end(); it++) { |
1830 |
{ |
|
|
1831 |
Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i); |
1832 |
|
1833 |
std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ()); |
1834 |
|
1835 |
if (ci != m_interfaceExclusions.end ()) |
1836 |
{ |
1837 |
olsr::MessageHeader::Hna::Association assoc = {route.GetDestNetwork (), route.GetDestNetworkMask ()}; |
1838 |
associations.push_back(assoc); |
1839 |
} |
1840 |
} |
1841 |
} |
1842 |
|
1843 |
int size = associations.size (); |
1844 |
|
1845 |
// Add (NetworkAddr, Netmask) entries specified using AddHostNetworkAssociation () to HNA message. |
1846 |
for (Associations::const_iterator it = m_state.GetAssociations ().begin (); |
1847 |
it != m_state.GetAssociations ().end (); it++) |
1848 |
{ |
1849 |
// Check if the entry has already been added from the Associated Routing Table |
1850 |
std::vector<olsr::MessageHeader::Hna::Association>::const_iterator ci = associations.begin (); |
1851 |
bool found = false; |
1852 |
for (int i = 0; i < size; i++) |
1853 |
{ |
1854 |
if (it->networkAddr == ci->address && it->netmask == ci->mask) |
1855 |
{ |
1856 |
found = true; |
1857 |
break; |
1858 |
} |
1859 |
ci++; |
1860 |
} |
1861 |
|
1862 |
if(!found) |
1863 |
{ |
1864 |
olsr::MessageHeader::Hna::Association assoc = {it->networkAddr,it->netmask}; |
1851 |
olsr::MessageHeader::Hna::Association assoc = {it->networkAddr,it->netmask}; |
1865 |
associations.push_back(assoc); |
1852 |
associations.push_back(assoc); |
1866 |
} |
1853 |
} |
1867 |
} |
1854 |
// If there is no HNA associations to send |
1868 |
|
1855 |
if (associations.size() == 0) { |
1869 |
if(associations.size () == 0) |
1856 |
// return without queuing the message |
1870 |
return; |
1857 |
return; |
1871 |
|
1858 |
} |
|
|
1859 |
// Else, queue the message to be sent later on |
1872 |
QueueMessage (msg, JITTER); |
1860 |
QueueMessage (msg, JITTER); |
1873 |
} |
1861 |
} |
1874 |
|
1862 |
|
1875 |
/// |
1863 |
/// |
1876 |
/// \brief Injects a (networkAddr, netmask) tuple for which the node |
1864 |
/// \brief Injects the specified (networkAddr, netmask) tuple in the list of |
1877 |
/// can generate an HNA message for |
1865 |
/// local HNA associations to be sent by the node via HNA messages. |
|
|
1866 |
/// If this tuple already exists, nothing is done. |
1878 |
/// |
1867 |
/// |
1879 |
void |
1868 |
void |
1880 |
RoutingProtocol::AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask) |
1869 |
RoutingProtocol::AddHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask) |
1881 |
{ |
1870 |
{ |
1882 |
m_state.InsertAssociation ((Association) {networkAddr, netmask}); |
1871 |
// Check if the (networkAddr, netmask) tuple already exist |
|
|
1872 |
// in the list of local HNA associations |
1873 |
const Associations &localHnaAssociations = m_state.GetAssociations(); |
1874 |
//TODO Could not the GetAssociations() method return a set rather than |
1875 |
// a vector? The std::vector does not provide a "find(element)" method |
1876 |
// that would be very useful right here... |
1877 |
for (Associations::const_iterator assocIterator = localHnaAssociations.begin(); |
1878 |
assocIterator != localHnaAssociations.end(); assocIterator++) { |
1879 |
Association const &localHnaAssoc = *assocIterator; |
1880 |
if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask) { |
1881 |
NS_LOG_INFO("HNA association for network " << networkAddr << "/" << netmask << " already exists."); |
1882 |
return; |
1883 |
} |
1884 |
} |
1885 |
// If the tuple does not already exist, add it to the list of local HNA associations. |
1886 |
NS_LOG_INFO("Adding HNA association for network " << networkAddr << "/" << netmask << "."); |
1887 |
m_state.InsertAssociation( (Association) {networkAddr, netmask} ); |
1888 |
} |
1889 |
|
1890 |
/// |
1891 |
/// \brief Removes the specified (networkAddr, netmask) tuple from the list of |
1892 |
/// local HNA associations to be sent by the node via HNA messages. |
1893 |
/// If this tuple does not exist, nothing is done (see "OlsrState::EraseAssociation()"). |
1894 |
/// |
1895 |
void |
1896 |
RoutingProtocol::RemoveHostNetworkAssociation (Ipv4Address networkAddr, Ipv4Mask netmask) |
1897 |
{ |
1898 |
NS_LOG_INFO("Removing HNA association for network " << networkAddr << "/" << netmask << "."); |
1899 |
m_state.EraseAssociation( (Association) {networkAddr, netmask} ); |
1883 |
} |
1900 |
} |
1884 |
|
1901 |
|
1885 |
/// |
1902 |
/// |
1886 |
/// \brief Adds an Ipv4StaticRouting protocol Association |
1903 |
/// \brief Associates the specified Ipv4StaticRouting routing table |
1887 |
/// can generate an HNA message for |
1904 |
/// to the OLSR routing protocol. Entries from this associated |
|
|
1905 |
/// routing table that use non-olsr outgoing interfaces are added |
1906 |
/// to the list of local HNA associations so that they are included |
1907 |
/// in HNA messages sent by the node. |
1908 |
/// If this method is called more than once, entries from the old |
1909 |
/// association are deleted before entries from the new one are added. |
1910 |
/// \param the Ipv4StaticRouting routing table to be associated. |
1888 |
/// |
1911 |
/// |
1889 |
void |
1912 |
void |
1890 |
RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable) |
1913 |
RoutingProtocol::SetRoutingTableAssociation (Ptr<Ipv4StaticRouting> routingTable) |
1891 |
{ |
1914 |
{ |
|
|
1915 |
// If a routing table has already been associated, remove |
1916 |
// corresponding entries from the list of local HNA associations |
1917 |
if (m_routingTableAssociation != 0) { |
1918 |
NS_LOG_INFO("Removing HNA entries coming from the old routing table association."); |
1919 |
for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes(); i++) { |
1920 |
Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute(i); |
1921 |
// If the outgoing interface for this route is a non-olsr interface |
1922 |
if (UsesNonOlsrOutgoingInterface(route)) { |
1923 |
// remove the corresponding entry |
1924 |
RemoveHostNetworkAssociation(route.GetDestNetwork(), route.GetDestNetworkMask()); |
1925 |
} |
1926 |
} |
1927 |
} |
1928 |
|
1929 |
// Sets the routingTableAssociation to its new value |
1892 |
m_routingTableAssociation = routingTable; |
1930 |
m_routingTableAssociation = routingTable; |
|
|
1931 |
|
1932 |
// Iterate over entries of the associated routing table and |
1933 |
// add the routes using non-olsr outgoing interfaces to the list |
1934 |
// of local HNA associations |
1935 |
const Associations &localHnaAssociations = m_state.GetAssociations(); //Just for logging |
1936 |
NS_LOG_DEBUG("Nb local associations before adding some entries from the associated routing table: " << localHnaAssociations.size()); |
1937 |
for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes(); i++) { |
1938 |
Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute(i); |
1939 |
Ipv4Address destNetworkAddress = route.GetDestNetwork(); |
1940 |
Ipv4Mask destNetmask = route.GetDestNetworkMask(); |
1941 |
|
1942 |
// If the outgoing interface for this route is a non-olsr interface |
1943 |
if (UsesNonOlsrOutgoingInterface(route)) { |
1944 |
// Add this entry's network address and netmask to the list of local HNA entries |
1945 |
AddHostNetworkAssociation(destNetworkAddress, destNetmask); |
1946 |
} |
1947 |
} |
1948 |
NS_LOG_DEBUG("Nb local associations after having added some entries from the associated routing table: " << localHnaAssociations.size()); |
1949 |
} |
1950 |
|
1951 |
/// |
1952 |
/// \brief Tests whether or not the specified route uses a non-OLSR outgoing interface. |
1953 |
/// Returns true if the outgoing interface of the specified route is a non-OLSR interface. |
1954 |
/// Returns false otherwise. |
1955 |
/// |
1956 |
bool RoutingProtocol::UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route) { |
1957 |
std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find(route.GetInterface()); |
1958 |
// The outgoing interface is a non-OLSR interface if a match is found |
1959 |
// before reaching the end of the list of excluded interfaces |
1960 |
return ci != m_interfaceExclusions.end(); |
1893 |
} |
1961 |
} |
1894 |
|
1962 |
|
1895 |
/// |
1963 |
/// |
|
2652 |
|
2720 |
|
2653 |
/// |
2721 |
/// |
2654 |
/// \brief Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer. |
2722 |
/// \brief Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer. |
2655 |
/// \param e The event which has expired. |
|
|
2656 |
/// |
2723 |
/// |
2657 |
void |
2724 |
void |
2658 |
RoutingProtocol::HnaTimerExpire () |
2725 |
RoutingProtocol::HnaTimerExpire () |
2659 |
{ |
2726 |
{ |
2660 |
if (m_state.GetAssociations ().size () > 0 || m_routingTableAssociation !=0) |
2727 |
if (m_state.GetAssociations().size() > 0) { |
2661 |
{ |
2728 |
SendHna(); |
2662 |
SendHna (); |
|
|
2663 |
} |
2729 |
} |
2664 |
else |
2730 |
else { |
2665 |
{ |
2731 |
NS_LOG_DEBUG("Not sending any HNA, no associations to advertise."); |
2666 |
NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise."); |
|
|
2667 |
} |
2732 |
} |
2668 |
m_hnaTimer.Schedule (m_hnaInterval); |
2733 |
m_hnaTimer.Schedule (m_hnaInterval); |
2669 |
} |
2734 |
} |