src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc
changeset 4793 4f6a6772628e
child 4797 9902003078aa
equal deleted inserted replaced
4244:7c98934dcccd 4793:4f6a6772628e
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2008,2009 IITP RAS
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License version 2 as 
       
     7  * published by the Free Software Foundation;
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    17  *
       
    18  * Author: Kirill Andreev <andreev@iitp.ru>
       
    19  */
       
    20 
       
    21 
       
    22 #include "ns3/object.h"
       
    23 #include "ns3/assert.h"
       
    24 #include "ns3/simulator.h"
       
    25 #include "ns3/ptr.h"
       
    26 #include "ns3/log.h"
       
    27 #include "ns3/node.h"
       
    28 #include "hwmp-rtable.h"
       
    29 
       
    30 NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
       
    31 
       
    32 namespace ns3 {
       
    33 
       
    34 NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
       
    35 
       
    36 TypeId
       
    37 HwmpRtable::GetTypeId(void)
       
    38 {
       
    39 	static TypeId tid = TypeId ("ns3::HwmpRtable")
       
    40 		.SetParent<Object> ()
       
    41 		.AddConstructor<HwmpRtable> ();
       
    42 	return tid;
       
    43 
       
    44 }
       
    45 
       
    46 HwmpRtable::HwmpRtable()
       
    47 {
       
    48 }
       
    49 
       
    50 HwmpRtable::~HwmpRtable()
       
    51 {
       
    52 	DoDispose();
       
    53 }
       
    54 
       
    55 void
       
    56 HwmpRtable::DoDispose()
       
    57 {
       
    58 	NS_LOG_UNCOND("RTABLE DISPOSE STARTED");
       
    59 	m_routes.clear();
       
    60 	m_roots.clear();
       
    61 }
       
    62 
       
    63 void
       
    64 HwmpRtable::AddReactivePath(
       
    65 		Mac48Address	destination,
       
    66 		Mac48Address	retransmitter,
       
    67 		uint32_t	port,
       
    68 		uint32_t	metric,
       
    69 		Time		lifetime,
       
    70 		uint32_t	seqnum
       
    71 		)
       
    72 {
       
    73 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
       
    74 	if(i == m_routes.end())
       
    75 	{
       
    76 		struct ReactiveRoute newroute;
       
    77 		m_routes[destination] = newroute;
       
    78 	}
       
    79 	else
       
    80 	{
       
    81 		/**
       
    82 		 * if outport differs from stored, routing info is
       
    83 		 * actual and metric is worse - we ignore this
       
    84 		 * information
       
    85 		 */
       
    86 		if(
       
    87 				(i->second.port != port) &&
       
    88 				(i->second.metric < metric) &&
       
    89 				/**
       
    90 				 * The routing info is actual or it
       
    91 				 * was received from peer
       
    92 				 */
       
    93 				((i->second.whenExpire > Simulator::Now())||(i->second.whenExpire == Seconds(0)))
       
    94 				)
       
    95 			return;
       
    96 	}
       
    97 	i = m_routes.find(destination);
       
    98 	NS_ASSERT(i != m_routes.end());
       
    99 	i->second.retransmitter = retransmitter;
       
   100 	i->second.port = port;
       
   101 	i->second.metric = metric;
       
   102 	if(lifetime != Seconds(0))
       
   103 		i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
       
   104 	else
       
   105 		/**
       
   106 		 * Information about peer does not have lifetime
       
   107 		 */
       
   108 		i->second.whenExpire = Seconds(0);
       
   109 	i->second.seqnum = seqnum;
       
   110 }
       
   111 
       
   112 void
       
   113 HwmpRtable::AddProactivePath(
       
   114 		uint32_t	metric,
       
   115 		Mac48Address	root,
       
   116 		Mac48Address	retransmitter,
       
   117 		uint32_t	port,
       
   118 		Time		lifetime,
       
   119 		uint32_t	seqnum
       
   120 		)
       
   121 {
       
   122 	struct ProactiveRoute newroute;
       
   123 	m_roots[port] = newroute;
       
   124 	std::map<uint32_t,struct ProactiveRoute>::iterator i = m_roots.find(port);
       
   125 	NS_ASSERT(i != m_roots.end());
       
   126 	i->second.root = root;
       
   127 	i->second.retransmitter = retransmitter;
       
   128 	i->second.metric = metric;
       
   129 	i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
       
   130 	i->second.seqnum = seqnum;
       
   131 
       
   132 }
       
   133 
       
   134 void
       
   135 HwmpRtable::AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor)
       
   136 {
       
   137 	bool should_add = true;
       
   138 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
       
   139 	if((i != m_routes.end()) && (i->second.port == port))
       
   140 	{
       
   141 		for(unsigned int j = 0 ; j < i->second.precursors.size(); j ++)
       
   142 			if(i->second.precursors[j] == precursor)
       
   143 			{
       
   144 				should_add = false;
       
   145 				break;
       
   146 			}
       
   147 		if(should_add)
       
   148 			i->second.precursors.push_back(precursor);
       
   149 	}
       
   150 	std::map<uint32_t,struct ProactiveRoute>::iterator k = m_roots.find(port);
       
   151 	if(k!= m_roots.end())
       
   152 	{
       
   153 		for(unsigned int j = 0 ; j < k->second.precursors.size(); j ++)
       
   154 			if(k->second.precursors[j] == precursor)
       
   155 				return;
       
   156 		k->second.precursors.push_back(precursor);
       
   157 		return;
       
   158 	}
       
   159 }
       
   160 
       
   161 void
       
   162 HwmpRtable::DeleteProactivePath(uint32_t port)
       
   163 {
       
   164 	std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
       
   165 	if(j != m_roots.end())
       
   166 		m_roots.erase(j);
       
   167 
       
   168 }
       
   169 void
       
   170 HwmpRtable::DeleteProactivePath(Mac48Address root, uint32_t port)
       
   171 {
       
   172 	std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
       
   173 	if((j != m_roots.end())&&(j->second.root == root))
       
   174 		m_roots.erase(j);
       
   175 
       
   176 }
       
   177 
       
   178 void
       
   179 HwmpRtable::DeleteReactivePath(Mac48Address destination, uint32_t port)
       
   180 {
       
   181 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
       
   182 	if(i != m_routes.end())
       
   183 		if(i->second.port ==  port)
       
   184 			m_routes.erase(i);
       
   185 }
       
   186 
       
   187 struct HwmpRtable::LookupResult
       
   188 HwmpRtable::LookupReactive(Mac48Address destination)
       
   189 {
       
   190 	struct LookupResult result;
       
   191 	result.retransmitter = Mac48Address::GetBroadcast();
       
   192 	result.metric = MAX_METRIC;
       
   193 	result.ifIndex = PORT_ANY;
       
   194 	
       
   195 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
       
   196 	if(i == m_routes.end())
       
   197 		return result;
       
   198 	result.ifIndex = i->second.port;
       
   199 	//Seconds(0) means that this is routing
       
   200 	if(i->second.whenExpire < Simulator::Now())
       
   201 		if(i->second.retransmitter != destination)
       
   202 			return result;
       
   203 	result.retransmitter = i->second.retransmitter;
       
   204 	result.metric = i->second.metric;
       
   205 	result.seqnum = i->second.seqnum;
       
   206 	return result;
       
   207 }
       
   208 
       
   209 struct HwmpRtable::LookupResult
       
   210 HwmpRtable::LookupProactive(uint32_t port)
       
   211 {
       
   212 	struct LookupResult result;
       
   213 	result.retransmitter = Mac48Address::GetBroadcast();
       
   214 	result.metric = MAX_METRIC;
       
   215 	result.ifIndex = PORT_ANY;
       
   216 	std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
       
   217 	if(i == m_roots.end())
       
   218 		return result;
       
   219 	result.ifIndex = i->first;
       
   220 	if(i->second.whenExpire < Simulator::Now())
       
   221 		return result;
       
   222 	result.retransmitter = i->second.retransmitter;
       
   223 	result.metric = i->second.metric;
       
   224 	result.seqnum = i->second.seqnum;
       
   225 	return result;
       
   226 }
       
   227 
       
   228 std::vector<struct HwmpRtable::FailedDestination>
       
   229 HwmpRtable::GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port)
       
   230 {
       
   231 	std::vector<struct FailedDestination> retval;
       
   232 	for(std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.begin(); i!= m_routes.end(); i++)
       
   233 		if((i->second.retransmitter == peerAddress)&&(i->second.port == port))
       
   234 		{
       
   235 			struct FailedDestination dst;
       
   236 			dst.destination = i->first;
       
   237 			i->second.seqnum ++;
       
   238 			dst.seqnum = i->second.seqnum;
       
   239 			retval.push_back(dst);
       
   240 		}
       
   241 	/**
       
   242 	 * Lookup a path to root
       
   243 	 */
       
   244 	std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
       
   245 	if((i != m_roots.end())&&(i->second.retransmitter == peerAddress))
       
   246 	{
       
   247 		struct FailedDestination dst;
       
   248 		dst.destination = i->second.root;
       
   249 		dst.seqnum = i->second.seqnum;
       
   250 		retval.push_back(dst);
       
   251 	}
       
   252 	return retval;
       
   253 }
       
   254 uint32_t
       
   255 HwmpRtable::RequestSeqnum(Mac48Address destination)
       
   256 {
       
   257 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
       
   258 	if(i == m_routes.end())
       
   259 		return 0;
       
   260 	return i->second.seqnum;
       
   261 }
       
   262 
       
   263 std::vector<Mac48Address>
       
   264 HwmpRtable::GetPrecursors(Mac48Address destination, uint32_t port)
       
   265 {
       
   266 	std::vector<Mac48Address> retval;
       
   267 	std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator root = m_roots.find(port);
       
   268 	if((root != m_roots.end()) &&(root->second.root == destination))
       
   269 	{
       
   270 		for(unsigned int i = 0; i < root->second.precursors.size(); i ++)
       
   271 			retval.push_back(root->second.precursors[i]);
       
   272 	}
       
   273 	std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator route = m_routes.find(destination);
       
   274 	if( (route != m_routes.end()) && (route->second.port == port) )
       
   275 	{
       
   276 		for(unsigned int i = 0; i < route->second.precursors.size(); i ++)
       
   277 			retval.push_back(route->second.precursors[i]);
       
   278 	}
       
   279 	return retval;
       
   280 }
       
   281 
       
   282 }//namespace ns3