苏州公司网站制作公司,怎么给QQ名片做网站,网络设计报告3000字,网站系统的设计与制作对于各个协议生成的路由信息的处理属于quagga中非常重要的一个功能#xff0c;如何在内核进行路由增加#xff0c;更新#xff0c;删除是一个复杂的过程。 quagga在thread任务调度中加入了一种工作队列#xff0c;work_queue#xff0c;与内核的工作队列类似#xff0c;是…对于各个协议生成的路由信息的处理属于quagga中非常重要的一个功能如何在内核进行路由增加更新删除是一个复杂的过程。 quagga在thread任务调度中加入了一种工作队列work_queue与内核的工作队列类似是一种相对而言低优先级的任务这里的任务看成类似的系统进程。 1、队列初始化 1 /* initialise zebra rib work queue */2 static void3 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 } OKmeta_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内核够用就行。 转载于:https://www.cnblogs.com/danxi/p/6285545.html