From 99538dae8c4263fad8c584851c7ced3da55b94eb Mon Sep 17 00:00:00 2001 From: seantywork Date: Tue, 9 Sep 2025 01:43:04 +0000 Subject: [PATCH] xdp native done --- kxdp/README.md | 4 +- kxdp/native/kxdp.c | 103 +++++++++++++++++++++++++++++---------- kxdp/native/kxdp.h | 7 +++ kxdp/xdp-prog/Makefile | 4 ++ kxdp/xdp-prog/xdp_drop.c | 25 ++++++++++ kxdp/xdp-prog/xdp_pass.c | 2 +- 6 files changed, 115 insertions(+), 30 deletions(-) create mode 100644 kxdp/xdp-prog/xdp_drop.c diff --git a/kxdp/README.md b/kxdp/README.md index 5126237..7e72eb9 100644 --- a/kxdp/README.md +++ b/kxdp/README.md @@ -3,9 +3,9 @@ ```shell # load -xdp-loader load -m native -s xdp_pass kxdp0 "xdp_pass.o" +xdp-loader load -m native -s xdp_prog kxdp0 "xdp_pass.o" -xdp-loader load -m native -s xdp_pass kxdp1 "xdp_pass.o" +xdp-loader load -m native -s xdp_prog kxdp1 "xdp_pass.o" # unload diff --git a/kxdp/native/kxdp.c b/kxdp/native/kxdp.c index cf568c6..fb33dc8 100644 --- a/kxdp/native/kxdp.c +++ b/kxdp/native/kxdp.c @@ -181,35 +181,82 @@ int kxdp_poll(struct napi_struct *napi, int budget){ struct net_device *dev = priv->dev; struct kxdp_packet *pkt; - printk(KERN_INFO "polling\n"); - - while (npackets < budget && priv->rx_queue) { - pkt = kxdp_rx_cons_buf(dev); - skb = dev_alloc_skb(NET_IP_ALIGN + pkt->datalen); - if (! skb) { - if (printk_ratelimit()){ - printk(KERN_INFO "kxdp: packet dropped\n"); - } - priv->stats.rx_dropped++; - npackets++; - kxdp_tx_release_buffer(pkt); - continue; - } - skb_reserve(skb, NET_IP_ALIGN); - memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen); - skb->dev = dev; - skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_receive_skb(skb); - - npackets++; - priv->stats.rx_packets++; - priv->stats.rx_bytes += pkt->datalen; - kxdp_tx_release_buffer(pkt); + void *orig_data, *orig_data_end; + struct bpf_prog *xdp_prog = priv->xdp_prog; + struct xdp_buff xdp_buff; + u32 frame_sz; + u32 act; + int off; + + printk(KERN_INFO "xdp polling\n"); + + xdp_set_return_frame_no_direct(); + + pkt = kxdp_rx_cons_buf(dev); + skb = dev_alloc_skb(NET_IP_ALIGN + pkt->datalen); + skb_reserve(skb, NET_IP_ALIGN); + memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + + if(unlikely(!xdp_prog)){ + goto noxdpprog; + } + + frame_sz = skb_end_pointer(skb) - skb->head; + frame_sz = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + xdp_init_buff(&xdp_buff, frame_sz, &priv->xdp_rxq); + xdp_prepare_buff(&xdp_buff, skb->head, skb_headroom(skb), skb_headlen(skb), true); + if (skb_is_nonlinear(skb)) { + skb_shinfo(skb)->xdp_frags_size = skb->data_len; + xdp_buff_set_frags_flag(&xdp_buff); + } else { + xdp_buff_clear_frags_flag(&xdp_buff); } - printk(KERN_INFO "polling done\n"); + orig_data = xdp_buff.data; + orig_data_end = xdp_buff.data_end; + + act = bpf_prog_run_xdp(xdp_prog, &xdp_buff); + switch(act){ + case XDP_PASS: + printk(KERN_INFO "kxdp: XDP_PASS\n"); + break; + default: + printk(KERN_INFO "kxdp: XDP_DROP\n"); + goto exit; + } + off = orig_data - xdp_buff.data; + if (off > 0) + __skb_push(skb, off); + else if (off < 0) + __skb_pull(skb, -off); + + skb_reset_mac_header(skb); + + off = xdp_buff.data_end - orig_data_end; + if (off != 0){ + __skb_put(skb, off); + } + + if (xdp_buff_has_frags(&xdp_buff)){ + skb->data_len = skb_shinfo(skb)->xdp_frags_size; + } else { + skb->data_len = 0; + } + +noxdpprog: + + netif_receive_skb(skb); + + npackets++; + priv->stats.rx_packets++; + priv->stats.rx_bytes += pkt->datalen; + + printk(KERN_INFO "xdp polling done\n"); +exit: if (npackets < budget) { printk(KERN_INFO "npackets smaller than budget\n"); unsigned long flags; @@ -221,7 +268,9 @@ int kxdp_poll(struct napi_struct *napi, int budget){ spin_unlock_irqrestore(&priv->lock, flags); } - printk(KERN_INFO "polling end\n"); + printk(KERN_INFO "xdp polling end\n"); + kxdp_tx_release_buffer(pkt); + xdp_clear_return_frame_no_direct(); return npackets; diff --git a/kxdp/native/kxdp.h b/kxdp/native/kxdp.h index 27aed1d..2a6ec87 100644 --- a/kxdp/native/kxdp.h +++ b/kxdp/native/kxdp.h @@ -31,7 +31,9 @@ #include #include #include + #include +#include #define DRV_NAME "kxdp" @@ -76,6 +78,11 @@ struct kxdp_priv { struct xdp_mem_info xdp_mem; }; +struct kxdp_xdp_buff { + struct xdp_buff xdp; + struct sk_buff *skb; +}; + extern struct net_device *kxdp_devs[DRV_COUNT]; extern struct kxdp_priv *kxdp_privs[DRV_COUNT]; diff --git a/kxdp/xdp-prog/Makefile b/kxdp/xdp-prog/Makefile index b152f0b..0383990 100644 --- a/kxdp/xdp-prog/Makefile +++ b/kxdp/xdp-prog/Makefile @@ -2,3 +2,7 @@ all: clang -O2 -g -Wall -c -target bpf -o xdp_pass.o xdp_pass.c + clang -O2 -g -Wall -c -target bpf -o xdp_drop.o xdp_drop.c + +clean: + rm -rf *.o \ No newline at end of file diff --git a/kxdp/xdp-prog/xdp_drop.c b/kxdp/xdp-prog/xdp_drop.c new file mode 100644 index 0000000..9a46943 --- /dev/null +++ b/kxdp/xdp-prog/xdp_drop.c @@ -0,0 +1,25 @@ + +#define AF_INET 2 /* Internet IP Protocol */ +#define ETH_ALEN 6 + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + + +SEC("xdp_prog") +int xdp_drop_prog(struct xdp_md *ctx) +{ + + return XDP_DROP; +} + +char _license[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/kxdp/xdp-prog/xdp_pass.c b/kxdp/xdp-prog/xdp_pass.c index 8bbb345..2b26ec8 100644 --- a/kxdp/xdp-prog/xdp_pass.c +++ b/kxdp/xdp-prog/xdp_pass.c @@ -15,7 +15,7 @@ #include -SEC("xdp_pass") +SEC("xdp_prog") int xdp_pass_prog(struct xdp_md *ctx) { -- 2.43.0