• 常用接口

常用接口

dpdk version

#include <rte_version.h>

printf("DPDK version: %s\n", rte_version());

接口信息

  • mac地址
  • link状态
  • driver,device info, numa id
  • 固件版本
  • 是否开启混杂模式
  • mtu

获取mtu

uint16_t mtu = 0;
ret = rte_eth_dev_get_mtu(i, &mtu);
if (ret == 0)
	printf("\t  -- mtu (%d)\n", mtu);

获取mac

struct rte_ether_addr mac;

ret = rte_eth_macaddr_get(i, &mac);
if (ret == 0) {
	char ebuf[RTE_ETHER_ADDR_FMT_SIZE];

	rte_ether_format_addr(ebuf, sizeof(ebuf), &mac);
	printf("\t  -- mac %s\n", ebuf);
}

获取link状态

struct rte_eth_link link;
char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];

ret = rte_eth_link_get(i, &link);
if (ret < 0) {
	printf("Link get failed (port %u): %s\n",
	       i, rte_strerror(-ret));
} else {
	rte_eth_link_to_str(link_status_text,
			sizeof(link_status_text),
			&link);
	printf("\t%s\n", link_status_text);
}

driver,device info, numa id

struct rte_eth_dev_info dev_info;
ret = rte_eth_dev_info_get(i, &dev_info);
if (ret != 0) {
	printf("Error during getting device info: %s\n",
		strerror(-ret));
	return;
}

printf("\t  -- driver %s device %s socket %d\n",
       dev_info.driver_name, rte_dev_name(dev_info.device),
       rte_eth_dev_socket_id(i));

固件版本

char fw_version[ETHDEV_FWVERS_LEN];

if (rte_eth_dev_fw_version_get(i, fw_version,
			       ETHDEV_FWVERS_LEN) == 0)
	printf("Ethdev port %u firmware version: %s\n", i,
		fw_version);
else
	printf("Ethdev port %u firmware version: %s\n", i,
		"not available");

内存池

  • 创建
  • 查看相关信息

创建

#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250

mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
		MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());

if (mbuf_pool == NULL)
	rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");

查看相关信息

static void
show_mempool(char *name)
{
	if (name != NULL) {
		struct rte_mempool *ptr = rte_mempool_lookup(name);
		if (ptr != NULL) {
			struct rte_mempool_ops *ops;
			uint64_t flags = ptr->flags;

			ops = rte_mempool_get_ops(ptr->ops_index);
			printf("  - Name: %s on socket %d\n"
				"  - flags:\n"
				"\t  -- No spread (%c)\n"
				"\t  -- No cache align (%c)\n"
				"\t  -- SP put (%c), SC get (%c)\n"
				"\t  -- Pool created (%c)\n"
				"\t  -- No IOVA config (%c)\n"
				"\t  -- Not used for IO (%c)\n",
				ptr->name,
				ptr->socket_id,
				(flags & RTE_MEMPOOL_F_NO_SPREAD) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_NO_CACHE_ALIGN) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_SP_PUT) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_SC_GET) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_POOL_CREATED) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_NO_IOVA_CONTIG) ? 'y' : 'n',
				(flags & RTE_MEMPOOL_F_NON_IO) ? 'y' : 'n');
			printf("  - Size %u Cache %u element %u\n"
				"  - header %u trailer %u\n"
				"  - private data size %u\n",
				ptr->size,
				ptr->cache_size,
				ptr->elt_size,
				ptr->header_size,
				ptr->trailer_size,
				ptr->private_data_size);
			printf("  - memezone - socket %d\n",
				ptr->mz->socket_id);
			printf("  - Count: avail (%u), in use (%u)\n",
				rte_mempool_avail_count(ptr),
				rte_mempool_in_use_count(ptr));
			printf("  - ops_index %d ops_name %s\n",
				ptr->ops_index, ops ? ops->name : "NA");

			return;
		}
	}

	rte_mempool_list_dump(stdout);
}

ring

创建

查看

创建

ring = rte_ring_create(ring_name, ring_size,
		       rte_socket_id(), 0);
if (ring == NULL)
	rte_exit(EXIT_FAILURE, "Could not create ring :%s\n",
		 rte_strerror(rte_errno));

查看

static void
show_ring(char *name)
{
	if (name != NULL) {
		struct rte_ring *ptr = rte_ring_lookup(name);
		if (ptr != NULL) {
			printf("  - Name (%s) on socket (%d)\n"
				"  - flags:\n"
				"\t  -- Single Producer Enqueue (%u)\n"
				"\t  -- Single Consumer Dequeue (%u)\n",
				ptr->name,
				ptr->memzone->socket_id,
				ptr->flags & RING_F_SP_ENQ,
				ptr->flags & RING_F_SC_DEQ);
			printf("  - size (%u) mask (0x%x) capacity (%u)\n",
				ptr->size,
				ptr->mask,
				ptr->capacity);
			printf("  - count (%u) free count (%u)\n",
				rte_ring_count(ptr),
				rte_ring_free_count(ptr));
			printf("  - full (%d) empty (%d)\n",
				rte_ring_full(ptr),
				rte_ring_empty(ptr));

			STATS_BDR_STR(50, "");
			return;
		}
	}

	rte_ring_list_dump(stdout);
}

vlan相关

  • Extract VLAN tag information into mbuf

  • Insert VLAN tag into mbuf

Extract VLAN tag information into mbuf

/**
 * Extract VLAN tag information into mbuf
 *
 * Software version of VLAN stripping
 *
 * @param m
 *   The packet mbuf.
 * @return
 *   - 0: Success
 *   - 1: not a vlan packet
 */
static inline int rte_vlan_strip(struct rte_mbuf *m)
{
	struct rte_ether_hdr *eh
		 = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
	struct rte_vlan_hdr *vh;

	if (eh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN))
		return -1;

	vh = (struct rte_vlan_hdr *)(eh + 1);
	m->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
	m->vlan_tci = rte_be_to_cpu_16(vh->vlan_tci);

	/* Copy ether header over rather than moving whole packet */
	memmove(rte_pktmbuf_adj(m, sizeof(struct rte_vlan_hdr)),
		eh, 2 * RTE_ETHER_ADDR_LEN);

	return 0;
}

Insert VLAN tag into mbuf

/**
 * Insert VLAN tag into mbuf.
 *
 * Software version of VLAN unstripping
 *
 * @param m
 *   The packet mbuf.
 * @return
 *   - 0: On success
 *   -EPERM: mbuf is is shared overwriting would be unsafe
 *   -ENOSPC: not enough headroom in mbuf
 */
static inline int rte_vlan_insert(struct rte_mbuf **m)
{
	struct rte_ether_hdr *oh, *nh;
	struct rte_vlan_hdr *vh;

	/* Can't insert header if mbuf is shared */
	if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_read(*m) > 1)
		return -EINVAL;

	/* Can't insert header if the first segment is too short */
	if (rte_pktmbuf_data_len(*m) < 2 * RTE_ETHER_ADDR_LEN)
		return -EINVAL;

	oh = rte_pktmbuf_mtod(*m, struct rte_ether_hdr *);
	nh = (struct rte_ether_hdr *)(void *)
		rte_pktmbuf_prepend(*m, sizeof(struct rte_vlan_hdr));
	if (nh == NULL)
		return -ENOSPC;

	memmove(nh, oh, 2 * RTE_ETHER_ADDR_LEN);
	nh->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN);

	vh = (struct rte_vlan_hdr *) (nh + 1);
	vh->vlan_tci = rte_cpu_to_be_16((*m)->vlan_tci);

	(*m)->ol_flags &= ~(RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_TX_VLAN);

	if ((*m)->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)
		(*m)->outer_l2_len += sizeof(struct rte_vlan_hdr);
	else
		(*m)->l2_len += sizeof(struct rte_vlan_hdr);

	return 0;
}

mempool

创建

查看

mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
	MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
rte_mempool_dump(stdout, mp);

输出信息

mempool <MBUF_POOL>@0x1002a1b40
  flags=10
  socket_id=0
  pool=0x100291880
  iova=0x1812a1b40
  nb_mem_chunks=10
  size=8191
  populated_size=8191
  header_size=64
  elt_size=2304
  trailer_size=0
  total_obj_size=2368
  private_data_size=64
  ops_index=6
  ops_name: <ring_mp_mc>
  avg bytes/object=2369.906483
  internal cache infos:
    cache_size=250
    cache_count[0]=0
    '''''''''