初始化有兩步,先使用宏初始化內(nèi)存然后再使用函數(shù)添加
為忻府等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及忻府網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站制作、網(wǎng)站設(shè)計、忻府網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
1.1 先初始化arc
arc就是一串有序的feature的集合
VNET_FEATURE_ARC_INIT (device_input, static) = { .arc_name = "device-input", .start_nodes = VNET_FEATURES ("device-input"), .arc_index_ptr = &feature_main.device_input_feature_arc_index, };
1.2 再初始化這個arc下的feature,通過.runs_before來控制feature的先后關(guān)系,當(dāng)然也有runs_after
VNET_FEATURE_INIT (worker_handoff, static) = { .arc_name = "device-input", .node_name = "worker-handoff", .runs_before = VNET_FEATURES ("ethernet-input"), }; VNET_FEATURE_INIT (span_input, static) = { .arc_name = "device-input", .node_name = "span-input", .runs_before = VNET_FEATURES ("ethernet-input"), }; VNET_FEATURE_INIT (ethernet_input, static) = { .arc_name = "device-input", .node_name = "ethernet-input", .runs_before = 0, /* not before any other features */};
把這些node都掛在對應(yīng)的構(gòu)造函數(shù)上,在初始化的時候就會調(diào)用。然后初始化相應(yīng)的配置,也就是vnet_feature_arc_init 這個函數(shù),會根據(jù)之前的配置,將各feature的先后關(guān)系排列好。此時只是排列好順序,并未插入feature_arc中,也就是不會被調(diào)用到。
調(diào)用vnet_feature_enable_disable即可,此時才是將要用到的feature真正的插入feature_arc中。
具體的實現(xiàn)是 vnet_config_add_feature() vnet_config_del_feature() 這兩個個函數(shù)跟之前版本的feature沒有什么區(qū)別了。
按照老版本的思想,feature至少分為兩種,接口的feature和其他的feature
在node的處理函數(shù)里調(diào)用vnet_feature_arc_start就好了。
通過命令show features可以看到成功加載的feature。
接口的feature與之前的版本不一樣,是移至ip4-rewrite中進行接口feature的跳轉(zhuǎn)。
通過命令show interface features xxx,可以看到接口的feature。
初始化會有一點變化,說一下區(qū)別
代碼里并沒有ip4-output這個節(jié)點,它只是一個arc_name。它的起始結(jié)點是使用.start_nodes掛上的兩個。也就是ip4-rewrite與ip4-midchain。 在ip4-rewrite里跳轉(zhuǎn)的feature
此處多說一句,"ip4-rewrite", "ip4-midchain"兩個節(jié)點(最終調(diào)用的一個函數(shù)ip4_rewrite_inline),都有name為ip4-output的feature arc。具體在vnet_feature_init中實現(xiàn)的。
VNET_FEATURE_ARC_INIT (ip4_output, static) = { .arc_name = "ip4-output", .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain"), .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index, };
在函數(shù)ip4_rewrite_inline中
ip4_rewrite_inline() { ...... if (PREDICT_TRUE (error0 == IP4_ERROR_NONE)) { p0->current_data -= rw_len0; p0->current_length += rw_len0; "從adj的rewrite取得sw_if_index" tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index; vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0; next0 = adj0[0].rewrite_header.next_index; if (is_midchain) { adj0->sub_type.midchain.fixup_func (vm, adj0, p0); } "若adj的VNET_REWRITE_HAS_FEATURES被置位,則跳轉(zhuǎn)到feature節(jié)點" if (PREDICT_FALSE (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES)) vnet_feature_arc_start (lm->output_feature_arc_index, tx_sw_if_index0, &next0, p0); } ...... }