From: Joshua Coutinho <souichirosano@gmail.com>
To: xdp-newbies@vger.kernel.org
Subject: XSK tx on loopback drops packets.
Date: Mon, 4 Dec 2023 15:41:50 +0000 [thread overview]
Message-ID: <CAOafi9EZ8L150jw_pC_DZj4_VO6r-BxCMDZzsC_X-V06o73org@mail.gmail.com> (raw)
Hi All,
I'm trying to transmit udp packets via an xsk socket. (XDP receives
work just fine). The xdp program is irrelevant/unused, I'm trying to
simply leverage the xsk socket write.
(Kernel: Linux fedora 6.5.12-300.fc39.x86_64)
(OS: "Fedora Linux 39 (Workstation Edition)"
I want a minimal working example of sending packets via an XSK socket
over loopback in user space land. I want to be able to fill in the
required memory regions and trigger the kernel to send the packet and
capture the sent packets on the other side with 'nc -lu 127.0.0.1
<port>' This seems to happen partly successfully but on the ingress
part of the loopback it is dropped somewhere after reaching the kernel
function ip_rcv and then nf_hook_slow. Specifically, I simply want to
write a packet into a UMEM region, fill in the TX descriptor and then
submit that descriptor like so.
u32 txIdx = -1;
const u32 txSlotsRecvd = xsk_ring_prod__reserve(&qs.txQ, 1, &txIdx);
u32 addr = umem.txState.nextSlot();
xdp_desc* txDescr = xsk_ring_prod__tx_desc(&qs.txQ, txIdx);
txDescr->addr = addr;
txDescr->len = sizeof(OrderFrame);
txDescr->options = 0;
u8* outputBuf = umem.buffer + addr;
TimeNs submitTime = currentTimeNs();
OrderFrame& frame = *reinterpret_cast<OrderFrame *>(outputBuf);
std::array<u8, ETH_ALEN> sourceMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
std::array<u8, ETH_ALEN> destMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
std::copy(sourceMac.begin(), sourceMac.end(), frame.eth.h_source);
std::copy(destMac.begin(), destMac.end(), frame.eth.h_dest);
frame.eth.h_proto = htons(ETH_P_IP);
frame.ip.ihl = 5;
frame.ip.version = 4;
frame.ip.tos = 0;
frame.ip.tot_len = htons(sizeof(OrderFrame) - sizeof(ethhdr));
frame.ip.id = orderId;
frame.ip.frag_off = 0x0;
frame.ip.ttl = static_cast<u8>(255);
frame.ip.protocol = 17;
frame.ip.check = 0;
constexpr u8 sourceIPBytes[4] = {127, 0, 0, 1};
constexpr u8 destIPBytes[4] = {127, 0, 0, 1};
const u32 sourceIP = *reinterpret_cast<const u32*>(sourceIPBytes);
const u32 destIP = *reinterpret_cast<const u32*>(destIPBytes);
frame.ip.saddr = sourceIP;
frame.ip.daddr = destIP;
const u8* dataptr = reinterpret_cast<u8 *>(&frame.ip);
const u16 kernelcsum = ip_fast_csum(dataptr, frame.ip.ihl);
frame.ip.check = kernelcsum;
constexpr int udpPacketSz = sizeof(OrderFrame) -
sizeof(ethhdr) - sizeof(iphdr);
frame.udp.len = htons(udpPacketSz);
frame.udp.check = 0;
frame.udp.dest = htons(OE_PORT);
frame.udp.source = htons(1234);
... // application packet logic
frame.udp.check = 0;
xsk_ring_prod__submit(&qs.txQ, 1);
if (xsk_ring_prod__needs_wakeup(&qs.txQ)) {
assert((socket.cfg.bind_flags & XDP_COPY) != 0);
const ssize_t ret = sendto(socket.xskFD, nullptr, 0,
MSG_DONTWAIT, nullptr, 0);
}
This is a relevant stacktrace from the kernel indicating the path of
my packet after the above sendto is called.
__netif_receive_skb_one_core+0x3c/0xa0
process_backlog+0x85/0x120
__napi_poll+0x28/0x1b0
net_rx_action+0x2a4/0x380
__do_softirq+0xd1/0x2c8
do_softirq.part.0+0x3d/0x60
__local_bh_enable_ip+0x68/0x70
__dev_direct_xmit+0x152/0x210
__xsk_generic_xmit+0x3e4/0x710
xsk_sendmsg+0x12f/0x1f0
__sys_sendto+0x1d6/0x1e0
__x64_sys_sendto+0x24/0x30
do_syscall_64+0x5d/0x90
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
My socket is bound to localhost using xdpgeneric. I see the
transmitted packets in tcpdump and via bpftrace I see that ip_rcv is
invoked for the packets. nf_hook_slow is also invoked with 1 active
prerouting hook. On kfree_skb I see the reason for the drop is 'reason
not specified'. Examining the packet in tcpdump I see no errors with
the checksums or packet lengths and ports. Listeners for the
corresponding udp ports never receieve the packets.This is how I
create my socket
cfg.rx_size = XSKQueues::NUM_READ_DESC;
cfg.tx_size = XSKQueues::NUM_WRITE_DESC;
cfg.libxdp_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
cfg.xdp_flags = XDP_FLAGS_SKB_MODE;
cfg.bind_flags = XDP_USE_NEED_WAKEUP | XDP_COPY;
if (xsk_socket__create(&socket, iface.c_str(), QUEUE, umem.umem,
&qs.rxQ, &qs.txQ, &cfg)) {
perror("XSK: ");
exit(EXIT_FAILURE);
}
What could be the issue?
next reply other threads:[~2023-12-04 15:42 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-04 15:41 Joshua Coutinho [this message]
2023-12-11 10:12 ` XSK tx on loopback drops packets Joshua Coutinho
2023-12-11 10:26 ` Magnus Karlsson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAOafi9EZ8L150jw_pC_DZj4_VO6r-BxCMDZzsC_X-V06o73org@mail.gmail.com \
--to=souichirosano@gmail.com \
--cc=xdp-newbies@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).