本文记录了基于NS3仿真软件的ETX-AODV路由协议的复现过程(本文章中仅展现最基础代码逻辑,具体代码请访问github仓库查看)

源代码仓库:https://github.com/leiSHOW/ETX_AODV

本篇博客将参考原论文中对于ETX-AODV路由协议的描述,在 ns-3 中基于 ETX (Expected Transmission Count) 这一路由度量来改进 AODV 路由协议,所以本文在之后将从 路由发现 路由维护 数据包转发 等方面说明应该如何在原有的 AODV 协议中使用 ETX 度量作为路由度量的指标。

1. 初始化阶段

在 AODV 协议初始化时,我们需要添加对 ETX 度量的支持,包括启用 ETX 计算并初始化相关的定时器、变量等

函数和变量:

  • RoutingProtocol::SetEtxEnable():启用 ETX 度量

  • RoutingProtocol::m_enableEtx:一个布尔值,标记是否启用 ETX 度量

  • RoutingProtocol::m_nbEtx:用于存储邻居节点的 ETX 信息

void RoutingProtocol::SetEtxEnable (bool f) {
    m_enableEtx = f;
}

bool RoutingProtocol::GetEtxEnable () const {
    return m_enableEtx;
}

2. ETX 度量计算

ETX 度量通常通过发送链路探测包(Link Probe Packets,LPP)来估算链路的质量。这些包用于定期测试节点之间的链路质量,并更新链路的 ETX 值。我们需要在 AODV 中引入链路探测包的发送和接收机制

函数:

  • RoutingProtocol::SendLpp():发送链路探测包

  • RoutingProtocol::RecvLpp():接收链路探测包,并更新 ETX 值

void RoutingProtocol::SendLpp () {
    // 发送链路探测包的逻辑
}

void RoutingProtocol::RecvLpp (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src) {
    // 接收链路探测包并更新链路的 ETX 信息
}

3. 路由发现阶段(RREQ和RREP的ETX优化)

在 AODV 的路由发现过程中,使用 ETX 度量来选择链路质量最好的路径。具体而言,当一个节点发送 RREQ 时,它需要考虑链路的 ETX 值。同时,当节点收到 RREP 时,应该选择 ETX 尽可能较低的路径

函数:

  • RoutingProtocol::SendRequest():发送路由请求(RREQ),并在包中加入 ETX 信息

  • RoutingProtocol::RecvRequest():接收路由请求(RREQ),根据 ETX 信息进行路径选择

  • RoutingProtocol::SendReply():发送路由回复(RREP),并在包中加入ETX值

  • RoutingProtocol::RecvReply():接收路由回复(RREP),根据 ETX 值进行路由选择

void RoutingProtocol::SendRequest (Ipv4Address dst) {
    // 在 RREQ 包中加入ETX度量信息
}

void RoutingProtocol::RecvRequest (Ptr<Packet> p, Ipv4Address receiver, Ipv4Address src) {
    // 根据ETX度量选择最优路径
}

void RoutingProtocol::SendReply (RreqHeader const & rreqHeader, RoutingTableEntry const & toOrigin) {
    // 在RREP包中加入ETX度量
}

void RoutingProtocol::RecvReply (Ptr<Packet> p, Ipv4Address my, Ipv4Address src) {
    // 根据ETX值选择最优路径
}

4. 路由维护阶段(RERR的ETX优化)

在 AODV 中,当一个路由失败时,会发送 RERR 包通知网络中的其他节点。基于 ETX 度量,我们可以优化失败链路的恢复过程。对于某些链路,如果其 ETX 值较高,,这代表这条链路可能是不可达的,所以就需要去选择其他链路

函数:

  • RoutingProtocol::SendRerrWhenBreaksLinkToNextHop():链路断开时发送 RERR 消息

  • RoutingProtocol::SendRerrMessage():转发 RERR 消息

void RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop) {
    // 发送 RERR 包并根据 ETX 选择新的路径
}

void RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> precursors) {
    // 根据 ETX 选择最佳路径并转发 RERR 包
}

5. 数据包转发阶段(ETX优化的转发决策)

数据包转发时,路由协议根据现有的路由表来决定转发路径。此时,使用 ETX 度量来选择链路质量较好的路径

函数:

  • RoutingProtocol::Forwarding():数据包转发时,选择最佳路径。如果启用了 ETX 度量,则使用 ETX 值来优化选择

bool RoutingProtocol::Forwarding (Ptr<const Packet> p, const Ipv4Header & header, UnicastForwardCallback ucb, ErrorCallback ecb) {
    // 如果启用了ETX,选择ETX值最小的路径进行转发
    if (m_enableEtx) {
        // 选择ETX最小的路径
    }
    // 进行数据包转发
    return true;
}

6. ETX更新机制(链路状态更新)

ETX 度量需要定期更新。在节点收到链路探测包后,需要更新邻居的 ETX 值。每个邻居的 ETX 值用于判断链路的可靠性

函数:

  • RoutingProtocol::UpdateRouteToNeighbor():更新邻居的路由和 ETX 信息

void RoutingProtocol::UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver) {
    // 更新邻居的ETX值
}

7. 定时器和定期操作

ETX 度量通常会通过定时器定期发送链路探测包(LPP),并基于 LPP 包的反馈更新链路的质量信息。AODV 协议中的 HelloTimerRREQ 定时器也可以与 ETX 相关联,用于定期更新链路质量

函数:

  • RoutingProtocol::LppTimerExpire():定时发送链路探测包

  • RoutingProtocol::HelloTimerExpire():定时发送 Hello 包

void RoutingProtocol::LppTimerExpire () {
    // 发送链路探测包以更新ETX值
}

void RoutingProtocol::HelloTimerExpire () {
    // 发送Hello包,更新邻居信息
}

8. ETX与路径选择

经过上述步骤,就已经实现将ETX度量指标融合应用在 AODV 协议中,如此一来,路径选择就不仅仅是基于跳数(Hops),还需要考虑链路的质量(ETX)。在转发数据包时,将优先选择 ETX 值较低的路径。每次路由更新后,节点也都会根据新的 ETX 值来调整自己的路由表。

整体过程总结

  1. ETX启用:在初始化时启用 ETX 度量

  2. 链路探测包(LPP):通过定期发送和接收链路探测包来更新链路的 ETX 值

  3. 路由发现(RREQ和RREP):在发送 RREQ 和 RREP 时,将 ETX 值纳入路径选择的决策中

  4. 路由维护(RERR):在链路断开时,根据 ETX 优化 RERR 消息的发送

  5. 数据包转发:转发数据包时,优先选择 ETX 值较低的路径

  6. 定时器管理:使用定时器定期更新链路质量信息