Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document pflua API #28

Open
wingo opened this issue Aug 8, 2014 · 2 comments
Open

Document pflua API #28

wingo opened this issue Aug 8, 2014 · 2 comments

Comments

@wingo
Copy link
Contributor

wingo commented Aug 8, 2014

The pflua API needs documentation.

@kbara
Copy link
Contributor

kbara commented Jun 11, 2015

Any preferred format/location for the documentation? @andywingo

@kbara
Copy link
Contributor

kbara commented Jun 22, 2015

Here's an initial draft. It uses the convert_ssa/convert_anf APIs with the extra optimize flag, although those are still in a PR.


The pflua API

Pflua compiles pflang (libpcap filter expressions), and matches packets accordingly.

Compilation is done with pf.compile_filter.
For examples of the API in use, see https://github.com/Igalia/pflua/tree/master/tools

Compilation: external API
pf.compile_filter(filter_str, opts)
filter_str is a pflang expression, such as "ip" or "tcp port 80 or udp".
opts is a lua table. It can specify none or any combination of:
 - optimize: a boolean. Enables or disables optimization; true by default
 - source: emit human-readable output rather than a normal Lua function
 - dlt: 'EN10MB' by default.
 - libpcap or bpf: select the compilation pipeline. If both are false, use
    the native pflua pipeline. If libpcap is true, use libpcap. If BPF is true,
    compile traditional BPF bytecode to Lua.

 If 'opts.source' is not true, the result is a lua predicate. See 'matching packets'.

Matching packets:
Get a predicate/matching function from pf.compile_filter. Then:
your_lua_predicate(packet, packet_len)
This will return true if the filter matches the packet, and false otherwise.

Getting packets:
The mechanism for getting packets can vary. The simplest way with a pcap file
and standalone pflua is to use savefile.load_packets(pcap_filename).

To use pflua within Snabb, from packet captures or interfaces, read the Snabb
documentation and see main.lua files under apps/ in the source tree for
configuration examples.

-----------------------------------------
Pflua internals: these may change without warning.

Pflua has two main compilation pipelines which emit Lua code. One takes bpf
bytecode as input; the other takes pflang. Additionally, a third pipeline is a
thin wrapper around libpcap.

Libpcap pipeline:
   Compile to BPF: libpcap.compile(filter_string, dlt, optimize)
     Example: libpcap.compile("tcp", "EN10MB", true)
   BPF to Lua source code: bpf.disassemble(bytecode)
   Compile pflang to a lua predicate: libpcap.offline_filter(bpf, header, pkt)
       - See libpcap.lua for details about the arguments.

BPF pipeline:
   Get bytecode: libpcap.compile(filter_string, dlt, optimize)
     Example: libpcap.compile("tcp", "EN10MB", true)
   Compile bytecode to Lua source: bpf.compile_lua(bytecode)
   Compile bytecode to a Lua predicate: bpf.compile(bytecode)

Pure-lua pipeline: this is the default, and most interesting.
   Parse a pflang expression: parse.parse(filter_str); returns an AST
   Expand the parse: expand.expand(ast, dlt); returns an (unnamed) IR
   Optimize the expanded parse: optimize.optimize(ir); returns the same type
      of IR, but optimized.
   Convert the unnamed IR to ANF: anf.convert_anf(ir, optimize)
   Convert ANF to SSA: ssa.convert_ssa(anf, optimize)
   Convert SSA to lua source: backend.emit_lua(ssa)
   Convert SSA to a Lua predicate: backend.emit_and_load(ssa, filter_str)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants