ZBLOG

dpdk的kni使用例子,给出代码并注释。

下面是一个使用DPDK的KNI(Kernel Network Interface)的简单例子,包括初始化KNI、接收数据包和发送数据包。

”`c #include #include #include #include

#include #include #include

#define MAX_PKT_BURST 32

/* KNI interface configuration */ static struct rte_kni_conf kni_conf = {

.group_id = 0,
.mbuf_size = (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM),
.hdr_len = 0,
.addr = {},
.id = {}

};

/* KNI interface status */ static struct rte_kni *kni;

/* Ethernet port configuration */ static const uint16_t nb_rxd = 128; static const uint16_t nb_txd = 512;

struct rte_eth_conf port_conf = {

.rxmode = {
    .max_rx_pkt_len = ETHER_MAX_LEN,
    .split_hdr_size = 0,
    .header_split   = 0, /**< Header Split disabled. */
    .hw_ip_checksum_ok      = 1, /**< IP checksum verification enabled. */
    .hw_vlan_filter         = 0, /**< VLAN filtering enabled. */
    .jumbo_frame            = 0, /**< Jumbo Frame Support disabled. */
    .hw_strip_crc           = 1, /**< CRC stripped by hardware. */
},
.txmode = {
    /* No need to configure anything here for transmit mode */
},

};

/* Ethernet port status */ struct rte_eth_dev_info dev_info; struct ether_addr addr;

/**

  • Initialize the KNI interface. *

  • @return

  • - On success, zero.

    • On failure, a negative value. */ int kni_init(void) { int ret;

    /* Set the KNI interface name */ snprintf(kni_conf.name, RTE_KNI_NAMESIZE, “vEth0”);

    /* Create the KNI interface */ kni = rte_kni_alloc(rte_eth_dev_get_port_by_name(“eth0”), &kni_conf);

    if (kni == NULL) {

    printf("Failed to create kni\n");
    return -1;
    

    }

    /* Initialize the KNI interface */ ret = rte_kni_init(kni, &kni_conf); if (ret < 0) {

    printf("Failed to init kni: %s\n", strerror(-ret));
    return ret;
    

    }

    return 0; }

/**

  • Receive packets from the Ethernet port and forward them to the KNI
  • interface. *
  • @param[in] port_id
  • The Ethernet port ID. */ void rx_packets(uint16_t port_id) { #define MAX_PKT_BURST 32

#define RX_RING_SIZE 128 #define TX_RING_SIZE 512

static struct rte_eth_conf port_conf = { .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN, .split_hdr_size = 0, .header_split = 0, .hw_ip_checksum_ok = 1, .hw_vlan_filter = 0, .jumbo_frame = 0, .hw_strip_crc = 1, }, .txmode = { /* No need to configure anything here for transmit mode */ }, };

struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; unsigned nb_rx_pkts;

/* Receive packets from the Ethernet port */ nb_rx_pkts = rte_eth_rx_burst(port_id, 0, pkts_burst, MAX_PKT_BURST);

if (nb_rx_pkts == 0) return;

/* Forward packets to the KNI interface */ for (unsigned i = 0; i < nb_rx_pkts; i++) {

struct rte_mbuf *pkt = pkts_burst[i];
rte_pktmbuf_free(pkt);

} }

/**

  • Send packets received from the KNI interface back out on the Ethernet
  • port. *
  • @param[in] port_id
  • The Ethernet port ID. */ void tx_packets(uint16_t port_id) { #define MAX_PKT_BURST 32

#define RX_RING_SIZE 128 #define TX_RING_SIZE 512

struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; unsigned nb_tx_pkts;

/* Receive packets from the KNI interface */ nb_tx_pkts = rte_kni_tx_burst(kni, pkts_burst, MAX_PKT_BURST);

if (nb_tx_pkts == 0) return;

/* Send packets to the Ethernet port */ rte_eth_tx_burst(port_id, 0, pkts_burst, nb_tx_pkts); }

int main(int argc, char **argv) { uint16_t nb_ports; uint16_t port_id = -1;

/* Initialize DPDK */ int ret = rte_eal_init(argc, argv); if (ret < 0) { printf(“Failed to initialize dpdk: %s\n”, strerror(-ret)); return -1; }

argc -= ret; argv += ret;

/* Get number of available ports */ nb_ports = rte_eth_dev_count_avail(); if (nb_ports == 0) { printf(“No ethernet ports available\n”); return -1; }

/* Find first available Ethernet port */ for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {

if ((rte_eth_devices[port_id].state == RTE_ETH_DEV_ATTACHED) &&
    (rte_eth_devices[port_id].data->dev_flags & RTE_ETH_DEV_DETACHABLE)) {
    break;
}

}

/* Check if an available Ethernet port was found */ if (port_id == RTE_MAX_ETHPORTS) { printf(“No available ethernet ports\n”); return -1; }

/* Initialize the KNI interface */ ret = kni_init(); if (ret < 0) { printf(“Failed to initialize KNI interface: %s\n”, strerror(-ret)); return -1; }

/* Configure Ethernet port */ memset(&dev_info, 0, sizeof(dev_info)); rte_eth_dev_info_get(port_id, &dev_info); memset(&addr, 0, sizeof(addr)); ether_addr_copy(&dev_info.default_mac_addr, &addr); rte_eth_dev_configure(port_id, 1, 1, &port_conf);

/* Start the Ethernet port */ rte_eth_dev_start(port_id);

for (;;) {

/* Receive packets from the Ethernet port and forward them to the KNI
 * interface.
 */
rx_packets(port_id);

/* Send packets received from the KNI interface back out on the Ethernet
 * port.
 */
tx_packets(port_id);




内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=1575

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?