]> git.feebdaed.xyz Git - linuxyz.git/commitdiff
xdp native done
authorseantywork <seantywork@gmail.com>
Tue, 9 Sep 2025 01:43:04 +0000 (01:43 +0000)
committerseantywork <seantywork@gmail.com>
Tue, 9 Sep 2025 01:43:04 +0000 (01:43 +0000)
kxdp/README.md
kxdp/native/kxdp.c
kxdp/native/kxdp.h
kxdp/xdp-prog/Makefile
kxdp/xdp-prog/xdp_drop.c [new file with mode: 0644]
kxdp/xdp-prog/xdp_pass.c

index 51262378b4742fdc92185f5283675504b7d45197..7e72eb9337a4db19ada563c1c95d3ef979f33bec 100644 (file)
@@ -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
 
index cf568c60fe74ad74c68cb2e35e419c0b2ab5e866..fb33dc84c4a114f26bc56a9c4a2d67279b4fd5c4 100644 (file)
@@ -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;
 
index 27aed1d9445028cf3f9edc6214b057721e305eca..2a6ec871fcf82a30d50cebb10a8437513235a71a 100644 (file)
@@ -31,7 +31,9 @@
 #include <net/neighbour.h>
 #include <net/route.h>
 #include <net/arp.h>
+
 #include <net/xdp.h>
+#include <linux/filter.h>
 
 
 #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];
index b152f0b5c9eca426b329bd2917a3ce5824898c1c..038399099bb5dd4eaefb09e7d623562f497d8455 100644 (file)
@@ -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 (file)
index 0000000..9a46943
--- /dev/null
@@ -0,0 +1,25 @@
+
+#define AF_INET                2       /* Internet IP Protocol         */
+#define ETH_ALEN    6
+
+#include <linux/bpf.h>
+
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/in.h>
+#include <linux/string.h>
+
+
+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
index 8bbb345036ef7f7679df56948ac109d731a8142b..2b26ec87d695a151236ea60870faf4e91f049af0 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/string.h>
 
 
-SEC("xdp_pass")
+SEC("xdp_prog")
 int xdp_pass_prog(struct xdp_md *ctx)
 {