batman-adv路由算法分析
来源:互联网 发布:西部域名怎么解析 编辑:程序博客网 时间:2024/05/01 06:44
五、路由算法分析
通过OGM包更新对应源节点的数据
在bat_iv_ogm.c中line 970,batadv_iv_ogm_orig_update函数执行此工作。
(1)遍历orig_node->neigh_list链表,匹配地址,接收接口。
if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && tmp_neigh_node->if_incoming == if_incoming && atomic_inc_not_zero(&tmp_neigh_node->refcount)) { ……}
(2)得到发送接口之后,更新TQ缓冲区,更新TQ平均值。
spin_lock_bh(&tmp_neigh_node->ifinfo_lock);batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv, &neigh_ifinfo->bat_iv.tq_index, 0);tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);neigh_ifinfo->bat_iv.tq_avg = tq_avg;spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);
(3)如果计算出的下一跳不是一跳邻居节点,则利用batadv_iv_ogm_neigh_new函数重新获取下一跳;
(4)如果该邻居已经是下一跳,则直接退出;
(5)如果该邻居的TQ值并不比原来好,则直接退出;
(6)如果TQ值相同但是链路对称性不比原来好也不考虑;
TQ值的计算
在bat_iv_ogm.c中line 1131,batadv_iv_ogm_calc_tq函数执行此工作。
(1)首先匹配到相应的邻居节点;
(2)更新其last_seen;
(3)找到对应的数据包计数。
/* find packet count of corresponding one hop neighbor */spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);if_num = if_incoming->if_num;orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);if (neigh_ifinfo) { neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count; batadv_neigh_ifinfo_free_ref(neigh_ifinfo);} else { neigh_rq_count = 0;}spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
其中,bcast_own_sum计算bcast_own的数量,存储在orig_eq_count中,bcast-own为计数的bit集,统计自己广播出去,然后由该邻居节点广播回来的OGM包,统计窗口为64。
将neigh_rq_count赋值统计到的真实OGM数量。
(4)将orig_eq_count和neigh_rq_count其中的较小者赋值给total_count。
/* pay attention to not get a value bigger than 100 % */if (orig_eq_count > neigh_rq_count) total_count = neigh_rq_count;else total_count = orig_eq_count;
(5)如果接受OGM包过少(小于1),将tq_own置0;
(6)否则,计算tq_own;
tq_own = (BATADV_TQ_MAX_VALUE * total_count) / neigh_rq_count;
(7)加入非对称链路惩罚1 - ((1-x) ** 3)和接口惩罚(半双工网卡会受影响,因为不能同时收发);
(8)考虑链路的最低传输质量需求(如果有的话);
透过广播与再广播OGMs的方式交换路由资讯,以传输品质(Transmission Quality,简称TQ)做为路径选择的依据,TQ值的计算必须先取得接收品质(Receive Quality,简称RQ)与回声品质(Echo Quality,简称EQ)这二个参考数值。
各网路节点以广播的方式定期发送路由讯息封包即OGMs封包,其内容包含发送端位址,转发节点位址,存活时间(Time To Live,简称TTL)值和序列号(Sequence Number),附近的邻近节点计算已收到的OGMs封包数量作为RQ值。
检查每个路由的资讯,选择最好的单跳节点(Best Hop Neighbor)。
将最好的单跳节点传送过来的OGMs封包进行再广播,原始的OGMs封包发送节点透过接收到的再广播OGMs数量可以得到EQ。
如果EQ值大于RQ,则TQ = max(TQ);如果RQ值大于EQ,则TQ = max(TQ)× EQ ÷ RQ。
OGM包处理
在bat_iv_OGM.c/line 1570行,函数batadv_iv_ogm_process负责处理一个接收到的OGM数据包。
邻居节点在接收到包时,首先会解析,然后会做相应处理。这里有四种情况:如果包来自本节点的其他次接口,则丢弃。如果该的发起者是本节点的主接口,则次接口有义务帮其转发。如果包的起始地址是广播地址,则丢掉。如果包经过广播又转发回来,先检查该包是否是发送出去的最新的包,如果是则对—的—和一进行滑动窗口式的更新,之后抛弃。一和成员是计算返回链路通信质量的成员,它们是计算的基础。如果排除以上三种可能则进入常规处理阶段,首先确定该包是否为新包,如果是旧包则抛弃;如果是新包则纳入邻居节点的局部窗口,同时其他的邻居节点也需要对窗口中的数值更新。之后需要确定该链路是否为双向导通,只有双向通信都顺畅的链路才能纳入网络。链路的双向导通检查非常必要,非双向导通的网络链路会影响数据的传输效率。双向导通的标准是通过计算衡量,当大于协议制定的下限值时,则确定该链路是双向导通。
if (is_my_addr) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Drop packet: received my own broadcast (sender: %pM)\n", ethhdr->h_source); return;}if (is_my_orig) {……}if (is_my_oldorig) { batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); return;}
接下来,在每个发送接口(同属一个soft接口)上广播该数据包。
batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,if_incoming, BATADV_IF_DEFAULT);……list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { if (hard_iface->if_status != BATADV_IF_ACTIVE) continue; if (hard_iface->soft_iface != bat_priv->soft_iface) continue; batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node, if_incoming, hard_iface);}
关于BATADV_IF_DEFAULT的解释:
/* default interface for multi interface operation. The default interface is* used for communication which originated locally (i.e. is not forwarded)* or where special forwarding is not desired/necessary.*/#define BATADV_IF_DEFAULT ((struct batadv_hard_iface *)NULL)
所以,在以下两种情况时会用到缺省接口:
* 本地发起的数据请求;
* 没有指定特殊转发的情况;
/* line 1449 */if (if_outgoing == BATADV_IF_DEFAULT)batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
其中的TVLV表示type-version-length-value,详见https://www.open-mesh.org/projects/batman-adv/wiki/TVLV。
接收单播数据包的处理
接收到单播数据包时,由batadv_recv_unicast_packet(routing.c/line 830)处理。
如果接收到的数据包是发送到自己的,则首先检查该数据包的类型,分为以下几种:
* BATADV_P_DATA: user payload
* BATADV_P_DAT_DHT_GET: DHT request message
* BATADV_P_DAT_DHT_PUT: DHT store message
* BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT
如果是第一种,则分析它的源节点地址,返回NET_RX_SUCCESS。
如果目的地不是自己,则进行下面的路由与转发。
路由与转发
- 普通单播数据包
在route.c/line571, batadv_route_unicast_packet负责单播路由。
首先对数据包进行检查(TTL),正常的话,利用batadv_orig_hash_find函数找到源节点,得到路由信息。然后进行后续操作(TTL减一等),然后根据packet_type转发。(详见packet.h/line 38)
- 对于bonding技术
在route.c/line441 , batadv_find_router函数负责为一个源节点和一个给定的接口,找到合适的路由节点。
* 首先运行batadv_orig_router_get函数找到合适的下一跳节点,然后考虑bonding和alter机制。在mesh接口信息结构体batadv_priv中,包含了bonding, fragmentation, bridge_loop_avoidance, distributed_arp_table, multicast_mode, gw_mode(gateway), network_coding等等标识符。
在bonding模式下,recv_if传入的值为BATADV_IF_DEFAULT。首先,遍历所有可能的转发节点,找到一个不同于上一个bonding接口的candidate (next_candidate)。如果没有找到,则继续使用之前的接口。如果第一个bonding接口都无法找到,则返回之前计算出来的下一跳。
在存储源节点的batadv_orig_node结构体中,有一个成员是last_bonding_candidate( pointer to last ifinfo of last used router)。首先遍历源节点的所有接口,为每个接口获取到达它的下一跳接口,存储在cand_router中。由于默认alternative是开启的,如果cand_router并不比原来的好,则视作无效。否则,如果cand_router与last_bonding_candidate相同,则两次不走同一个接口,也视作无效。满足上述两个条件之后,将算出来的第一个cand_router保存在first_ candidate中。如果遍历指针已经处于last_bonding_candidate之后(已遍历),则直接选用list中位于last_bonding_candidate后一个的接口作为next_candidate,程序退出。否则,返回first_ candidate。(估计链表根据某种指标从坏到好排序)
广播数据包处理
接收到广播数据包时,由batadv_recv_bcast_packet(routing.c/line 1012)处理。
1、对数据包进行检查,大小不合格、携带有源节点地址、自己转发或发送的广播报文、TTL<2、找不到发送源节点的数据包都会不作处理。
2、检查该数据包是否重复、是否是旧的或者发送它的源节点刚刚启动。
3、将其记录下来,必要的话更新滑动窗口位置。
4、检查该数据包是否被其他节点转发过。
5、通过batadv_add_bcast_packet_to_list,在当前所属soft interface广播出去。
6、对广播报文进行处理,例如回复、更新必要信息等。
batadv_add_bcast_packet_to_list函数会将一个广播报文广播几次来提高接收可靠性。
- batman-adv路由算法分析
- BATMAN-ADV
- batman-adv协议相关概念
- batman-adv主要结构体
- batman-adv-kernel-android-(make-depmod-modprobe)
- batman-adv链路传输质量计算方法
- [batman-adv]学习(1) —— Overview
- Have you considered compiled a batman-adv.ko for android?
- (OK) install—batman-adv—batctl—CentOS7
- (OK) install—batman-adv—batctl—CentOS7
- batman-adv中OGM学习包代码处理流程
- [batman-adv]学习(2) —— Quick Start
- BATMAN
- (OK) 编译batman-adv.ko—成功—android—cm11源码—下载
- batman-adv——B.A.T.M.A.N. Advanced quick start guide
- (OK) adb—fastboot—recovery—insmod—TWRP Recovery—batman-adv.ko
- (OK) 编译batman-adv.ko—成功—android—cm11源码—下载
- (OK) adb—fastboot—recovery—insmod—TWRP Recovery—batman-adv.ko
- 安卓核心组件一activity
- 引用和指针
- jdk环境变量的设置
- batman-adv主要结构体
- mybatis源码之StatementHandler
- batman-adv路由算法分析
- 杭电1022——Train Problem I(栈的应用)
- JSON数据转换成对象
- 负载均衡之基于DNS负载
- 字符个数统计
- ng-disabled 不起作用的解决办法
- c++ 优秀文章
- mybatis源码之BaseStatementHandler
- 生成像jar一样的arr文件并且导入