netfilterModule
Lua interface to the Linux Netfilter framework.
A script that registers hooks runs in a softirq runtime,lunatik run -c softirq <script>; see
execution contexts. Hooks are
registered in the initial network namespace only: packets of another namespace do not reach
them.
Usage
-- lunatik run -c softirq <script>: drops the locally generated IPv4 packets marked 0x10,
-- as `sudo ping -m 16 127.0.0.1` sends them
local netfilter = require("netfilter")
local nf = require("linux.nf")
local MARK <const> = 0x10
local function drop(skb)
return nf.action.DROP
end
netfilter.register{
hook = drop,
pf = nf.proto.IPV4,
hooknum = nf.inet.LOCAL_OUT,
priority = nf.ip.pri.FILTER,
mark = MARK,
}
Class netfilter_hook
| netfilter_hook:stop () | Stops the hook’s callback. |
netfilter
| register (opts) | Registers a Netfilter hook. |
Class netfilter_hook in detail
A registered Netfilter hook.
Returned by netfilter.register.
- netfilter_hook:stop ()
-
Stops the hook’s callback.
A packet the hook sees afterwards takes the
ACCEPTpolicy without reaching Lua. The hook stays registered until the runtime closes, since unregistering it sleeps and a stop may come from a callback; in a percpu script this stops the callback of this runtime alone. Calling it again does nothing, and a to-be-closed variable holding the hook stops it the same way.Returns
-
nil
Usage
hook:stop()
netfilter in detail
- register (opts)
-
Registers a Netfilter hook.
In a percpu script the runtimes share one hook: the first registration installs it, the
others attach their callbacks, and a packet reaches the runtime of the CPU it arrived on.
Parameters
- opts
table
Hook options:
hook(function),pf,hooknum,priority(integers), and optionallymark(integer), a prefilter that keeps a packet out of Lua: given amark, 0 included, only a packet whoseskb:mark()equals it reaches the callback, and the hook accepts every other packet; without amark, the callback runs for every packet.pftakes a linux.nf.proto value,hooknuma hook of that family, as linux.nf.inet, linux.nf.arp or linux.nf.br list them, andpriorityalinux.nf.ip.priorlinux.nf.br.privalue.hook(skb)returns the packet’s verdict,DROP,ACCEPTorQUEUEof linux.nf.action, and optionally a mark to set on the packet. A callback that returns no verdict, or that raises, accepts the packet; one that returns any other value,STOLEN,REPEATandSTOPincluded, accepts it too and logsinvalid verdict. A mark that is not an integer from 0 to 232 - 1 leaves the packet’s mark as it was and logsinvalid mark.
Returns
-
netfilter_hook
the hook, which netfilter.register keeps for its runtime: dropping it
stops nothing, and the callback runs until stop or the end of the runtime. The hook stays
registered until the runtime closes, and the one hook a percpu script’s runtimes share until
the percpu set stops.
Raises
“not allowed once the runtime is armed” past the script body;runtime context mismatchoutside a softirq runtime;not allowed while the runtime closesfrom a finalizer that runs at its close;bad field 'hook' (function expected, got <type>)ifhookis missing or not a function;bad field '<field>' (number expected, got <type>)ifpf,hooknumorpriorityis missing or not a number, or ifmarkis present and not a number;bad field '<field>' (out of bounds)ifpfis not a family whose hooks netfilter keeps in a table,hooknumis not a hook of that table,markis negative or past 32 bits, orpriorityis past anint; if the hook cannot be registered; in a percpu script, if this runtime already registered the samepf,hooknum,priorityandmark, or the same three both times without amarkUsage
local netfilter = require("netfilter") local nf = require("linux.nf") local QUARANTINED <const> = 2 -- ifindex local function quarantine(skb) return skb:ifindex() == QUARANTINED and nf.action.DROP or nf.action.ACCEPT end netfilter.register{ hook = quarantine, pf = nf.proto.INET, hooknum = nf.inet.PRE_ROUTING, priority = nf.ip.pri.FILTER, }
- opts
table
Hook options: