mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2026-04-28 00:18:01 +00:00
Compare commits
70 Commits
refactor_a
...
e4575a6b1e
| Author | SHA1 | Date | |
|---|---|---|---|
| e4575a6b1e | |||
| 3ec3ab30fe | |||
| 7fb3ecff48 | |||
| ec59dad025 | |||
| 28b7b1620c | |||
| 9f8e240a38 | |||
| e6c05ab494 | |||
| 8aa9cf7119 | |||
| 9683e3799f | |||
| 200d293750 | |||
| ed196caebf | |||
| a049796b81 | |||
| 384fc9dd40 | |||
| 5f2df57e64 | |||
| 130d8a9edc | |||
| 40ae3d825a | |||
| 484624104e | |||
| e7c4bdb150 | |||
| 7210366e7d | |||
| 435bf27176 | |||
| 1ba27ac7cf | |||
| e4ddec3a02 | |||
| bc7b5c97d1 | |||
| fa720f8e6b | |||
| eff0f66d95 | |||
| b43c252224 | |||
| aae7aa981d | |||
| 6f9a7301af | |||
| 48923d03d4 | |||
| 019a83cf11 | |||
| 140d9e6e35 | |||
| a351b0f1b5 | |||
| 3cb73ff0c3 | |||
| 3b08c2bede | |||
| 86378d6cc4 | |||
| 00d1c583af | |||
| cfc246c80d | |||
| f3c80f9e5f | |||
| 0d3a5748dd | |||
| 079431754c | |||
| 46f5eca33d | |||
| 7081e939fb | |||
| 1e29460d6f | |||
| e180a89644 | |||
| 34a267e982 | |||
| c81aad7c67 | |||
| 2e677c2c7b | |||
| 4ea7b22b44 | |||
| b8b937bfca | |||
| 6cc29c4fa1 | |||
| 5451ba646d | |||
| 7720437ca5 | |||
| eb0a7a917d | |||
| 6f65903552 | |||
| 97e74d09be | |||
| 9c7560ed2e | |||
| 2979ceedcf | |||
| 745f59278f | |||
| 49c59b32ca | |||
| ff78140a7d | |||
| 82ff71b753 | |||
| f46e7cd846 | |||
| 9d73eb67c4 | |||
| 21ce041353 | |||
| 6402cf7be5 | |||
| 9a96e1247b | |||
| 989134f4be | |||
| b95fbd0ed0 | |||
| d84ce0c6fa | |||
| 8d07a4cd05 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ __pycache__/
|
|||||||
*.ll
|
*.ll
|
||||||
*.o
|
*.o
|
||||||
.ipynb_checkpoints/
|
.ipynb_checkpoints/
|
||||||
|
vmlinux.py
|
||||||
|
|||||||
@ -83,14 +83,14 @@ def hist() -> HashMap:
|
|||||||
def hello(ctx: c_void_p) -> c_int64:
|
def hello(ctx: c_void_p) -> c_int64:
|
||||||
process_id = pid()
|
process_id = pid()
|
||||||
one = 1
|
one = 1
|
||||||
prev = hist().lookup(process_id)
|
prev = hist.lookup(process_id)
|
||||||
if prev:
|
if prev:
|
||||||
previous_value = prev + 1
|
previous_value = prev + 1
|
||||||
print(f"count: {previous_value} with {process_id}")
|
print(f"count: {previous_value} with {process_id}")
|
||||||
hist().update(process_id, previous_value)
|
hist.update(process_id, previous_value)
|
||||||
return c_int64(0)
|
return c_int64(0)
|
||||||
else:
|
else:
|
||||||
hist().update(process_id, one)
|
hist.update(process_id, one)
|
||||||
return c_int64(0)
|
return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
TODO.md
13
TODO.md
@ -1,13 +0,0 @@
|
|||||||
## Short term
|
|
||||||
|
|
||||||
- Implement enough functionality to port the BCC tutorial examples in PythonBPF
|
|
||||||
- Add all maps
|
|
||||||
- XDP support in pylibbpf
|
|
||||||
- ringbuf support
|
|
||||||
- Add oneline IfExpr conditionals (wishlist)
|
|
||||||
|
|
||||||
## Long term
|
|
||||||
|
|
||||||
- Refactor the codebase to be better than a hackathon project
|
|
||||||
- Port to C++ and use actual LLVM?
|
|
||||||
- Fix struct_kioctx issue in the vmlinux transpiler
|
|
||||||
248446
examples/vmlinux.py
248446
examples/vmlinux.py
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
|||||||
from pythonbpf import bpf, map, section, bpfglobal, compile
|
from pythonbpf import bpf, map, section, bpfglobal, compile, compile_to_ir
|
||||||
from pythonbpf.helper import XDP_PASS
|
from pythonbpf.helper import XDP_PASS
|
||||||
from pythonbpf.maps import HashMap
|
from pythonbpf.maps import HashMap
|
||||||
|
from ctypes import c_int64, c_void_p
|
||||||
|
|
||||||
from ctypes import c_void_p, c_int64
|
|
||||||
|
|
||||||
# Instructions to how to run this program
|
# Instructions to how to run this program
|
||||||
# 1. Install PythonBPF: pip install pythonbpf
|
# 1. Install PythonBPF: pip install pythonbpf
|
||||||
@ -40,5 +40,5 @@ def hello_world(ctx: c_void_p) -> c_int64:
|
|||||||
def LICENSE() -> str:
|
def LICENSE() -> str:
|
||||||
return "GPL"
|
return "GPL"
|
||||||
|
|
||||||
|
compile_to_ir("xdp_pass.py", "xdp_pass.ll")
|
||||||
compile()
|
compile()
|
||||||
|
|||||||
@ -4,6 +4,7 @@ from .license_pass import license_processing
|
|||||||
from .functions import func_proc
|
from .functions import func_proc
|
||||||
from .maps import maps_proc
|
from .maps import maps_proc
|
||||||
from .structs import structs_proc
|
from .structs import structs_proc
|
||||||
|
from .vmlinux_parser import vmlinux_proc
|
||||||
from .globals_pass import (
|
from .globals_pass import (
|
||||||
globals_list_creation,
|
globals_list_creation,
|
||||||
globals_processing,
|
globals_processing,
|
||||||
@ -44,6 +45,7 @@ def processor(source_code, filename, module):
|
|||||||
for func_node in bpf_chunks:
|
for func_node in bpf_chunks:
|
||||||
logger.info(f"Found BPF function/struct: {func_node.name}")
|
logger.info(f"Found BPF function/struct: {func_node.name}")
|
||||||
|
|
||||||
|
vmlinux_proc(tree, module)
|
||||||
populate_global_symbol_table(tree, module)
|
populate_global_symbol_table(tree, module)
|
||||||
license_processing(tree, module)
|
license_processing(tree, module)
|
||||||
globals_processing(tree, module)
|
globals_processing(tree, module)
|
||||||
|
|||||||
@ -15,5 +15,8 @@ def deref(ptr):
|
|||||||
return result if result is not None else 0
|
return result if result is not None else 0
|
||||||
|
|
||||||
|
|
||||||
|
XDP_ABORTED = ctypes.c_int64(0)
|
||||||
XDP_DROP = ctypes.c_int64(1)
|
XDP_DROP = ctypes.c_int64(1)
|
||||||
XDP_PASS = ctypes.c_int64(2)
|
XDP_PASS = ctypes.c_int64(2)
|
||||||
|
XDP_TX = ctypes.c_int64(3)
|
||||||
|
XDP_REDIRECT = ctypes.c_int64(4)
|
||||||
|
|||||||
0
pythonbpf/tbaa_gen/__init__.py
Normal file
0
pythonbpf/tbaa_gen/__init__.py
Normal file
1
pythonbpf/vmlinux_parser/__init__.py
Normal file
1
pythonbpf/vmlinux_parser/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .import_detector import vmlinux_proc
|
||||||
5
pythonbpf/vmlinux_parser/import_detector.py
Normal file
5
pythonbpf/vmlinux_parser/import_detector.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import llvmlite.ir as ir
|
||||||
|
import ast
|
||||||
|
|
||||||
|
def vmlinux_proc(tree, module):
|
||||||
|
pass
|
||||||
@ -1,11 +1,10 @@
|
|||||||
#include <linux/bpf.h>
|
#include "vmlinux.h"
|
||||||
#include <bpf/bpf_helpers.h>
|
#include <bpf/bpf_helpers.h>
|
||||||
#define u64 unsigned long long
|
#include <bpf/bpf_endian.h>
|
||||||
#define u32 unsigned int
|
|
||||||
|
|
||||||
SEC("xdp")
|
SEC("xdp")
|
||||||
int hello(struct xdp_md *ctx) {
|
int hello(struct xdp_md *ctx) {
|
||||||
bpf_printk("Hello, World!\n");
|
bpf_printk("Hello, World! %ud \n", ctx->data);
|
||||||
return XDP_PASS;
|
return XDP_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
43
tests/failing_tests/xdp_pass.py
Normal file
43
tests/failing_tests/xdp_pass.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from pythonbpf import bpf, map, section, bpfglobal, compile, compile_to_ir
|
||||||
|
from pythonbpf.maps import HashMap
|
||||||
|
from vmlinux import struct_xdp_md, XDP_PASS
|
||||||
|
from ctypes import c_int64
|
||||||
|
|
||||||
|
# Instructions to how to run this program
|
||||||
|
# 1. Install PythonBPF: pip install pythonbpf
|
||||||
|
# 2. Run the program: python examples/xdp_pass.py
|
||||||
|
# 3. Run the program with sudo: sudo tools/check.sh run examples/xdp_pass.o
|
||||||
|
# 4. Attach object file to any network device with something like ./check.sh xdp examples/xdp_pass.o tailscale0
|
||||||
|
# 5. send traffic through the device and observe effects
|
||||||
|
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@map
|
||||||
|
def count() -> HashMap:
|
||||||
|
return HashMap(key=c_int64, value=c_int64, max_entries=1)
|
||||||
|
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@section("xdp")
|
||||||
|
def hello_world(ctx: struct_xdp_md) -> c_int64:
|
||||||
|
key = 0
|
||||||
|
one = 1
|
||||||
|
prev = count().lookup(key)
|
||||||
|
if prev:
|
||||||
|
prevval = prev + 1
|
||||||
|
print(f"count: {prevval}")
|
||||||
|
count().update(key, prevval)
|
||||||
|
return XDP_PASS
|
||||||
|
else:
|
||||||
|
count().update(key, one)
|
||||||
|
|
||||||
|
return XDP_PASS
|
||||||
|
|
||||||
|
|
||||||
|
@bpf
|
||||||
|
@bpfglobal
|
||||||
|
def LICENSE() -> str:
|
||||||
|
return "GPL"
|
||||||
|
|
||||||
|
compile_to_ir("xdp_pass.py", "xdp_pass.ll")
|
||||||
|
compile()
|
||||||
@ -243,6 +243,17 @@ class BTFConverter:
|
|||||||
data
|
data
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# below to replace those c_bool with bitfield greater than 8
|
||||||
|
def repl(m):
|
||||||
|
name, bits = m.groups()
|
||||||
|
return f"('{name}', ctypes.c_uint32, {bits})" if int(bits) > 8 else m.group(0)
|
||||||
|
|
||||||
|
data = re.sub(
|
||||||
|
r"\('([^']+)',\s*ctypes\.c_bool,\s*(\d+)\)",
|
||||||
|
repl,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
|
||||||
# Remove ctypes. prefix from invalid entries
|
# Remove ctypes. prefix from invalid entries
|
||||||
invalid_ctypes = ["bpf_iter_state", "_cache_type", "fs_context_purpose"]
|
invalid_ctypes = ["bpf_iter_state", "_cache_type", "fs_context_purpose"]
|
||||||
for name in invalid_ctypes:
|
for name in invalid_ctypes:
|
||||||
|
|||||||
Reference in New Issue
Block a user