Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
80679473
Commit
80679473
authored
Apr 05, 2017
by
4ast
Committed by
GitHub
Apr 05, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1097 from vavrusa/master
Updates to Lua/BPF code generator
parents
f762df56
67bb1502
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
158 additions
and
67 deletions
+158
-67
src/lua/README.md
src/lua/README.md
+1
-0
src/lua/bpf/bpf.lua
src/lua/bpf/bpf.lua
+106
-61
src/lua/bpf/builtins.lua
src/lua/bpf/builtins.lua
+33
-6
src/lua/bpf/cdef.lua
src/lua/bpf/cdef.lua
+3
-0
src/lua/bpf/proto.lua
src/lua/bpf/proto.lua
+15
-0
No files found.
src/lua/README.md
View file @
80679473
...
...
@@ -137,6 +137,7 @@ Below is a list of BPF-specific helpers:
*
`comm(var)`
- write current process name (uses
`bpf_get_current_comm`
)
*
`perf_submit(map, var)`
- submit variable to perf event array BPF map
*
`stack_id(map, flags)`
- return stack trace identifier from stack trace BPF map
*
`load_bytes(off, var)`
- helper for direct packet access with
`skb_load_bytes()`
### Current state
...
...
src/lua/bpf/bpf.lua
View file @
80679473
This diff is collapsed.
Click to expand it.
src/lua/bpf/builtins.lua
View file @
80679473
...
...
@@ -80,7 +80,7 @@ if ffi.abi('be') then
builtins
[
hton
]
=
function
(
a
,
b
,
w
)
return
end
end
-- Other built-ins
local
function
xadd
(
a
,
b
)
error
(
'NYI'
)
end
local
function
xadd
()
error
(
'NYI'
)
end
builtins
.
xadd
=
xadd
builtins
[
xadd
]
=
function
(
e
,
dst
,
a
,
b
,
off
)
assert
(
e
.
V
[
a
].
const
.
__dissector
,
'xadd(a, b) called on non-pointer'
)
...
...
@@ -120,7 +120,7 @@ builtins[probe_read] = function (e, ret, dst, src, vtype, ofs)
e
.
reg_alloc
(
e
.
tmpvar
,
3
)
-- Copy from original register
e
.
emit
(
BPF
.
ALU64
+
BPF
.
MOV
+
BPF
.
X
,
3
,
e
.
V
[
src
].
reg
,
0
,
0
)
else
local
src_reg
=
e
.
vreg
(
src
,
3
)
e
.
vreg
(
src
,
3
)
e
.
reg_spill
(
src
)
-- Spill to avoid overwriting
end
if
ofs
and
ofs
>
0
then
...
...
@@ -133,6 +133,7 @@ builtins[probe_read] = function (e, ret, dst, src, vtype, ofs)
e
.
emit
(
BPF
.
JMP
+
BPF
.
CALL
,
0
,
0
,
0
,
HELPER
.
probe_read
)
e
.
V
[
e
.
tmpvar
].
reg
=
nil
-- Free temporary registers
end
builtins
[
ffi
.
cast
]
=
function
(
e
,
dst
,
ct
,
x
)
assert
(
e
.
V
[
ct
].
const
,
'ffi.cast(ctype, x) called with bad ctype'
)
e
.
vcopy
(
dst
,
x
)
...
...
@@ -151,6 +152,7 @@ builtins[ffi.cast] = function (e, dst, ct, x)
e
.
V
[
dst
].
source
=
'probe'
end
end
builtins
[
ffi
.
new
]
=
function
(
e
,
dst
,
ct
,
x
)
if
type
(
ct
)
==
'number'
then
ct
=
ffi
.
typeof
(
e
.
V
[
ct
].
const
)
-- Get ctype from variable
...
...
@@ -160,7 +162,8 @@ builtins[ffi.new] = function (e, dst, ct, x)
e
.
vset
(
dst
,
nil
,
ct
)
e
.
V
[
dst
].
const
=
{
__base
=
e
.
valloc
(
ffi
.
sizeof
(
ct
),
true
),
__dissector
=
ct
}
end
builtins
[
ffi
.
copy
]
=
function
(
e
,
ret
,
dst
,
src
)
builtins
[
ffi
.
copy
]
=
function
(
e
,
ret
,
dst
,
src
)
assert
(
cdef
.
isptr
(
e
.
V
[
dst
].
type
),
'ffi.copy(dst, src) - dst MUST be a pointer type'
)
assert
(
cdef
.
isptr
(
e
.
V
[
src
].
type
),
'ffi.copy(dst, src) - src MUST be a pointer type'
)
-- Specific types also encode source of the data
...
...
@@ -186,7 +189,7 @@ builtins[ffi.copy] = function (e,ret, dst, src)
e.reg_alloc(e.tmpvar, 3) -- Copy from original register
e.emit(BPF.ALU64 + BPF.MOV + BPF.X, 3, e.V[src].reg, 0, 0)
else
local src_reg =
e.vreg(src, 3)
e.vreg(src, 3)
e.reg_spill(src) -- Spill to avoid overwriting
end
-- Call probe read helper
...
...
@@ -265,6 +268,28 @@ local function perf_submit(e, dst, map_var, src)
e.V[e.tmpvar].reg = nil -- Free temporary registers
end
-- Implements bpf_skb_load_bytes(ctx, off, var, vlen) on skb->data
local function load_bytes(e, dst, off, var)
print(e.V[off].const, e.V[var].const)
-- Set R2 = offset
e.vset(e.tmpvar, nil, off)
e.vreg(e.tmpvar, 2, false, ffi.typeof('
uint64_t
'))
-- Set R1 = ctx
e.reg_alloc(e.tmpvar, 1) -- Spill anything in R1 (unnamed tmp variable)
e.emit(BPF.ALU64 + BPF.MOV + BPF.X, 1, 6, 0, 0) -- CTX is always in R6, copy
-- Set R3 = pointer to var on stack
assert(e.V[var].const.__base, '
NYI
:
load_bytes
(
off
,
var
,
len
)
-
variable
is
not
on
stack
')
e.emit(BPF.ALU64 + BPF.MOV + BPF.X, 3, 10, 0, 0)
e.emit(BPF.ALU64 + BPF.ADD + BPF.K, 3, 0, 0, -e.V[var].const.__base)
-- Set R4 = var length
e.emit(BPF.ALU64 + BPF.MOV + BPF.K, 4, 0, 0, ffi.sizeof(e.V[var].type))
-- Set R0 = ret and call
e.vset(dst)
e.vreg(dst, 0, true, ffi.typeof('
int32_t
')) -- Return is integer
e.emit(BPF.JMP + BPF.CALL, 0, 0, 0, HELPER.skb_load_bytes)
e.V[e.tmpvar].reg = nil -- Free temporary registers
end
-- Implements bpf_get_stack_id()
local function stack_id(e, ret, map_var, key)
-- Set R2 = map fd (indirect load)
...
...
@@ -313,7 +338,7 @@ builtins[comm] = function (e, ret, dst)
end
-- Math library built-ins
math.log2 = function (
x
) error('
NYI
') end
math.log2 = function () error('
NYI
') end
builtins[math.log2] = function (e, dst, x)
-- Classic integer bits subdivison algorithm to find the position
-- of the highest bit set, adapted for BPF bytecode-friendly operations.
...
...
@@ -363,7 +388,7 @@ end
-- Call-type helpers
local
function
call_helper
(
e
,
dst
,
h
)
e
.
vset
(
dst
)
local
dst_reg
=
e
.
vreg
(
dst
,
0
,
true
)
e
.
vreg
(
dst
,
0
,
true
)
e
.
emit
(
BPF
.
JMP
+
BPF
.
CALL
,
0
,
0
,
0
,
h
)
e
.
V
[
dst
].
const
=
nil
-- Target is not a function anymore
end
...
...
@@ -381,6 +406,7 @@ builtins.uid_gid = uid_gid
builtins
.
comm
=
comm
builtins
.
perf_submit
=
perf_submit
builtins
.
stack_id
=
stack_id
builtins
.
load_bytes
=
load_bytes
builtins
[
cpu
]
=
function
(
e
,
dst
)
return
call_helper
(
e
,
dst
,
HELPER
.
get_smp_processor_id
)
end
builtins
[
rand
]
=
function
(
e
,
dst
)
return
call_helper
(
e
,
dst
,
HELPER
.
get_prandom_u32
)
end
builtins
[
time
]
=
function
(
e
,
dst
)
return
call_helper
(
e
,
dst
,
HELPER
.
ktime_get_ns
)
end
...
...
@@ -388,5 +414,6 @@ builtins[pid_tgid] = function (e, dst) return call_helper(e, dst, HELPER.get_cur
builtins
[
uid_gid
]
=
function
(
e
,
dst
)
return
call_helper
(
e
,
dst
,
HELPER
.
get_current_uid_gid
)
end
builtins
[
perf_submit
]
=
function
(
e
,
dst
,
map
,
value
)
return
perf_submit
(
e
,
dst
,
map
,
value
)
end
builtins
[
stack_id
]
=
function
(
e
,
dst
,
map
,
key
)
return
stack_id
(
e
,
dst
,
map
,
key
)
end
builtins
[
load_bytes
]
=
function
(
e
,
dst
,
off
,
var
,
len
)
return
load_bytes
(
e
,
dst
,
off
,
var
,
len
)
end
return
builtins
src/lua/bpf/cdef.lua
View file @
80679473
...
...
@@ -78,6 +78,9 @@ struct bpf {
static const int F_USER_STACK = 1 << 8;
static const int F_FAST_STACK_CMP = 1 << 9;
static const int F_REUSE_STACKID = 1 << 10;
/* special offsets for ancillary data */
static const int NET_OFF = -0x100000;
static const int LL_OFF = -0x200000;
};
/* eBPF commands */
struct bpf_cmd {
...
...
src/lua/bpf/proto.lua
View file @
80679473
...
...
@@ -35,6 +35,10 @@ struct sk_buff {
uint32_t tc_classid;
};
struct net_off_t {
uint8_t ver:4;
} __attribute__((packed));
struct eth_t {
uint8_t dst[6];
uint8_t src[6];
...
...
@@ -275,12 +279,23 @@ M.udp = function (...) return dissector(ffi.typeof('struct udp_t'), ...) end
M
.
tcp
=
function
(
...
)
return
dissector
(
ffi
.
typeof
(
'struct tcp_t'
),
...
)
end
M
.
vxlan
=
function
(
...
)
return
dissector
(
ffi
.
typeof
(
'struct vxlan_t'
),
...
)
end
M
.
data
=
function
(
...
)
return
dissector
(
ffi
.
typeof
(
'uint8_t'
),
...
)
end
M
.
net_off
=
function
(
...
)
return
dissector
(
ffi
.
typeof
(
'struct net_off_t'
),
...
)
end
-- Metatables
ffi
.
metatype
(
ffi
.
typeof
(
'struct eth_t'
),
{
__index
=
{
ip
=
skip_eth
,
ip6
=
skip_eth
,
net_off
=
function
(
e
,
dst
)
next_skip
(
e
,
dst
,
BPF
.
NET_OFF
)
end
,
}
})
ffi
.
metatype
(
ffi
.
typeof
(
'struct net_off_t'
),
{
__index
=
{
ip
=
function
()
end
,
ip6
=
function
()
end
,
}
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment