STRUCT LIBETH_XDP_TX_FRAME(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct libeth_xdp_tx_frame β€” the kernel API manual ✨

okay so bestie, welcome to the glow-up doc for struct libeth_xdp_tx_frame πŸ¦‹ this is the little struct that represents one XDP Tx element β€” like, one single packet-shaped unit of main character energy in the Tx ring πŸ’– no cap, it's giving "small struct, big job."


✨ NAME ✨

struct libeth_xdp_tx_frame β€” represents one XDP Tx element πŸŽ€


🌸 SYNOPSIS 🌸

ok so the shape of it is literally this, don't touch anything, copy it exact:

struct libeth_xdp_tx_frame {
    union {
      struct {
        void *data;
        u32 len_fl;
        u32 soff;
      };
      skb_frag_t frag;
      struct {
        union {
          struct xdp_frame                *xdpf;
          dma_addr_t dma;
          struct libeth_xdp_buff          *xsk;
        };
        union {
          struct {
            u32 len;
            u32 flags;
          };
          aligned_u64 opts;
        };
      };
      struct xdp_desc                 desc;
   };
 };

like… the nesting?? the way that union inside struct inside union inside struct ate πŸ’€ it's a whole matryoshka doll of memory layouts and honestly we stan a union that's doing the absolute most 😭


🫢 Members 🫢

let's go member by member, bestie, no skipping, i would never πŸ™ˆ

  • {unnamed_union} β€” anonymous πŸ‘» (yes it's literally anonymous, it has no name, it's the mystery icon of the struct)
  • {unnamed_struct} β€” anonymous πŸ‘» and its struct bestie is anonymous too, iconic behavior
  • data β€” frame start pointer for XDP_TX ⭐ where the frame begins, periodt
  • len_fl β€” XDP_TX, combined flags [31:16] and len [15:0] field for speed πŸ”₯ like, the flags live in the top bits and the length lives in the bottom bits, mashed into one field because speed matters and we love a shortcut
  • soff β€” XDP_TX, offset from data to the start of skb_shared_info πŸŽ€ so soff = "start offset", the distance from data to where skb_shared_info begins
  • frag β€” one (non-head) frag for XDP_TX 🧚 literally one non-head frag, that's the whole vibe
  • {unnamed_struct} β€” anonymous πŸ‘» yep, another one
  • {unnamed_union} β€” anonymous πŸ‘» and another one, the anonymity is highkey contagious
  • xdpf β€” xdp_frame for the head frag for .ndo_xdp_xmit πŸ‘‘ the head frag's xdp_frame, for when you're going through .ndo_xdp_xmit
  • dma β€” DMA address of the non-head frag for .ndo_xdp_xmit 🌈 the non-head frag's DMA address, same .ndo_xdp_xmit situation
  • xsk β€” XDP_TX for XSk, XDP buffer for any frag πŸ’œ for XDP_TX when it's XSk, and it's the XDP buffer for any frag
  • {unnamed_union} β€” anonymous πŸ‘» third time's the charm
  • {unnamed_struct} β€” anonymous πŸ‘» and its anonymous struct buddy, slay
  • len β€” frag length for XSk XDP_TX and .ndo_xdp_xmit πŸ“ the frag length, for XSk XDP_TX and .ndo_xdp_xmit
  • flags β€” Tx flags for the above πŸ¦‹ Tx flags for the stuff we just talked about, iykyk
  • opts β€” combined len + flags for the above for speed ⚑ combined len + flags for the above, packed together, again for speed, because nobody has time for two fields
  • desc β€” XSk xmit descriptor for direct casting ✨ the XSk xmit descriptor, there specifically so you can cast directly to it
lowkey the theme here is "pack it into one field for speed" and honestly? valid. speed is the aesthetic πŸ’…

πŸ‘‘ SEE ALSO πŸ‘‘

Kernel file ./include/net/libeth/xdp.h, plus this whole friend group 🌸:

struct libeth_xdp_buff(9), __LIBETH_XDP_ONSTACK_BUFF(9), LIBETH_XDP_ONSTACK_BUFF(9), libeth_xdpsq_num(9), libeth_xdpsq_shared(9), libeth_xdpsq_id(9), libeth_xdpsq_get(9), libeth_xdpsq_put(9), libeth_xdpsq_lock(9), libeth_xdpsq_unlock(9), libeth_xdpsq_deinit_timer(9), libeth_xdpsq_queue_timer(9), libeth_xdpsq_run_timer(9), enum (anonymous)(9), enum (anonymous)(9), struct libeth_xdp_tx_bulk(9), LIBETH_XDP_ONSTACK_BULK(9), struct libeth_xdpsq(9), struct libeth_xdp_tx_desc(9), libeth_xdp_ptr_to_priv(9), libeth_xdp_priv_to_ptr(9), libeth_xdp_tx_xmit_bulk(9), libeth_xdp_tx_queue_head(9), libeth_xdp_tx_queue_frag(9), libeth_xdp_tx_queue_bulk(9), libeth_xdp_tx_fill_stats(9), libeth_xdp_tx_fill_buf(9), __libeth_xdp_tx_flush_bulk(9), libeth_xdp_tx_flush_bulk(9), libeth_xdp_xmit_init_bulk(9), libeth_xdp_xmit_frame_dma(9), libeth_xdp_xmit_queue_head(9), libeth_xdp_xmit_queue_frag(9), libeth_xdp_xmit_queue_bulk(9), libeth_xdp_xmit_fill_buf(9), libeth_xdp_xmit_flush_bulk(9), __libeth_xdp_xmit_do_bulk(9), libeth_xdp_xmit_do_bulk(9), libeth_xdp_tx_init_bulk(9), libeth_xdp_init_buff(9), libeth_xdp_save_buff(9), libeth_xdp_return_stash(9), libeth_xdp_return_buff(9), libeth_xdp_prepare_buff(9), libeth_xdp_process_buff(9), libeth_xdp_buff_stats_frags(9), __libeth_xdp_run_prog(9), __libeth_xdp_run_flush(9), libeth_xdp_run_prog(9), __libeth_xdp_run_pass(9), libeth_xdp_run_pass(9), libeth_xdp_finalize_rx(9), LIBETH_XDP_DEFINE_TIMER(9), LIBETH_XDP_DEFINE_FLUSH_TX(9), LIBETH_XDP_DEFINE_FLUSH_XMIT(9), LIBETH_XDP_DEFINE_RUN_PROG(9), LIBETH_XDP_DEFINE_RUN_PASS(9), LIBETH_XDP_DEFINE_RUN(9), LIBETH_XDP_DEFINE_FINALIZE(9), libeth_xdp_buff_to_rq(9), libeth_xdpmo_rx_hash(9), __libeth_xdp_complete_tx(9), libeth_xdp_set_features(9), libeth_xdp_set_features_noredir(9) πŸŽ€


and that's the whole page bestie! 🌈 this one lives in ./include/net/libeth, dated October 2026, and it's filed under struct libeth_xdp_tx_frame(9) β€” go forth and Tx your XDP elements with confidence, mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from