这段代码是VPP(Virtual Packet Processing)网络虚拟化平台中用于创建 TAP 接口的函数。该函数使用了 VLIB 库提供的主要数据结构和函数,其中:
vlib_main_t
是 VPP 的主数据结构,代表一个 VPP 实例。tap_create_if_args_t
是一个结构体,包含了创建 TAP 接口所需的参数信息。
该函数通过调用 vnet_tap_create()
函数来创建一个 TAP 接口,并将其添加到 VPP 的接口列表中。该函数还会为新建的 TAP 接口分配并配置一个 VNET (Virtual Network Interface) 设备结构体,以便进行进一步的网络配置操作。最后,该函数返回一个错误码,表示 TAP 接口是否成功创建。
该函数的具体实现如下:
void
tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
{
vnet_main_t *vnm = vnet_get_main ();
vnet_hw_interface_t *hi;
vnet_sw_interface_t *si;
vnet_hw_interface_class_t *hw_class;
vnet_interface_main_t *im = &vnm->interface_main;
clib_error_t *error = 0;
/* Create a new TAP interface */
error = vnet_tap_create(vm, args);
if (error)
{
clib_error_report(error);
return;
}
/* Allocate a new VNET interface for the TAP */
pool_get_zero(im->sw_interfaces, si);
pool_get_zero(im->hw_interfaces, hi);
/* Set interface type and flags */
si->type = VNET_SW_INTERFACE_TYPE_TAP;
hi->sw_if_index = si->sw_if_index;
hi->hw_instance = 0;
hi->output_node_index = vlib_get_node_by_name(vm, (u8 *) "tapcli-output")->index;
/* Set hardware interface class */
hw_class = vnet_get_hw_interface_class(vnm, VNET_HW_INTERFACE_CLASS_TAP);
hi->hw_class_index = hw_class->index;
/* Set interface name */
if (args->devname)
{
strncpy(si->interface_name, (char *) args->devname, ARRAY_LEN(si->interface_name)-1);
strncpy(hi->name, (char *) args->devname, ARRAY_LEN(hi->name)-1);
}
else
{
snprintf(si->interface_name, ARRAY_LEN(si->interface_name),
"tap%d", si - im->sw_interfaces);
snprintf(hi->name, ARRAY_LEN(hi->name),
"tap%d", si - im->sw_interfaces);
}
/* Set MTU */
hi->max_l3_packet_bytes = ETHER_MAX_LEN;
/* Add to interface counters */
vnet_interface_counter_lock(im);
vlib_zero_simple_counter(&im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX], hi->sw_if_index);
vlib_zero_simple_counter(&im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX], hi->sw_if_index);
vnet_interface_counter_unlock(im);
/* Register with the interface abstraction layer */
vnet_hw_interface_set_flags(vnm, hi->hw_if_index, VNET_HW_INTERFACE_FLAG_LINK_UP);
/* Signal to the driver that the interface is ready */
vec_add1 (vnm->pending_hw_if_down_indexes, hi->hw_if_index);
vnet_hw_interface_set_flags(vnm, hi->hw_if_index, VNET_HW_INTERFACE_FLAG_LINK_UP);
/* Send event to tapcli */
vnet_link_up_down_args_t a = {
.sw_if_index = hi->sw_if_index,
.flags = VNET_SW_INTERFACE_FLAG_ADMIN_UP,
};
vnet_sw_interface_link_up_down (vnm, &a);
}
其中,vnet_tap_create()
函数的实现在 src/vnet/devices/tap/tap.c
文件中。此外,该函数会调用 VPP 中其他函数来完成接口的创建和配置操作。