基于官网文档的 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 disabled uint32_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 entry rtentry = Create<Ipv4Route> (); rtentry->SetDestination (route->GetDest ()); /// \todo handle multi-address case rtentry->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里面实现多路径路由