• 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的事件中处理。

  • 相关阅读:
    数据结构学习记录_2019.02.26
    数据结构学习记录_2019.02.23
    数据结构学习记录_2019.02.27
    C语言学习记录_2019.02.23
    本博客所有博文密码均为“000000”
    Oracle触发器
    Oracle重载
    Oracle程序包
    Oracle函数
    Oracle存储过程
  • 原文地址:https://www.cnblogs.com/danxi/p/6363469.html
Copyright © 2020-2023  润新知