@@ -141,6 +141,7 @@ pin type struct enum if else
141141while loop break continue return import
142142pub priv impl true false null
143143try catch throw defer delete match
144+ extern
144145```
145146
146147** Note** : The ` pin ` keyword is used for both maps and global variables to enable filesystem persistence.
@@ -1240,11 +1241,113 @@ fn advanced_security_monitor(ctx: LsmContext) -> i32 {
12401241}
12411242```
12421243
1243- ### 3.7 Helper Functions (@helper )
1244+ ### 3.7 External Kernel Functions (extern)
1245+
1246+ KernelScript supports importing existing kernel functions using the ` extern ` keyword. These are kernel functions that already exist in the running kernel (discovered via BTF) and can be called directly from eBPF programs without requiring custom kernel modules.
1247+
1248+ #### 3.7.1 extern Declaration and Usage
1249+
1250+ External kernel functions are declared using the ` extern ` keyword and provide type-safe access to kernel-provided kfuncs:
1251+
1252+ ``` kernelscript
1253+ // Import existing kernel functions via extern declarations
1254+ extern bpf_ktime_get_ns() -> u64
1255+ extern bpf_trace_printk(fmt: *u8, fmt_size: u32) -> i32
1256+ extern bpf_get_current_pid_tgid() -> u64
1257+ extern bpf_get_current_comm(buf: *u8, buf_size: u32) -> i32
1258+
1259+ // eBPF programs can call extern functions directly
1260+ @xdp
1261+ fn packet_tracer(ctx: *xdp_md) -> xdp_action {
1262+ // Get current timestamp using extern kfunc
1263+ var timestamp = bpf_ktime_get_ns()
1264+
1265+ // Get current process ID using extern kfunc
1266+ var pid_tgid = bpf_get_current_pid_tgid()
1267+ var pid = (pid_tgid >> 32) as u32
1268+
1269+ // Get process name
1270+ var comm: u8[16]
1271+ bpf_get_current_comm(&comm[0], 16)
1272+
1273+ // Print debug information
1274+ bpf_trace_printk(&"packet from pid %d\n"[0], 18)
1275+
1276+ return XDP_PASS
1277+ }
1278+ ```
1279+
1280+ #### 3.7.2 extern vs @kfunc Comparison
1281+
1282+ | Aspect | ` extern ` | ` @kfunc ` |
1283+ | --------| ----------| ----------|
1284+ | ** Definition** | Declaration of existing kernel function | User-defined kernel function |
1285+ | ** Implementation** | Already exists in kernel | Implemented in generated kernel module |
1286+ | ** BTF Registration** | Already registered | Registered by compiler |
1287+ | ** Compilation** | Declaration only | Full implementation + module |
1288+ | ** Usage** | Import existing kernel APIs | Create custom kernel functionality |
1289+ | ** Performance** | Direct kernel function call | BTF-mediated call to module |
1290+
1291+ #### 3.7.3 extern Declaration Rules
1292+
1293+ - ** Declaration only** : ` extern ` functions must not have function bodies
1294+ - ** Type safety** : Parameter and return types must match kernel BTF signatures
1295+ - ** eBPF only** : ` extern ` functions can only be called from eBPF programs, not userspace
1296+ - ** Kernel availability** : Functions must exist in the target kernel version
1297+
1298+ ``` kernelscript
1299+ // ✅ Valid extern declaration
1300+ extern bpf_ktime_get_ns() -> u64
1301+
1302+ // ❌ Invalid - extern cannot have function body
1303+ extern invalid_function() -> u32 {
1304+ return 42 // Error: extern functions cannot have bodies
1305+ }
1306+
1307+ // ❌ Invalid - extern functions cannot be called from userspace
1308+ fn userspace_function() -> u64 {
1309+ return bpf_ktime_get_ns() // Error: extern kfuncs only callable from eBPF
1310+ }
1311+ ```
1312+
1313+ #### 3.7.4 BTF Integration and Discovery
1314+
1315+ The compiler can automatically discover available kernel functions from BTF:
1316+
1317+ ``` bash
1318+ # Automatic extern generation from kernel BTF
1319+ kernelscript init --kfuncs xdp my_xdp
1320+
1321+ # Generated extern_kfuncs.ks would contain:
1322+ # extern bpf_ktime_get_ns() -> u64
1323+ # extern bpf_trace_printk(fmt: *u8, fmt_size: u32) -> i32
1324+ # extern bpf_get_current_pid_tgid() -> u64
1325+ # ... (all available kernel kfuncs)
1326+ ```
1327+
1328+ #### 3.7.5 Common extern kfunc Examples
1329+
1330+ ``` kernelscript
1331+ extern bpf_ktime_get_ns() -> u64
1332+ extern bpf_get_current_pid_tgid() -> u64
1333+ extern bpf_trace_printk(fmt: *u8, fmt_size: u32) -> i32
1334+
1335+ @tc("ingress")
1336+ fn network_monitor(ctx: *__sk_buff) -> i32 {
1337+ var timestamp = bpf_ktime_get_ns()
1338+ var pid_tgid = bpf_get_current_pid_tgid()
1339+
1340+ // Process monitoring logic here
1341+ bpf_trace_printk("Processing packet at %llu from PID %d\n", 40)
1342+ return 0 // TC_ACT_OK
1343+ }
1344+ ```
1345+
1346+ ### 3.8 Helper Functions (@helper )
12441347
12451348KernelScript supports kernel-shared helper functions using the ` @helper ` attribute. These functions compile to eBPF bytecode and are shared across all eBPF programs within the same compilation unit, providing a way to reuse common logic without duplicating code.
12461349
1247- #### 3.7 .1 @helper Declaration and Usage
1350+ #### 3.8 .1 @helper Declaration and Usage
12481351
12491352Helper functions are declared using the ` @helper ` attribute and can be called from any eBPF program:
12501353
@@ -1301,7 +1404,7 @@ fn traffic_shaper(ctx: *__sk_buff) -> int {
13011404}
13021405```
13031406
1304- #### 3.7 .2 @helper vs Other Function Types
1407+ #### 3.8 .2 @helper vs Other Function Types
13051408
13061409| Aspect | ` @helper ` | ` @kfunc ` | ` @xdp/@tc/etc ` | Regular ` fn ` |
13071410| --------| -----------| ----------| ----------------| --------------|
@@ -1311,7 +1414,7 @@ fn traffic_shaper(ctx: *__sk_buff) -> int {
13111414| ** Shared Across Programs** | Yes | Yes | No | No |
13121415| ** Memory Access** | eBPF-restricted | Unrestricted kernel | eBPF-restricted | Userspace-restricted |
13131416
1314- #### 3.7 .3 Code Organization Benefits
1417+ #### 3.8 .3 Code Organization Benefits
13151418
13161419Using ` @helper ` functions provides several benefits:
13171420
@@ -1351,11 +1454,11 @@ fn connection_tracker(ctx: *__sk_buff) -> int {
13511454}
13521455```
13531456
1354- ### 3.8 Private Kernel Module Functions (@private )
1457+ ### 3.9 Private Kernel Module Functions (@private )
13551458
13561459KernelScript supports private helper functions within kernel modules using the ` @private ` attribute. These functions execute in kernel space but are internal to the module - they cannot be called by eBPF programs and are not registered via BTF. They serve as utility functions for ` @kfunc ` implementations.
13571460
1358- #### 3.8 .1 @private Declaration and Usage
1461+ #### 3.9 .1 @private Declaration and Usage
13591462
13601463Private functions are declared using the ` @private ` attribute and can only be called by other functions within the same kernel module:
13611464
@@ -1446,7 +1549,7 @@ fn packet_filter(ctx: *xdp_md) -> xdp_action {
14461549}
14471550```
14481551
1449- #### 3.8 .2 Function Visibility and Call Hierarchy
1552+ #### 3.9 .2 Function Visibility and Call Hierarchy
14501553
14511554``` kernelscript
14521555// Example showing function call hierarchy
@@ -1486,7 +1589,7 @@ fn traffic_analyzer(ctx: *__sk_buff) -> int {
14861589}
14871590```
14881591
1489- #### 3.8 .3 @private vs @kfunc Comparison
1592+ #### 3.9 .3 @private vs @kfunc Comparison
14901593
14911594| Aspect | ` @private ` | ` @kfunc ` |
14921595| --------| -----------| ----------|
@@ -1497,7 +1600,7 @@ fn traffic_analyzer(ctx: *__sk_buff) -> int {
14971600| ** Use Case** | Internal implementation details | Public API functions |
14981601| ** Performance** | Direct function call | BTF-mediated call |
14991602
1500- #### 3.8 .4 Code Organization Benefits
1603+ #### 3.9 .4 Code Organization Benefits
15011604
15021605Using ` @private ` functions provides several architectural benefits:
15031606
@@ -1560,11 +1663,11 @@ fn optimized_packet_check(packet: *u8, len: u32) -> bool {
15601663}
15611664```
15621665
1563- ### 3.9 Struct_ops and Kernel Module Function Pointers
1666+ ### 3.10 Struct_ops and Kernel Module Function Pointers
15641667
15651668KernelScript supports eBPF struct_ops through clean impl block syntax that allows implementing kernel interfaces using eBPF programs.
15661669
1567- #### 3.9 .1 eBPF Struct_ops with Impl Blocks
1670+ #### 3.10 .1 eBPF Struct_ops with Impl Blocks
15681671
15691672eBPF struct_ops allow implementing kernel interfaces using eBPF programs. KernelScript uses impl blocks for a clean, intuitive syntax:
15701673
@@ -1629,7 +1732,7 @@ impl my_bbr_congestion_control {
16291732register(my_bbr_congestion_control)
16301733```
16311734
1632- #### 3.9 .2 Simplified Struct_ops Example
1735+ #### 3.10 .2 Simplified Struct_ops Example
16331736
16341737``` kernelscript
16351738// Minimal struct_ops implementation
@@ -1669,7 +1772,7 @@ fn main() -> i32 {
16691772}
16701773```
16711774
1672- #### 3.9 .3 Registration Function
1775+ #### 3.10 .3 Registration Function
16731776
16741777The ` register() ` function is type-aware and generates the appropriate registration code:
16751778
@@ -4530,7 +4633,8 @@ kernelscript_file = { global_declaration }
45304633
45314634global_declaration = config_declaration | map_declaration | type_declaration |
45324635 function_declaration | struct_declaration | impl_declaration |
4533- global_variable_declaration | bindings_declaration | import_declaration
4636+ global_variable_declaration | bindings_declaration | import_declaration |
4637+ extern_declaration
45344638
45354639(* Map declarations - global scope *)
45364640map_declaration = [ "pin" ] [ "@flags" "(" flag_expression ")" ] "var" identifier ":" map_type "<" key_type "," value_type ">" "(" map_config ")"
@@ -4717,10 +4821,16 @@ null_literal = "null"
47174821(* Import declarations - unified syntax for KernelScript and external languages *)
47184822import_declaration = "import" identifier "from" string_literal
47194823
4824+ (* External kernel function declarations - for importing existing kernel kfuncs *)
4825+ extern_declaration = "extern" identifier "(" parameter_list ")" [ "->" type_annotation ]
4826+
47204827(* Examples:
47214828 import utils from "./common/utils.ks" // KernelScript import
47224829 import ml_analysis from "./ml/threat.py" // Python import (userspace only)
47234830
4831+ extern bpf_ktime_get_ns() -> u64 // Import existing kernel kfunc
4832+ extern bpf_trace_printk(fmt: *u8, fmt_size: u32) -> i32 // Import with parameters
4833+
47244834 Import behavior is determined by file extension:
47254835 - .ks files: Import KernelScript symbols (functions, types, maps, configs)
47264836 - .py files: Import Python functions with automatic FFI bridging (userspace only)
0 commit comments