路由层如何处理底层的传输失败

转自:http://hi.baidu.com/karashun/blog/item/0fad3e4f7bbb28d5d0c86a08.html

1. 大致思想

    MAC 在传输失败的时候,通过函数指针调用 上层(路由层)的失败处理函数。

2. 函数指针的用法:

  1) 定义: 
   // packet.h
     typedef void (*FailureCallback)(Packet *,void *);

      //  FailureCallback 是一个函数指针类型, 可以指向 任意参数 为(Packet *,void *),返回值为void的函数。
    struct hdr_cmn {
   .....
    // called if pkt can't obtain media or isn't ack'd. not called if  droped by a queue
         FailureCallback xmit_failure_;
        void *xmit_failure_data_;
      }   
 
  2) 赋值: 
    赋值为函数地址就好了

    例如,在adov中,ch->xmit_failure_ = aodv_rt_failed_callback;  

 3) 使用:

       (a) 定义函数  aodv_rt_failed_callback, 符合指针类型要求

            尤其注意返回类型, 是void, 而不能是void  DSRAgent:: !! 

            所以只能用两个函数实现, 继续调用路由协议agent的失败处理函数。 

          void  XmitFlowFailureCallback(Packet *pkt, void *data)
         {
                  DSRAgent *agent = (DSRAgent *)data;
                 agent->xmitFlowFailed(pkt);
       }

         void  DSRAgent::xmitFailed(Packet *pkt, const char* reason) { 

     }

      (b) 调用:

      ch->xmit_failure_ (pDATA->copy(), ch->xmit_failure_data_);



3.  MAC 层的传输 失败

    1) RTS/CTS 握手次数超过 limit

    2) MAC层数据重传 次数超过limit

// mac-802_11Ext.cc

 

1)  void TXC::handleTCTStimeout() {

if (shortretrycounter >= mac_->macmib_.getShortRetryLimit()) {
         .......            
            // higher layers feedback support
            struct hdr_cmn *ch = HDR_CMN(pDATA);
            if (ch->xmit_failure_) {
                ch->xmit_reason_ = XMIT_REASON_RTS;
               ch->xmit_failure_(pDATA->copy(), ch->xmit_failure_data_);
            }
             mac_->discard(pDATA, DROP_MAC_RETRY_COUNT_EXCEEDED);

.....}

 2) void TXC::handleTACKtimeout() { 

   if (*counter >= limit) {
            // higher layers feedback support
            struct hdr_cmn *ch = HDR_CMN(pDATA);
            if (ch->xmit_failure_) {
                ch->xmit_reason_ = XMIT_REASON_RTS;
                ch->xmit_failure_(pDATA->copy(), ch->xmit_failure_data_);
            }
            mac_->discard(pDATA, DROP_MAC_RETRY_COUNT_EXCEEDED);

 

4.  路由层的失败处理:

  以aodv.cc 为例: 

  1) 对回调函数进行赋值: ch->xmit_failure_

 void
   AODV::rt_resolve(Packet *p) {
   struct hdr_cmn *ch = HDR_CMN(p);
  struct hdr_ip *ih = HDR_IP(p);
   aodv_rt_entry *rt;
 
                          //   赋值 : Set the transmit failure callback.  That    won't change. 
  ch->xmit_failure_ = aodv_rt_failed_callback; 

                           // kara say: xmit_failure_ 是一个函数指针, 这里赋值为 aodv 中的失败回调函数, 函数名称代表函数地址。

    ch->xmit_failure_data_ = (void*) this;
    rt = rtable.rt_lookup(ih->daddr());
    if(rt == 0) {
      rt = rtable.rt_add(ih->daddr());
    }

 

 2)  失败处理函数

  /*   Link Failure Management Functions*/

static void

aodv_rt_failed_callback(Packet *p, void *arg) {
       ((AODV*) arg)->rt_ll_failed(p);
}

/*  * This routine is invoked when the link-layer reports a route failed.  */
void
AODV::rt_ll_failed(Packet *p) {
      nsaddr_t broken_nbr = ch->next_hop_;    
      log_link_broke(p);
    if((rt = rtable.rt_lookup(ih->daddr())) == 0) {
    drop(p, DROP_RTR_MAC_CALLBACK);
    return;
  }
  log_link_del(ch->next_hop_);

#ifdef AODV_LOCAL_REPAIR
  /* if the broken link is closer to the dest than source,       attempt a local repair. Otherwise, bring down the route. */

  if (ch->num_forwards() > rt->rt_hops) {
    local_rt_repair(rt, p); // local repair
    // retrieve all the packets in the ifq using this link,
    // queue the packets for which local repair is done, 
    return;
  }
  else    
#endif // LOCAL REPAIR   

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值