zoukankan      html  css  js  c++  java
  • quagga源码学习--BGP协议路由更新

    BGP的核心就是交换路由,所以关键的部分还是在路由的更新与撤销上面,这之间包含了繁杂的属性,community等等可以称之为业务逻辑的处理过程,不做详述。

    bgp_read函数是路由更新的事件处理函数,在收到BGP_MSG_UPDATE消息的时候开始调用bgp_update_receive函数处理。

    1 switch (i) {
    2         case NLRI_UPDATE:
    3         case NLRI_MP_UPDATE:
    4             nlri_ret = bgp_nlri_parse(peer, NLRI_ATTR_ARG, &nlris[i]);
    5             break;
    6         case NLRI_WITHDRAW:
    7         case NLRI_MP_WITHDRAW:
    8             nlri_ret = bgp_nlri_parse(peer, NULL, &nlris[i]);
    9         }

    上面是更新路由与撤销路由。比如在cli输入clear ip bgp 命令的时候会撤销路由。

    nlri是(network layer reachable infomation)的缩写。

    在bgp_nlri_parse里对bgp UPDATE消息内容进行处理,遍历消息内容里的全部路由前缀,开始bgp_update调用。

    1 /* Normal process. */
    2         if (attr)
    3             ret = bgp_update(peer, &p, attr, packet->afi, packet->safi,
    4                              ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
    5         else
    6             ret = bgp_withdraw(peer, &p, attr, packet->afi, packet->safi,
    7                                ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);

    在bgp_update中对本节点以及所有的邻居的路由信息都进行更新,主要的更新是在bgp_process函数里。

    1 switch (bgp_node_table(rn)->type) {
    2     case BGP_TABLE_MAIN:
    3         work_queue_add(bm->process_main_queue, pqnode);
    4         break;
    5     case BGP_TABLE_RSCLIENT:
    6         work_queue_add(bm->process_rsclient_queue, pqnode);
    7         break;
    8     }

    可以看到,最后都是在工作队列里进行更新。对应初始化的时候设置的工作函数:

    1     bm->process_main_queue->spec.workfunc = &bgp_process_main;
    2     bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
    3     bm->process_main_queue->spec.max_retries = 0;
    4     bm->process_main_queue->spec.hold = 50;
    5 
    6     bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
    7     bm->process_rsclient_queue->spec.del_item_data = &bgp_processq_del;
    8     bm->process_rsclient_queue->spec.max_retries = 0;
    9     bm->process_rsclient_queue->spec.hold = 50;

    对本节点(即服务端),在bgp_process_main里最终发送给了zserv。

    1 zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *)p, &api);

    对于邻居(即通过neighbor命令配置的),在bgp_process_rsclient中分别如下处理

    如果是添加或者更新,则添加到fifo队列中:

    1 /* Add new advertisement to advertisement attribute list. */
    2     bgp_advertise_add(adv->baa, adv);
    3 
    4     FIFO_ADD(&peer->sync[afi][safi]->update, &adv->fifo);

    如果是撤销路由,则:

    1 /* Add to synchronization entry for withdraw announcement.  */
    2         FIFO_ADD(&peer->sync[afi][safi]->withdraw, &adv->fifo);
    3 
    4         /* Schedule packet write. */
    5         BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);

    都是在thread任务调度的bgp_write的事件中处理。

  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/danxi/p/6363469.html
Copyright © 2011-2022 走看看