//如果转发的跳数大于到达目的节点的跳数,则进行路由修复;否则丢弃通过此邻居的
//数据并且删除此邻居
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
{
drop(p, DROP_RTR_MAC_CALLBACK);
// Do the same thing for other packets in the interface queue using the
// broken link -Mahesh
while((p = ifqueue->filter(broken_nbr))) {
drop(p, DROP_RTR_MAC_CALLBACK);
}
nb_delete(broken_nbr);
}
#endif // LINK LAYER DETECTION
}
/*当发现邻居失效的时候,就会调用此函数*/
void
AODV::handle_link_failure(nsaddr_t id) {
aodv_rt_entry *rt, *rtn;
Packet *rerr = Packet::alloc();
struct hdr_aodv_error *re = HDR_AODV_ERROR(rerr);
re->DestCount = 0;
//查找通过此邻居节点到达目的的路由,
for(rt = rtable.head(); rt; rt = rtn) { // for each rt entry
rtn = rt->rt_link.le_next;
//如果跳数不是无限大并且下一跳就是失效的邻居
if ((rt->rt_hops != INFINITY2) && (rt->rt_nexthop == id) ) {
assert (rt->rt_flags == RTF_UP);
assert((rt->rt_seqno%2) == 0);
rt->rt_seqno++;
re->unreachable_dst[re->DestCount] = rt->rt_dst;
re->unreachable_dst_seqno[re->DestCount] = rt->rt_seqno;
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\n", __FUNCTION__, CURRENT_TIME,
index, re->unreachable_dst[re->DestCount],
re->unreachable_dst_seqno[re->DestCount], rt->rt_nexthop);
#endif // DEBUG
re->DestCount += 1;
rt_down(rt);//将此路由down掉
}
// remove the lost neighbor from all the precursor lists
rt->pc_delete(id);//删除此路由的前缀列表
}
/*如果存在通过此邻居到达目的节点的路由,则发送错误报文*/
if (re->DestCount > 0) {
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\tsending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
#endif // DEBUG
sendError(rerr, false);
}
else {
Packet::free(rerr);
}
}
void
AODV::local_rt_repair(aodv_rt_entry *rt, Packet *p) {
#ifdef DEBUG
fprintf(stderr,"%s: Dst - %d\n", __FUNCTION__, rt->rt_dst);
#endif
// Buffer the packet
rqueue.enque(p);
// mark the route as under repair
rt->rt_flags = RTF_IN_REPAIR;
sendRequest(rt->rt_dst);
// set up a timer interrupt
Scheduler::instance().schedule(&lrtimer, p->copy(), rt->rt_req_timeout);
}
/*更新路由条目*/
void
AODV::rt_update(aodv_rt_entry *rt, u_int32_t seqnum, u_int16_t metric,
nsaddr_t nexthop, double expire_time) {
rt->rt_seqno = seqnum;
rt->rt_hops = metric;
rt->rt_flags = RTF_UP;
rt->rt_nexthop = nexthop;
rt->rt_expire = expire_time;
}
/*将此路由条目down掉*/
void
AODV::rt_down(aodv_rt_entry *rt) {
/*
* Make sure that you don't "down" a route more than once.
*/
if(rt->rt_flags == RTF_DOWN) {
return;
}
// assert (rt->rt_seqno%2); // is the seqno odd?
rt->rt_last_hop_count = rt->rt_hops;
rt->rt_hops = INFINITY2;
rt->rt_flags = RTF_DOWN;
rt->rt_nexthop = 0;
rt->rt_expire = 0;
} /* rt_down function */
/*
Route Handling Functions
*/
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;
ch->xmit_failure_data_ = (void*) this;
rt = rtable.rt_lookup(ih->daddr());
if(rt == 0) {
rt = rtable.rt_add(ih->daddr());
}
/*
* If the route is up, forward the packet
*/
//如果存在路由,则转发
if(rt->rt_flags == RTF_UP) {
assert(rt->rt_hops != INFINITY2);
forward(rt, p, NO_DELAY);
}
/*
* if I am the source of the packet, then do a Route Request.
*/
else if(ih->saddr() == index)
// {
//如果是源节点且没有到达目的节点的路由,缓存数分组
//发送路由请求
rqueue.enque(p);
sendRequest(rt->rt_dst);
}
/*
* A local repair is in progress. Buffer the packet.
*/
//如果此路由处于修复状态,则缓存分组
else if (rt->rt_flags == RTF_IN_REPAIR) {
rqueue.enque(p);
}