初始化有两步,先使用宏初始化内存然后再使用函数添加
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的先后关系,当然也有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都挂在对应的构造函数上,在初始化的时候就会调用。然后初始化相应的配置,也就是vnet_feature_arc_init 这个函数,会根据之前的配置,将各feature的先后关系排列好。此时只是排列好顺序,并未插入feature_arc中,也就是不会被调用到。
调用vnet_feature_enable_disable即可,此时才是将要用到的feature真正的插入feature_arc中。
具体的实现是 vnet_config_add_feature() vnet_config_del_feature() 这两个个函数跟之前版本的feature没有什么区别了。
按照老版本的思想,feature至少分为两种,接口的feature和其他的feature
在node的处理函数里调用vnet_feature_arc_start就好了。
通过命令show features可以看到成功加载的feature。
接口的feature与之前的版本不一样,是移至ip4-rewrite中进行接口feature的跳转。
通过命令show interface features xxx,可以看到接口的feature。
初始化会有一点变化,说一下区别
代码里并没有ip4-output这个节点,它只是一个arc_name。它的起始结点是使用.start_nodes挂上的两个。也就是ip4-rewrite与ip4-midchain。 在ip4-rewrite里跳转的feature
此处多说一句,"ip4-rewrite", "ip4-midchain"两个节点(最终调用的一个函数ip4_rewrite_inline),都有name为ip4-output的feature arc。具体在vnet_feature_init中实现的。
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,
};
在函数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被置位,则跳转到feature节点"
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);
}
......
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
网络异常,请检查网络