aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/docs/dpdk.dox12
-rw-r--r--host/lib/CMakeLists.txt2
-rw-r--r--host/lib/include/uhdlib/transport/dpdk/udp.hpp25
-rw-r--r--host/lib/transport/udp_dpdk_link.cpp5
-rw-r--r--host/lib/transport/uhd-dpdk/dpdk_common.cpp71
-rw-r--r--host/lib/transport/uhd-dpdk/dpdk_io_service.cpp34
6 files changed, 100 insertions, 49 deletions
diff --git a/host/docs/dpdk.dox b/host/docs/dpdk.dox
index 54ed1c6e4..539a6ce18 100644
--- a/host/docs/dpdk.dox
+++ b/host/docs/dpdk.dox
@@ -26,7 +26,7 @@ computer.
\subsection dpdk_installation DPDK Installation Instructions
As a new and developing technology, the DPDK APIs are unstable. UHD requires
-version 19.11 or 20.11.
+version 19.11, 20.11 or 21.11.
On Ubuntu 20.04, Fedora 33-36, or Debian Bullseye/Buster (via backports),
DPDK is available in your distribution's repositories. For example, on Debian
@@ -35,8 +35,8 @@ systems, it can be obtained with the following command:
sudo apt install dpdk dpdk-dev
Otherwise, you'll need to follow the build guide at
-https://doc.dpdk.org/guides-20.11/linux_gsg/build_dpdk.html . The software
-releases can be found at https://core.dpdk.org/download/. Version 20.11 builds
+https://doc.dpdk.org/guides-21.11/linux_gsg/build_dpdk.html . The software
+releases can be found at https://core.dpdk.org/download/. Version >=20.11 builds
with appropriate options when using the default build procedure.
Note that if you are using a Mellanox NIC, the MLNX-OFED drivers available from
@@ -61,7 +61,7 @@ following line:
\subsection dpdk_system_configuration System Configuration
The official documentation regarding system configuration can be found at
-https://doc.dpdk.org/guides-20.11/linux_gsg/sys_reqs.html.
+https://doc.dpdk.org/guides-21.11/linux_gsg/sys_reqs.html.
First, you'll need to enable the IOMMU and set up some hugepages. DPDK will
completely take over all available hugepages, so don't allocate all your memory
@@ -107,7 +107,7 @@ If successful, the script might provide an updated status like this:
[...]
-See https://doc.dpdk.org/guides-20.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules
+See https://doc.dpdk.org/guides-21.11/linux_gsg/linux_drivers.html#binding-and-unbinding-network-ports-to-from-the-kernel-modules
for more details.
With the hugepages, IOMMU, and drivers set up, the system is ready for DPDK to
@@ -141,7 +141,7 @@ options:
;create a separate folder with symlinks to the librte_pmd_* and librte_mempool_* libraries.
dpdk_driver=/usr/local/lib/x86_64-linux-gnu/dpdk/pmds-21.0/
;dpdk_corelist is the -l flag for the DPDK EAL. See more at the link
- ; https://doc.dpdk.org/guides-20.11/linux_gsg/build_sample_apps.html#running-a-sample-application
+ ; https://doc.dpdk.org/guides-21.11/linux_gsg/build_sample_apps.html#running-a-sample-application
dpdk_corelist=0,1
;dpdk_num_mbufs is the total number of packet buffers allocated
;to each direction's packet buffer pool
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index 00da8b75c..094827d2a 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -60,7 +60,7 @@ endmacro(INCLUDE_SUBDIRECTORY)
message(STATUS "")
# Dependencies
find_package(LIBUSB)
-find_package(DPDK 19.11...20.11)
+find_package(DPDK 19.11...21.11)
LIBUHD_REGISTER_COMPONENT("USB" ENABLE_USB ON "ENABLE_LIBUHD;LIBUSB_FOUND" OFF OFF)
# Devices
LIBUHD_REGISTER_COMPONENT("B100" ENABLE_B100 ON "ENABLE_LIBUHD;ENABLE_USB" OFF OFF)
diff --git a/host/lib/include/uhdlib/transport/dpdk/udp.hpp b/host/lib/include/uhdlib/transport/dpdk/udp.hpp
index 712b73d81..d43fa3959 100644
--- a/host/lib/include/uhdlib/transport/dpdk/udp.hpp
+++ b/host/lib/include/uhdlib/transport/dpdk/udp.hpp
@@ -15,7 +15,8 @@
namespace uhd { namespace transport { namespace dpdk {
constexpr size_t HDR_SIZE_UDP_IPV4 =
- (sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + sizeof(struct rte_udp_hdr));
+ (sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)
+ + sizeof(struct rte_udp_hdr));
/*!
* An enumerated type representing the type of flow for an IPv4 client
@@ -57,12 +58,17 @@ inline void fill_rte_ipv4_hdr(struct rte_mbuf* mbuf,
ip_hdr->hdr_checksum = 0; // Require HW offload
ip_hdr->src_addr = port->get_ipv4();
ip_hdr->dst_addr = dst_rte_ipv4_addr;
-
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ mbuf->ol_flags = RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_IPV4;
+#else
mbuf->ol_flags = PKT_TX_IP_CKSUM | PKT_TX_IPV4;
- mbuf->l2_len = sizeof(struct rte_ether_hdr);
- mbuf->l3_len = sizeof(struct rte_ipv4_hdr);
- mbuf->pkt_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + payload_len;
- mbuf->data_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + payload_len;
+#endif
+ mbuf->l2_len = sizeof(struct rte_ether_hdr);
+ mbuf->l3_len = sizeof(struct rte_ipv4_hdr);
+ mbuf->pkt_len =
+ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + payload_len;
+ mbuf->data_len =
+ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + payload_len;
}
/* All values except payload length must be in network order */
@@ -77,8 +83,11 @@ inline void fill_rte_udp_hdr(struct rte_mbuf* mbuf,
struct rte_ipv4_hdr* ip_hdr;
struct rte_udp_hdr* tx_hdr;
- fill_rte_ipv4_hdr(
- mbuf, port, dst_rte_ipv4_addr, IPPROTO_UDP, sizeof(struct rte_udp_hdr) + payload_len);
+ fill_rte_ipv4_hdr(mbuf,
+ port,
+ dst_rte_ipv4_addr,
+ IPPROTO_UDP,
+ sizeof(struct rte_udp_hdr) + payload_len);
eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
ip_hdr = (struct rte_ipv4_hdr*)&eth_hdr[1];
diff --git a/host/lib/transport/udp_dpdk_link.cpp b/host/lib/transport/udp_dpdk_link.cpp
index 194b0536c..4249d4bb8 100644
--- a/host/lib/transport/udp_dpdk_link.cpp
+++ b/host/lib/transport/udp_dpdk_link.cpp
@@ -175,8 +175,13 @@ void udp_dpdk_link::release_send_buff(frame_buff::uptr buff)
// Fill in L2 header
auto local_mac = _port->get_mac_addr();
struct rte_ether_hdr* l2_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ rte_ether_addr_copy(&_remote_mac, &l2_hdr->dst_addr);
+ rte_ether_addr_copy(&local_mac, &l2_hdr->src_addr);
+#else
rte_ether_addr_copy(&_remote_mac, &l2_hdr->d_addr);
rte_ether_addr_copy(&local_mac, &l2_hdr->s_addr);
+#endif
l2_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
// Fill in L3 and L4 headers
dpdk::fill_rte_udp_hdr(mbuf,
diff --git a/host/lib/transport/uhd-dpdk/dpdk_common.cpp b/host/lib/transport/uhd-dpdk/dpdk_common.cpp
index a84b0f4a3..55bf57cdc 100644
--- a/host/lib/transport/uhd-dpdk/dpdk_common.cpp
+++ b/host/lib/transport/uhd-dpdk/dpdk_common.cpp
@@ -49,9 +49,9 @@ inline void separate_rte_ipv4_addr(
boost::algorithm::split(
result, ipv4, [](const char& in) { return in == '/'; }, boost::token_compress_on);
UHD_ASSERT_THROW(result.size() == 2);
- rte_ipv4_addr = (uint32_t)inet_addr(result[0].c_str());
- int netbits = std::atoi(result[1].c_str());
- netmask = htonl(0xffffffff << (32 - netbits));
+ rte_ipv4_addr = (uint32_t)inet_addr(result[0].c_str());
+ int netbits = std::atoi(result[1].c_str());
+ netmask = htonl(0xffffffff << (32 - netbits));
}
} // namespace
@@ -63,8 +63,13 @@ dpdk_port::uptr dpdk_port::make(port_id_t port,
struct rte_mempool* tx_pktbuf_pool,
std::string rte_ipv4_address)
{
- return std::make_unique<dpdk_port>(
- port, mtu, num_queues, num_desc, rx_pktbuf_pool, tx_pktbuf_pool, rte_ipv4_address);
+ return std::make_unique<dpdk_port>(port,
+ mtu,
+ num_queues,
+ num_desc,
+ rx_pktbuf_pool,
+ tx_pktbuf_pool,
+ rte_ipv4_address);
}
dpdk_port::dpdk_port(port_id_t port,
@@ -83,17 +88,6 @@ dpdk_port::dpdk_port(port_id_t port,
/* Set MTU and IPv4 address */
int retval;
- retval = rte_eth_dev_set_mtu(_port, _mtu);
- if (retval) {
- uint16_t actual_mtu;
- UHD_LOGGER_WARNING("DPDK")
- << boost::format("Port %d: Could not set mtu to %d") % _port % _mtu;
- rte_eth_dev_get_mtu(_port, &actual_mtu);
- UHD_LOGGER_WARNING("DPDK")
- << boost::format("Port %d: Current mtu=%d") % _port % actual_mtu;
- _mtu = actual_mtu;
- }
-
separate_rte_ipv4_addr(rte_ipv4_address, _ipv4, _netmask);
/* Set hardware offloads */
@@ -121,11 +115,19 @@ dpdk_port::dpdk_port(port_id_t port,
_num_queues = num_queues;
}
- struct rte_eth_conf port_conf = {};
- port_conf.rxmode.offloads = rx_offloads | DEV_RX_OFFLOAD_JUMBO_FRAME;
+ struct rte_eth_conf port_conf = {};
+#ifdef DEV_RX_OFFLOAD_JUMBO_FRAME
+ port_conf.rxmode.offloads = rx_offloads | DEV_RX_OFFLOAD_JUMBO_FRAME;
+#else
+ port_conf.rxmode.offloads = rx_offloads;
+#endif
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ port_conf.rxmode.mtu = _mtu;
+#else
port_conf.rxmode.max_rx_pkt_len = _mtu;
- port_conf.txmode.offloads = tx_offloads;
- port_conf.intr_conf.lsc = 1;
+#endif
+ port_conf.txmode.offloads = tx_offloads;
+ port_conf.intr_conf.lsc = 1;
retval = rte_eth_dev_configure(_port, _num_queues, _num_queues, &port_conf);
if (retval != 0) {
@@ -133,6 +135,17 @@ dpdk_port::dpdk_port(port_id_t port,
throw uhd::runtime_error("DPDK: Failed to configure the device");
}
+ retval = rte_eth_dev_set_mtu(_port, _mtu);
+ if (retval) {
+ uint16_t actual_mtu;
+ UHD_LOGGER_WARNING("DPDK")
+ << boost::format("Port %d: Could not set mtu to %d") % _port % _mtu;
+ rte_eth_dev_get_mtu(_port, &actual_mtu);
+ UHD_LOGGER_WARNING("DPDK")
+ << boost::format("Port %d: Current mtu=%d") % _port % actual_mtu;
+ _mtu = actual_mtu;
+ }
+
/* Set descriptor ring sizes */
uint16_t rx_desc = num_desc;
if (dev_info.rx_desc_lim.nb_max < rx_desc || dev_info.rx_desc_lim.nb_min > rx_desc
@@ -266,18 +279,27 @@ int dpdk_port::_arp_reply(queue_id_t queue_id, struct rte_arp_hdr* arp_req)
hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
arp_frame = (struct rte_arp_hdr*)&hdr[1];
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ rte_ether_addr_copy(&arp_req->arp_data.arp_sha, &hdr->dst_addr);
+ rte_ether_addr_copy(&_mac_addr, &hdr->src_addr);
+#else
rte_ether_addr_copy(&arp_req->arp_data.arp_sha, &hdr->d_addr);
rte_ether_addr_copy(&_mac_addr, &hdr->s_addr);
+#endif
hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
arp_frame->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER);
arp_frame->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
- arp_frame->arp_hlen = 6;
- arp_frame->arp_plen = 4;
- arp_frame->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REPLY);
+ arp_frame->arp_hlen = 6;
+ arp_frame->arp_plen = 4;
+ arp_frame->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REPLY);
rte_ether_addr_copy(&_mac_addr, &arp_frame->arp_data.arp_sha);
arp_frame->arp_data.arp_sip = _ipv4;
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ rte_ether_addr_copy(&hdr->dst_addr, &arp_frame->arp_data.arp_tha);
+#else
rte_ether_addr_copy(&hdr->d_addr, &arp_frame->arp_data.arp_tha);
+#endif
arp_frame->arp_data.arp_tip = arp_req->arp_data.arp_sip;
mbuf->pkt_len = 42;
@@ -619,7 +641,8 @@ struct rte_mempool* dpdk_ctx::_get_rx_pktbuf_pool(
unsigned int cpu_socket, size_t num_bufs)
{
if (!_rx_pktbuf_pools.at(cpu_socket)) {
- const int mbuf_size = _mtu + RTE_PKTMBUF_HEADROOM;
+ const int mbuf_size =
+ _mtu + RTE_PKTMBUF_HEADROOM + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
char name[32];
snprintf(name, sizeof(name), "rx_mbuf_pool_%u", cpu_socket);
_rx_pktbuf_pools[cpu_socket] = rte_pktmbuf_pool_create(name,
diff --git a/host/lib/transport/uhd-dpdk/dpdk_io_service.cpp b/host/lib/transport/uhd-dpdk/dpdk_io_service.cpp
index 4c8fa3f35..4133697ea 100644
--- a/host/lib/transport/uhd-dpdk/dpdk_io_service.cpp
+++ b/host/lib/transport/uhd-dpdk/dpdk_io_service.cpp
@@ -570,10 +570,10 @@ void dpdk_io_service::_service_xport_disconnect(dpdk::wait_req* req)
int dpdk_io_service::_service_arp_request(dpdk::wait_req* req)
{
- int status = 0;
- auto arp_req_data = (struct dpdk::arp_request*)req->data;
+ int status = 0;
+ auto arp_req_data = (struct dpdk::arp_request*)req->data;
dpdk::rte_ipv4_addr dst_addr = arp_req_data->tpa;
- auto ctx_sptr = _ctx.lock();
+ auto ctx_sptr = _ctx.lock();
UHD_ASSERT_THROW(ctx_sptr);
dpdk::dpdk_port* port = ctx_sptr->get_port(arp_req_data->port);
UHD_LOG_TRACE("DPDK::IO_SERVICE",
@@ -629,15 +629,20 @@ int dpdk_io_service::_send_arp_request(
hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*);
arp_frame = (struct rte_arp_hdr*)&hdr[1];
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ memset(hdr->dst_addr.addr_bytes, 0xFF, RTE_ETHER_ADDR_LEN);
+ hdr->src_addr = port->get_mac_addr();
+#else
memset(hdr->d_addr.addr_bytes, 0xFF, RTE_ETHER_ADDR_LEN);
- hdr->s_addr = port->get_mac_addr();
+ hdr->s_addr = port->get_mac_addr();
+#endif
hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP);
- arp_frame->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER);
- arp_frame->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
- arp_frame->arp_hlen = 6;
- arp_frame->arp_plen = 4;
- arp_frame->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REQUEST);
+ arp_frame->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER);
+ arp_frame->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
+ arp_frame->arp_hlen = 6;
+ arp_frame->arp_plen = 4;
+ arp_frame->arp_opcode = rte_cpu_to_be_16(RTE_ARP_OP_REQUEST);
arp_frame->arp_data.arp_sha = port->get_mac_addr();
arp_frame->arp_data.arp_sip = port->get_ipv4();
memset(arp_frame->arp_data.arp_tha.addr_bytes, 0x00, RTE_ETHER_ADDR_LEN);
@@ -676,9 +681,18 @@ int dpdk_io_service::_rx_burst(dpdk::dpdk_port* port, dpdk::queue_id_t queue)
rte_pktmbuf_free(bufs[buf]);
break;
case RTE_ETHER_TYPE_IPV4:
+
+#if RTE_VER_YEAR > 21 || (RTE_VER_YEAR == 21 && RTE_VER_MONTH == 11)
+ if ((ol_flags & RTE_MBUF_F_RX_IP_CKSUM_MASK)
+ == RTE_MBUF_F_RX_IP_CKSUM_BAD) {
+ UHD_LOG_WARNING("DPDK::IO_SERVICE", "RX packet has bad IP cksum");
+ } else if ((ol_flags & RTE_MBUF_F_RX_IP_CKSUM_MASK)
+ == RTE_MBUF_F_RX_IP_CKSUM_NONE) {
+#else
if ((ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_BAD) {
UHD_LOG_WARNING("DPDK::IO_SERVICE", "RX packet has bad IP cksum");
} else if ((ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_NONE) {
+#endif
UHD_LOG_WARNING("DPDK::IO_SERVICE", "RX packet missing IP cksum");
} else {
_process_ipv4(port, bufs[buf], (struct rte_ipv4_hdr*)l2_data);
@@ -695,7 +709,7 @@ int dpdk_io_service::_rx_burst(dpdk::dpdk_port* port, dpdk::queue_id_t queue)
int dpdk_io_service::_process_arp(
dpdk::dpdk_port* port, dpdk::queue_id_t queue_id, struct rte_arp_hdr* arp_frame)
{
- uint32_t dest_ip = arp_frame->arp_data.arp_sip;
+ uint32_t dest_ip = arp_frame->arp_data.arp_sip;
struct rte_ether_addr dest_addr = arp_frame->arp_data.arp_sha;
UHD_LOG_TRACE("DPDK::IO_SERVICE",
"Processing ARP packet: " << dpdk::ipv4_num_to_str(dest_ip) << " -> "