dpdk从给定的port/queue捕获流量

简介

dpdk编程之从给定的port/queue tuple捕获流量。

首先推荐一篇非常好的文章:DPDK之KNI原理 - 云+社区 - 腾讯云

rte_lcore_id

rte_lcore_id()返回当前运行的lcore id。

lcore指的是EAL linux线程。

EAL创建和管理eal线程通过remote_launch来实现任务分配。

在每个EAL线程中,有一个称为_lcore_id TLS是线程的独一无二的id。

通常EAL线程绑定物理cpu,lcore_id通常等于cpu id。

当使用多线程时,绑定不再在线程和指定物理cpu之间总是1:1,EAL线程设为对cpu集的亲和性,而lcore id不再和cpu id一样。所以dpdk 提供了EAL选项-lcores,设置lcore的cpu亲和性,指定lcore id或组对EAL线程设置cpu set。

EAL为环境抽象层,DPDK运行时对linux操作系统进行初始化,并为用户态 DPDK App提供了一个通用接口,隐藏封装了与底层交互能力。做了一些实dpdk运行初始化工作,大页内存分配、numa亲和性、cpu绑定、内存/buffer/ring分配等,并通过 UIO 或 VFIO 技术将 PCI/PCIe 设备地址映射到用户空间。

rte_eth_rx_burst

nb_rx = rte_eth_rx_burst(arg0,arg1,arg2,arg3)从物理网口批量收包函数。

最大收包数量由args3决定。

arg0为port id,arg1为queue id。

arg2为数据包buffers数组类型为struct rte_mbuf *bufs[arg3];。

返回值nb_rx为实际接收的数据包数量,有效提供给bufs数组的指向rte_mbuf结构的指针数量。

rte_ring_enqueue_burst

nb_rx_enqueued = rte_ring_enqueue_burst(arg0,arg1,arg2)在ring上入队packet bufs。

根据ring创建时指定的默认行为,调用多生产者or单生产者。通常rte_ring支持多生产者入队和多消费者出队并且是非抢占的。

arg0为ring。

arg2为packet bufs。

arg3为nb_rx。

返回值nb_rx_enqueued为入队的实际数据包数

丢包统计

nb_rx与nb_rx_enqueued差值就是丢失数据包个数。

通过rte_pktmbuf_free把不能入队的数据包结构体free掉。

demo code

#include <stdbool.h>
#include <signal.h>
#include <string.h>

#include <dpdk/rte_log.h>
#include <dpdk/rte_lcore.h>
#include <dpdk/rte_ethdev.h>
#include <dpdk/rte_ether.h>
#include <dpdk/rte_ethdev.h>
#include <dpdk/rte_ip.h>
#include <arpa/inet.h>
#include "core_capture.h"


// 从给定的port/queue tuple捕获流量
int capture_core(const struct core_capture_config * config) {
  struct rte_mbuf *bufs[DPDKCAP_CAPTURE_BURST_SIZE];
  uint16_t nb_rx;
  int nb_rx_enqueued;

  RTE_LOG(INFO, DPDKCAP, "Core %u is capturing packets for port %u\n",
      rte_lcore_id(), config->port);

  /* Init stats */
  *(config->stats) = (struct core_capture_stats) {
    .core_id=rte_lcore_id(),
    .packets = 0,
    .missed_packets = 0,
  };

  /* Run until the application is quit or killed. */
  for (;;) {
    /* Stop condition */
    if (unlikely(*(config->stop_condition))) {
      break;
    }

    /* Retrieve packets and put them into the ring */
    nb_rx = rte_eth_rx_burst(config->port, config->queue,
        bufs, DPDKCAP_CAPTURE_BURST_SIZE);
    if (likely(nb_rx > 0)) {
      nb_rx_enqueued = rte_ring_enqueue_burst(config->ring, (void*) bufs,
          nb_rx);

      /* Update stats */
      config->stats->packets+=nb_rx_enqueued;
      config->stats->missed_packets+=nb_rx-nb_rx_enqueued;

      /* Free whatever we can't put in the write ring */
      for (; nb_rx_enqueued < nb_rx; nb_rx_enqueued++) {
        rte_pktmbuf_free(bufs[nb_rx_enqueued]);
      }
    }
  }

  RTE_LOG(INFO, DPDKCAP, "Closed capture core %d (port %d)\n",
      rte_lcore_id(), config->port);

  return 0;
}

消费数据包统计分析​​​​​​​

dpdk从环形队列ring获取解析数据包,并使用hashtable统计_istan1ey的博客-CSDN博客_rte_ring_dequeue_burst

其他

vlan过滤

网卡初始化时增加这两句代码,可以实现port 0只接受vlan=100的报文;

port_conf.rxmode.hw_vlan_filter = 1;

rte_eth_dev_vlan_filter(0,100,1);

vlan 剥离

port_conf.rxmode.hw_vlan_strip = 1;

checksum验证

port_conf.rxmode.hw_ip_checksum = 1;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,没有直接说明如何使用Prometheus监控DPDK流量。但是,可以通过以下步骤来实现: 1. 在DPDK应用程序中启用统计信息,以便DPDK可以生成有关流量的指标。 2. 使用Prometheus的DPDK Exporter来收集DPDK生成的指标。 3. 将指标发送到Prometheus服务器以进行聚合和可视化。 以下是一个简单的示例,演示如何使用DPDK Exporter和Prometheus监控DPDK流量: 1. 在DPDK应用程序中启用统计信息。可以通过在应用程序中调用rte\_eth\_stats\_get函数来实现。例如,以下代码片段显示如何获取有关端口1的统计信息: ```c struct rte_eth_stats stats; rte_eth_stats_get(1, &stats); printf("Packets received: %lu\n", stats.ipackets); printf("Packets sent: %lu\n", stats.opackets); ``` 2. 使用DPDK Exporter来收集DPDK生成的指标。可以使用DPDK Exporter来收集DPDK生成的指标。DPDK Exporter是一个开源项目,可以从GitHub上获取。可以使用以下命令来启动DPDK Exporter: ```shell ./dpdk_exporter --dpdk-config /path/to/dpdk-config --dpdk-stats /path/to/dpdk-stats ``` 其中,--dpdk-config参数指定DPDK配置文件的路径,--dpdk-stats参数指定DPDK统计信息文件的路径。 3. 将指标发送到Prometheus服务器以进行聚合和可视化。可以使用以下命令将DPDK Exporter生成的指标发送到Prometheus服务器: ```shell ./dpdk_exporter --dpdk-config /path/to/dpdk-config --dpdk-stats /path/to/dpdk-stats --prometheus-addr <prometheus-server>:<prometheus-port> ``` 其中,--prometheus-addr参数指定Prometheus服务器的地址和端口号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值