探究分段场景下vlib_buf在收发包的处理

2023-03-08 23:06:09 来源:腾讯云

VLIB_NODE_FN (dpdk_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node,                vlib_frame_t * f){  dpdk_main_t *dm = &dpdk_main;  dpdk_device_t *xd;  uword n_rx_packets = 0;  vnet_device_input_runtime_t *rt = (void *) node->runtime_data;  vnet_device_and_queue_t *dq;  u32 thread_index = node->thread_index;  /*轮询此cpu上的所有设备的输入或者中断。会存在一个cpu绑多个接口的情况   * Poll all devices on this cpu for input/interrupts.   */  /* *INDENT-OFF* */  foreach_device_and_queue (dq, rt->devices_and_queues)    {      xd = vec_elt_at_index(dm->devices, dq->dev_instance);      n_rx_packets += dpdk_device_input (vm, dm, xd, node, thread_index,                     dq->queue_id);    }  /* *INDENT-ON* */  return n_rx_packets;}/* *dpdk-input节点定义* */VLIB_REGISTER_NODE (dpdk_input_node) = {  .type = VLIB_NODE_TYPE_INPUT,  .name = "dpdk-input",  .sibling_of = "device-input",  .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,  /* Will be enabled if/when hardware is detected. */  .state = VLIB_NODE_STATE_DISABLED,  .format_buffer = format_ethernet_header_with_length,  .format_trace = format_dpdk_rx_trace,  .n_errors = DPDK_N_ERROR,  .error_strings = dpdk_error_strings,};

在dpdk_device_input函数中调用dpdkpmd收包通用接口从网卡描述符收取报文,具体流程可以参考:DPDK 网卡收包流程。

下面分段报文的处理,需要通过rte_mbuf 串联关系讲vlib_buf也串联起来。

/*通过dpdk pmd接口从网卡收取报文 get up to DPDK_RX_BURST_SZ buffers from PMD */  while (n_rx_packets < DPDK_RX_BURST_SZ)    {      n = rte_eth_rx_burst (xd->port_id, queue_id,                ptd->mbufs + n_rx_packets,                DPDK_RX_BURST_SZ - n_rx_packets);      n_rx_packets += n;      if (n < 32)    break;    }/*处理从网卡描述符收到的报文。*/static_always_inline uworddpdk_process_rx_burst (vlib_main_t * vm, dpdk_per_thread_data_t * ptd,               uword n_rx_packets, int maybe_multiseg,               u16 * or_flagsp){....while (n_left)    {      /*通过rte_mbuf的的搭配vlib-buf头*/      b[0] = vlib_buffer_from_rte_mbuf (mb[0]);      /*前64字节赋值模板*/      vlib_buffer_copy_template (b[0], &bt);      or_flags |= dpdk_ol_flags_extract (mb, flags, 1);      flags += 1;      b[0]->current_data = mb[0]->data_off - RTE_PKTMBUF_HEADROOM;      n_bytes += b[0]->current_length = mb[0]->data_len;      /*多分段的场景,需要通过rte_mbuf 串联关系讲vlib_buf也串联起来*/      if (maybe_multiseg)    n_bytes += dpdk_process_subseq_segs (vm, b[0], mb[0], &bt);      /*跟踪记录node执行节点trace初始化*/      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]);      /* next */      mb += 1;      n_left -= 1;    }....}

使用dpdk 发包接口函数

对应的在plugins目录下dpdk模块文件中src\plugins\dpdk\device\device.c定义dpdk对应的设备类。

/*对应的通用的dpdk tx接口函数*/VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm,                         vlib_node_runtime_t * node,                         vlib_frame_t * f)/* *dpdk对应的设备类结构体描述* */VNET_DEVICE_CLASS (dpdk_device_class) = {  .name = "dpdk",  .admin_up_down_function = dpdk_interface_admin_up_down,  .subif_add_del_function = dpdk_subif_add_del_function,  .rx_redirect_to_node = dpdk_set_interface_next_node,  .mac_addr_change_function = dpdk_set_mac_address,  .mac_addr_add_del_function = dpdk_add_del_mac_address,  .format_flow = format_dpdk_flow,  .flow_ops_function = dpdk_flow_ops_fn,  .set_rss_queues_function = dpdk_interface_set_rss_queues,};

在对应发包函数中会对分段vlib_buf的连对应的mbuf进行串联,以保证在调用dpdk库中对应网卡的pmd驱动发包接口使用。

关键词:
x 广告
x 广告

Copyright   2015-2022 财务报告网版权所有  备案号: 京ICP备12018864号-19   联系邮箱:29 13 23 6 @qq.com