bfcli
¶
bfcli
is a command line tool to communicate with the bpfilter daemon. It provides supports for extended features compared to the iptables client.
Commands¶
bfcli
commands are structured as bfcli OBJECT ACTION
. The commands and actions supported by bfcli
are described below.
ruleset set
¶
Define a new ruleset: replace all the existing chains with the ruleset provided. Replacement is not atomic.
- Options
--str RULESET
: read and apply the ruleset defining from the command line.--file FILE
: readFILE
and apply the ruleset contained in it.
--str
and --file
are mutually exclusive.
Example
bfcli ruleset set --file myruleset.txt
bfcli ruleset set --str "chain my_xdp_chain BF_HOOK_XDP ACCEPT rule ip4.saddr in {192.168.1.1} ACCEPT"
ruleset get
¶
Print the ruleset: request all the chains and rules from the daemon with counters values.
Example
$ sudo bfcli ruleset get
chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT
counters policy 87 packets 9085 bytes; error 0 packets 0 bytes
rule
ip4.saddr eq 0xc0 0xa8 0x01 0x01 0xff 0xff 0xff 0xff
counters 2 packets 196 bytes
ACCEPT
ruleset flush
¶
Remove all the chains and rules defined by the daemon. Once this command completes, the daemon doesn’t contain any filtering rules, as if it was freshly started.
Examples
$ sudo bfcli ruleset get
chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT
counters policy 87 packets 9085 bytes; error 0 packets 0 bytes
rule
ip4.saddr eq 0xc0 0xa8 0x01 0x01 0xff 0xff 0xff 0xff
counters 2 packets 196 bytes
ACCEPT
$ sudo bfcli ruleset flush
$ sudo bfcli ruleset get
$ # Empty ruleset
chain set
¶
Generate and load a chain into the kernel. If the chain definition contains hook options, the daemon will attach it to its hook. Any existing chain with the same name (attached or not) will be discarded and replaced with the new one.
If you want to update an existing chain without downtime, use bfcli chain update
instead.
- Options
--from-str CHAIN
: read the chain to set from the command line arguments.--from-file FILEPATH
: read the chain from a file.--name NAME
: if--from-str
or--from-file
provide multiple chains,NAME
specify which one to send to the daemon.
Examples
$ # Create an empty XDP chain, do not attach it
$ sudo bfcli chain set --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT"
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP ACCEPT
counters policy 0 packets 0 bytes; error 0 packets 0 bytes
# Create an empty TC chain and attach it
$ sudo bfcli chain set --from-str "chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT"
$ sudo bfcli chain get --name my_tc_chain
chain my_tc_chain BF_HOOK_TC_INGRESS{ifindex=2} ACCEPT
counters policy 35 packets 4091 bytes; error 0 packets 0 bytes
chain get
¶
Print a chain.
- Options
--name NAME
: name of the chain to print.
Examples
$ # Create a Netfilter chain and print it
$ sudo bfcli chain set --from-str "chain my_input_chain BF_HOOK_NF_LOCAL_IN{family=inet4,priorities=101-102} ACCEPT"
$ sudo bfcli chain get --name my_input_chain
chain my_input_chain BF_HOOK_NF_LOCAL_IN{family=inet4,priorities=101-102} ACCEPT
counters policy 1161 packets 149423 bytes; error 0 packets 0 bytes
chain load
¶
Generate and load a chain into the kernel. Hook options are ignored.
If a chain with the same name already exist, it won’t be replaced. See bfcli chain set
or bfcli chain update
to replace an existing chain.
- Options
--from-str CHAIN
: read the chain to set from the command line arguments.--from-file FILEPATH
: read the chain from a file.--name NAME
: if--from-str
or--from-file
provide multiple chains,NAME
specify which one to send to the daemon.
Examples
$ # Create an XDP chain and print it
$ sudo bfcli chain load --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT"
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP ACCEPT
counters policy 0 packets 0 bytes; error 0 packets 0 bytes
$ # Create a single chain from a string containing 2 chains. Hook options are ignored.
$ sudo bfcli chain load --name my_other_xdp_chain --from-str "
chain my_next_xdp_chain BF_HOOK_XDP DROP
chain my_other_xdp_chain BF_HOOK_XDP ACCEPT"
$ sudo bfcli chain get --name my_other_xdp_chain
chain my_other_xdp_chain BF_HOOK_XDP ACCEPT
counters policy 0 packets 0 bytes; error 0 packets 0 bytes
chain attach
¶
Attach a loaded chain to its hook.
Only loaded chains (not attached) can be attached. See bfcli chain set
and bfcli chain update
if you want to update an existing chain.
See below for a list of available hook options.
- Options
--name NAME
: name of the chain to attach.--option OPTION
: hook-specific options to attach the chain to its hook. See hook options below.
Examples
$ # Load and attach an XDP chain, print it
$ sudo bfcli chain load --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT"
$ sudo bfcli chain attach --name my_xdp_chain --option ifindex=2
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP{ifindex=2} ACCEPT
counters policy 101 packets 11714 bytes; error 0 packets 0 bytes
chain update
¶
Update an existing chain. The new chain will atomically update the existing one. Hook options are ignored. The new chain will replace the existing chain with the same name.
If you want to modify the hook options, use bfcli chain set
instead.
- Options
--from-str CHAIN
: read the chain to set from the command line arguments.--from-file FILEPATH
: read the chain from a file.--name NAME
: if--from-str
or--from-file
provide multiple chains,NAME
specify which one to send to the daemon.
Examples
$ # Set an XDP chain and update it
$ sudo bfcli chain set --from-str "chain my_xdp_chain BF_HOOK_XDP{ifindex=2} ACCEPT"
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP{ifindex=2} ACCEPT
counters policy 307 packets 36544 bytes; error 0 packets 0 bytes
$ sudo bfcli chain update --from-str "
chain my_xdp_chain BF_HOOK_XDP{ifindex=2} ACCEPT
rule
ip4.proto eq icmp
counter
DROP"
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP{ifindex=2} ACCEPT
counters policy 204 packets 24074 bytes; error 0 packets 0 bytes
rule
ip4.proto eq 0x01
counters 0 packets 0 bytes
DROP
chain flush
¶
Detach, unload, and discard an existing chain.
- Options
--name NAME
: name of the chain to flush.
Examples
$ # Set an XDP chain and update it
$ sudo bfcli chain set --from-str "chain my_xdp_chain BF_HOOK_XDP ACCEPT"
$ sudo bfcli chain get --name my_xdp_chain
chain my_xdp_chain BF_HOOK_XDP ACCEPT
counters policy 0 packets 0 bytes; error 0 packets 0 bytes
$ sudo bfcli chain flush --name my_xdp_chain
$ sudo bfcli chain get --name my_xdp_chain
$ # No output, chain doesn't exist
Filters definition¶
The following sections will use the dollar sign ($
) to prefix values that should be replaced by the user, and brackets ([]
) for optional values (whether it’s a literal or a user-provided value).
Example of a ruleset:
chain $NAME $HOOK $HOOK_OPTIONS $POLICY
rule
$MATCHER
$VERDICT
[...]
[...]
- A ruleset is composed of chain(s), rule(s), and matcher(s):
A chain is a set of rule(s) to match the packet against. It will use the rules to filter packets at a specific location in the kernel: a
$HOOK
. There can be only one chain defined for a given kernel hook. Chains also have a$POLICY
which specify the action to take with the packet if none of the rules matches.A rule defines an action to take on a packet if it matches all its specified criteria. A rule will then apply a defined action to the packet if it’s matched.
A matcher is a matching criterion within a rule. It can match a specific protocol, a specific field, a network interface… The number of matchers supported by
bpfilter
andbfcli
is constantly growing.
Note
Lines starting with #
are comments and bfcli
will ignore them.
Chains¶
Chains are defined such as:
chain $NAME $HOOK{$OPTIONS} $POLICY
- With:
$NAME
: user-defined name for the chain.$HOOK
: hook in the kernel to attach the chain to:BF_HOOK_XDP
: XDP hook.BF_HOOK_TC_INGRESS
: ingress TC hook.BF_HOOK_NF_PRE_ROUTING
: similar tonftables
andiptables
prerouting hook.BF_HOOK_NF_LOCAL_IN
: similar tonftables
andiptables
input hook.BF_HOOK_CGROUP_INGRESS
: ingress cgroup hook.BF_HOOK_CGROUP_EGRESS
: egress cgroup hook.BF_HOOK_NF_FORWARD
: similar tonftables
andiptables
forward hook.BF_HOOK_NF_LOCAL_OUT
: similar tonftables
andiptables
output hook.BF_HOOK_NF_POST_ROUTING
: similar tonftables
andiptables
postrouting hook.BF_HOOK_TC_EGRESS
: egress TC hook.
$POLICY
: action taken if no rule matches the packet, eitherACCEPT
forward the packet to the kernel, orDROP
to discard it. Note whileCONTINUE
is a valid verdict for rules, it is not supported for chain policy.
$OPTIONS
are hook-specific comma separated key value pairs:
Option |
Required by |
Supported by |
Notes |
---|---|---|---|
|
|
N/A |
Interface index to attach the program to. |
|
|
N/A |
Path to the cgroup to attach to. |
|
|
N/A |
Netfilter hook version to attach the chain to: |
|
|
N/A |
|
Rules¶
Rules are defined such as:
rule
[$MATCHER...]
[counter]
$VERDICT
- With:
$MATCHER
: zero or more matchers. Matchers are defined later.counter
: optional literal. If set, the filter will counter the number of packets and bytes matched by the rule.$VERDICT
: action taken by the rule if the packet is matched against all the criteria: eitherACCEPT
,DROP
orCONTINUE
. -ACCEPT
: forward the packet to the kernel -DROP
: discard the packet. -CONTINUE
: continue processing subsequent rules.
In a chain, as soon as a rule matches a packet, its verdict is applied. If the verdict is ACCEPT
or DROP
, the subsequent rules are not processed. Hence, the rules’ order matters. If no rule matches the packet, the chain’s policy is applied.
Note CONTINUE
means a packet can be counted more than once if multiple rules specify CONTINUE
and counter
.
Matchers¶
Matchers are defined such as:
$TYPE [$OP] $PAYLOAD
- With:
$TYPE
: type of the matcher, defined which part of the processed network packet need to be compared against. All the exact matcher types are defined below.$OP
: comparison operation, not all$TYPE
of matchers support all the existing comparison operators:eq
: exact equality.not
: inequality.any
: match the packet against a set of data defined as the payload. If any of the member of the payload set is found in the packet, the matcher is positive. For example, if you want to match all theicmp
andudp
packets:ip4.proto any icmp,udp
.all
: match the packet against a set of data defined as the payload. If all the member of the payload set are found in the packet, the matcher is positive, even if the packet contains more than only the members defined in the payload. For example, to match all the packets containing at least theACK
TCP flag:tcp.flags all ACK
.in
: matches the packet against a hashed set of reference values. Using thein
operator is useful when the packet’s data needs to be compared against a large set of different values. Let’s say you want to filter 1000 different IPv4 addresses, you can either define 1000ip4.saddr eq $IP
matcher, in which casebpfilter
will compare the packet against every IP one after the other. Or you can useip4.saddr in {$IP0,IP1,...}
in which casebpfilter
will compare the packet’s data against the hashed set as a whole in 1 operation.range
: matches in a range of values. Formatted as$START-$END
. Both$START
and$END
are included in the range.
$PAYLOAD
: payload to compare to the processed network packet. The exact payload format depends on$TYPE
.
Meta matchers
Matches |
Type |
Operator |
Payload |
Notes |
---|---|---|---|---|
Interface index |
|
|
|
For chains attached to an ingress hook, |
L3 protocol |
|
|
|
|
L4 protocol |
|
|
|
|
Source port |
|
|
|
|
|
||||
|
|
|
||
Destination port |
|
|
|
|
|
||||
|
|
|
IPv4 matchers
Matches |
Type |
Operator |
Payload |
Notes |
---|---|---|---|---|
Source address |
|
|
|
|
|
||||
|
|
Only support |
||
Destination address |
|
|
|
|
|
||||
|
|
Only support |
||
Protocol |
|
|
|
Only |
IPv6 matchers
Matches |
Type |
Operator |
Payload |
Notes |
---|---|---|---|---|
Source address |
|
|
|
|
|
||||
Destination address |
|
|
||
|
TCP matchers
Matches |
Type |
Operator |
Payload |
Notes |
---|---|---|---|---|
Source port |
|
|
|
|
|
||||
|
|
|
||
Destination port |
|
|
|
|
|
||||
|
|
|
||
Flags |
|
|
|
|
|
||||
|
||||
|
UDP matchers
Matches |
Type |
Operator |
Payload |
Notes |
---|---|---|---|---|
Source port |
|
|
|
|
|
||||
|
|
|
||
Destination port |
|
|
|
|
|
||||
|
|
|