quagga源碼分析--路由信息處理zebra-rib


對於各個協議生成的路由信息的處理屬於quagga中非常重要的一個功能,如何在內核進行路由增加,更新,刪除是一個復雜的過程。

quagga在thread任務調度中加入了一種工作隊列,work_queue,與內核的工作隊列類似,是一種相對而言,低優先級的任務,這里的任務看成類似的系統進程。

1、隊列初始化:

 1 /* initialise zebra rib work queue */
 2 static void
 3 rib_queue_init(struct zebra_t *zebra)
 4 {
 5     assert(zebra);
 6 
 7     if (!(zebra->ribq = work_queue_new(zebra->master,
 8                                        "route_node processing")))
 9     {
10         zlog_err("%s: could not initialise work queue!", __func__);
11         return;
12     }
13 
14     /* fill in the work queue spec */
15     zebra->ribq->spec.workfunc = &meta_queue_process;
16     zebra->ribq->spec.errorfunc = NULL;
17     /* XXX: TODO: These should be runtime configurable via vty */
18     zebra->ribq->spec.max_retries = 3;
19     zebra->ribq->spec.hold = rib_process_hold_time;
20 
21     if (!(zebra->mq = meta_queue_new()))
22     {
23         zlog_err("%s: could not initialise meta queue!", __func__);
24         return;
25     }
26     return;
27 }

第19行,zebra->ribq->spec.hold = rib_process_hold_time; 指定了rib工作隊列在thread_fetch的時候會等待10毫秒

 

1 /* Hold time for RIB process, should be very minimal.
2  * it is useful to able to set it otherwise for testing, hence exported
3  * as global here for test-rig code.
4  */
5 int rib_process_hold_time = 10;

 

在添加thread任務的時候進行了時間單位換算:

 1 /* Add a background thread, with an optional millisec delay */
 2 struct thread*
 3 funcname_thread_add_background(struct thread_master *m,
 4                                int (*func)(struct thread *),
 5                                void *arg, long delay,
 6                                debugargdef) {
 7     struct timeval trel;
 8 
 9     assert(m != NULL);
10 
11     if (delay) {
12         trel.tv_sec = delay / 1000;
13         trel.tv_usec = 1000 * (delay % 1000);
14     } else {
15         trel.tv_sec = 0;
16         trel.tv_usec = 0;
17     }
18 
19     return funcname_thread_add_timer_timeval(m, func, THREAD_BACKGROUND,
20                                              arg, &trel, debugargpass);
21 }

OK,meta_queue_process,就指定了工作隊列在調度執行的處理函數,由此guagga就會一直同步更新路由了。

2、每個子網的下一跳路由表項的描述:

quagga使用了雙向鏈表來管理表項,定義了路由表現的詳細信息,但比如 status 這個字段是用來在更新路由時來做比較的關鍵字段。如下宏定義了3種狀態:

#define RIB_ENTRY_REMOVED    (1 << 0)
#define RIB_ENTRY_CHANGED    (1 << 1)
#define RIB_ENTRY_SELECTED_FIB    (1 << 2)

 1 struct rib { 
 2   struct rib *next;         /* Link list. */
 3   struct rib *prev;
 4   struct nexthop *nexthop; /* Nexthop structure */
 5   unsigned long refcnt;    /* Refrence count. */
 6   time_t uptime;           /* Uptime. */
 7   int type;                /* Type fo this route. */
 8   vrf_id_t vrf_id;         /* VRF identifier. */
 9   int table;               /* Which routing table */
10   u_int32_t metric;        /* Metric */
11   u_int32_t mtu;           /* MTU */
12   u_int32_t nexthop_mtu;
13   u_char distance;         /* Distance. */
14   u_char flags;             /* Flags of this route. in lib/zebra.h ZEBRA_FLAG_* */
15   u_char status;            /* RIB internal status */
16 #define RIB_ENTRY_REMOVED    (1 << 0)
17 #define RIB_ENTRY_CHANGED    (1 << 1)
18 #define RIB_ENTRY_SELECTED_FIB    (1 << 2)
19   u_char nexthop_num;        /* Nexthop information. */
20   u_char nexthop_active_num;
21   u_char nexthop_fib_num;
22 };

 3、整個路由表的描述:

/* Routing table top structure. */
struct route_table {
  struct route_node *top;
  /*
   * Delegate that performs certain functions for this table.
   */
  route_table_delegate_t *delegate;
  unsigned long count;
  void *info;     /* User data. */
};

route_table包含了一個二叉樹結構來保存所有的路由前綴和下一跳路由表項,prefix結構保持了路由前綴的長度和值,用來做最長前綴匹配:

 1 /* Each routing entry. */
 2 struct route_node {
 3   struct prefix p;   /* Actual prefix of this radix. */
 4   struct route_table *table;   /* Tree link. */
 5   struct route_node *parent;
 6   struct route_node *link[2];
 7   unsigned int lock; /* Lock of this radix */
 8   void *info;        /* Each node of route. */
 9   void *aggregate;   /* Aggregation. */
10 
11 #define l_left   link[0]
12 #define l_right  link[1]
13 };

呃,說好的mtire樹呢? 好吧,我們不太可能把成千上萬的路由表項塞給linux內核,夠用就行。

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM