基于官网文档的 Routing Overview 部分详细研究一下ns3中路由是怎么工作的
文档链接16.4. Routing overview — Model Library
一、概述
NS3整体的工作架构如下:
路由部分的工作架构如下:
路由部分目前大多数用到的算法都包含在Ipv4RoutingProtocol部分:
二、 Ipv4RoutingProtocol
抽象基类 Ipv4RoutingProtocol () 声明了一个最小接口,由两个方法组成:RouteInput()和RouteOutput(),这两个方法通过定义接口决定了数据包传输的路径
简单理解,对于所有数据包,传输协议都需要向 Ipv4 查询 Ipv4RoutingProtocol 对象接口,并通过 Ipv4RoutingProtocol::RouteOutput () 请求路由,并返回一个指向 Ipv4Route 对象的 Ptr
主要的几类路由协议在单播路由中介绍:
- Ipv4ListRouting
用于在节点上储存一系列路由协议,根据优先级调用 - Ipv4StaticRouting
这个之前写过一篇如何配置静态路由的文章,不细讲了,就是手动指定通信链路的端口 - Ipv4GlobalRouting
安装InternetStackHelper时会默认添加的路由协议,采用的是OSPF算法,优先级低于静态路由,一般会在官方示例代码里看见这样给所有节点计算路由表:
如果发生了一些变化需要重新计算路由表:Ipv4GlobalRoutingHelper::PopulateRoutingTables();
路由表的计算还有两个属性可以修改:Ipv4GlobalRoutingHelper::RecomputeRoutingTables(); Simulator::Schedule(Seconds(5),&Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
① Ipv4GlobalRouting::RandomEcmpRouting:如果设置为 true,数据包将在等成本多路径路由上随机路由。如果设置为 false(默认值),则只持续使用一条路由。
②Ipv4GlobalRouting::RespondToInterfaceEvents:如果设置为 true,则会在发生接口通知事件(上/下或添加/删除地址)时动态地重新计算全局路由。如果设置为 false(默认值),路由可能会中断,除非用户在此类事件发生后手动调用 RecomputeRoutingTables()。
PS.这两个属性的修改要放在主程序最前面,在创建接口之前:Config::SetDefault("ns3::Ipv4GlobalRouting::RandomEcmpRouting", BooleanValue(true)); // enable multi-path routing
底层的源码在ns3目录下:src/internet/model/ipv4-global-routing.cc:
TypeId Ipv4GlobalRouting::GetTypeId (void) { static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting").SetParent<Object> ().SetGroupName ("Internet").AddAttribute ("RandomEcmpRouting","Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",BooleanValue (false),MakeBooleanAccessor (&Ipv4GlobalRouting::m_randomEcmpRouting),MakeBooleanChecker ()).AddAttribute ("RespondToInterfaceEvents","Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",BooleanValue (false),MakeBooleanAccessor (&Ipv4GlobalRouting::m_respondToInterfaceEvents),MakeBooleanChecker ());return tid; }
先生成所有可能的路径,然后再用随机数选择一条,否则默认选择第一条路径:
if (allRoutes.size () > 0 ) // if route(s) is found{// pick up one of the routes uniformly at random if random// ECMP routing is enabled, or always select the first route// consistently if random ECMP routing is disableduint32_t selectIndex;if (m_randomEcmpRouting){selectIndex = m_rand->GetInteger (0, allRoutes.size ()-1);}else {selectIndex = 0;}Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex); // create a Ipv4Route object from the selected routing table entryrtentry = Create<Ipv4Route> ();rtentry->SetDestination (route->GetDest ());/// \todo handle multi-address casertentry->SetSource (m_ipv4->GetAddress (route->GetInterface (), 0).GetLocal ());rtentry->SetGateway (route->GetGateway ());uint32_t interfaceIdx = route->GetInterface ();rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));return rtentry;}
传输的数据包速率、大小需要设置大一点,这样就可以看到RandomECMP同时用到多条路径进行传输的效果
路由部分的东西太多了,这篇先写到这里,下篇重点研究如何在ns3里面实现多路径路由