File: bfcli.rst

package info (click to toggle)
bpfilter 0.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,076 kB
  • sloc: ansic: 30,397; sh: 1,383; cpp: 959; python: 495; yacc: 385; lex: 194; makefile: 9
file content (689 lines) | stat: -rw-r--r-- 26,220 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
``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.

Chains with valid hook options defined are attached to their hook. Chains without hook options are only loaded into the kernel.

**Options**
  - ``--from-str RULESET``: read and apply the ruleset defining from the command line.
  - ``--from-file FILE``: read ``FILE`` and apply the ruleset contained in it.

``--from-str`` and ``--from-file`` are mutually exclusive.

**Example**

.. code:: shell

    bfcli ruleset set --from-file myruleset.txt
    bfcli ruleset set --from-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**

.. code:: shell

    $ 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**

.. code:: shell

    $ 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**

.. code:: shell

    $ # 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**

.. code:: shell

    $ # 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 logs``
~~~~~~~~~~~~~~

Print a chain's logged packets.

bfcli will print the logged headers as they are published by the chain. Only the headers requested in the ``log`` action will be printed. Hit ``Ctrl+C`` to quit.

For each logged packet, bfcli will print the receive timestamp and the packet size, followed by each requested layer (see the ``log`` action below). If one of the requested layer could not be processed by the chain, the corresponding output will be truncated.

**Options**
  - ``--name NAME``: name of the chain to print the logged packets for.

**Examples**

.. code:: shell

    $ # Create an XDP chain with logs and print the logs
    $ sudo bfcli chain set --from-str "
      chain my_input_chain BF_HOOK_XDP{ifindex=2} ACCEPT
          rule
              meta.l4_proto tcp
              log transport
              CONTINUE
      "
    $ sudo bfcli chain logs --name my_input_chain
      [15:14:32.652085] Packet: 66 bytes
        TCP       : 52719 → 22    [ack]
                    seq=1643155516 ack=1290470623 win=4618

      [15:14:32.652842] Packet: 66 bytes
        TCP       : 52719 → 22    [ack]
                    seq=1643155516 ack=1290470723 win=4619

      [...]

``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**

.. code:: shell

    $ # 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**

.. code:: shell

    $ # 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**

.. code:: shell

    $ # 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**

.. code:: shell

    $ # 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:

.. code-block:: shell

    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`` and ``bfcli`` is constantly growing.

.. note::

    Lines starting with ``#`` are comments and ``bfcli`` will ignore them.

Chains
~~~~~~

Chains are defined such as:

.. code:: shell

    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 to ``nftables`` and ``iptables`` prerouting hook.
    - ``BF_HOOK_NF_LOCAL_IN``: similar to ``nftables`` and ``iptables`` input hook.
    - ``BF_HOOK_CGROUP_INGRESS``: ingress cgroup hook.
    - ``BF_HOOK_CGROUP_EGRESS``: egress cgroup hook.
    - ``BF_HOOK_NF_FORWARD``: similar to ``nftables`` and ``iptables`` forward hook.
    - ``BF_HOOK_NF_LOCAL_OUT``: similar to ``nftables`` and ``iptables`` output hook.
    - ``BF_HOOK_NF_POST_ROUTING``: similar to ``nftables`` and ``iptables`` postrouting hook.
    - ``BF_HOOK_TC_EGRESS``: egress TC hook.
  - ``$POLICY``: action taken if no rule matches the packet, either ``ACCEPT`` forward the packet to the kernel, or ``DROP`` to discard it. Note while ``CONTINUE`` is a valid verdict for rules, it is not supported for chain policy.

``$OPTIONS`` are hook-specific comma separated key value pairs:

.. flat-table::
   :header-rows: 1
   :widths: 2 2 2 12
   :fill-cells:

   * - Option
     - Required by
     - Supported by
     - Notes
   * - ``ifindex=$IFINDEX``
     - ``BF_HOOK_XDP``, ``BF_HOOK_TC``
     - N/A
     - Interface index to attach the program to.
   * - ``cgpath=$CGROUP_PATH``
     - ``BF_HOOK_CGROUP_INGRESS``, ``BF_HOOK_CGROUP_EGRESS``
     - N/A
     - Path to the cgroup to attach to.
   * - ``family=$FAMILY``
     - ``BF_HOOK_NF_*``
     - N/A
     - Netfilter hook version to attach the chain to: ``inet4`` for IPv4 or ``inet6`` for IPv6. Rules that are incompatible with the hook version will be ignored.
   * - ``priorities=$INT1-$INT2``
     - ``BF_HOOK_NF_*``
     - N/A
     - ``INT1`` and ``INT2`` are different non-zero integers. Priority values to use when attaching the chain. Two values are required to ensure atomic update of the chain.


Rules
~~~~~

Rules are defined such as:

.. code:: shell

    rule
        [$MATCHER...]
        [log link,internet,transport]
        [counter]
        $VERDICT

With:
  - ``$MATCHER``: zero or more matchers. Matchers are defined later.
  - ``log``: optional. If set, log the requested protocol headers. ``link`` will log the link (layer 2) header, ``internet`` with log the internet (layer 3) header, and ``transport`` will log the transport (layer 4) header. At least one header type is required.
  - ``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: either ``ACCEPT``, ``DROP`` or ``CONTINUE``.
    - ``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:

.. code:: shell

    $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 the ``icmp`` and ``udp`` 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* the ``ACK`` TCP flag: ``tcp.flags all ACK``.
    - ``in``: matches the packet against a hashed set of reference values. Using the ``in`` 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 1000 ``ip4.saddr eq $IP`` matcher, in which case ``bpfilter`` will compare the packet against every IP one after the other. Or you can use ``ip4.saddr in {$IP0,IP1,...}`` in which case ``bpfilter`` 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
####

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - Interface
      - ``meta.iface``
      - ``eq``
      - ``$INTERFACE``
      - For chains attached to an ingress hook, ``$INTERFACE`` is the input interface, for chains attached to an egress hook, ``$INTERFACE`` is the output interface. ``$INTERFACE`` must be an interface name (e.g., "eth0", "wlan0") or a decimal interface index (e.g., "1", "2").
    * - L3 protocol
      - ``meta.l3_proto``
      - ``eq``
      - ``$PROTOCOL``
      - ``$PROTOCOL`` must be an internet layer protocol name (e.g. "IPv6", case insensitive), or a valid decimal or hexadecimal `IEEE 802 number`_.
    * - L4 protocol
      - ``meta.l4_proto``
      - ``eq``
      - ``$PROTOCOL``
      - ``$PROTOCOL`` must be a transport layer protocol name (e.g. "ICMP", case insensitive), or a valid decimal `internet protocol number`_.
    * - :rspan:`2` Source port
      - :rspan:`2` ``meta.sport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.
    * - :rspan:`2` Destination port
      - :rspan:`2` ``meta.dport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.
    * - Probability
      - ``meta.probability``
      - ``eq``
      - ``$PROBABILITY``
      - ``$PROBABILITY`` is a valid decimal percentage value (i.e., within [0%, 100%]).

IPv4
####

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`2` Source address
      - :rspan:`2` ``ip4.saddr``
      - ``eq``
      - :rspan:`1` ``$ADDR``
      - :rspan:`5` ``$ADDR`` is an IPv4 address in dotted-decimal format, "ddd.ddd.ddd.ddd", where ddd is a decimal number of up to three digits in the range 0 to 255. To filter on an IPv4 network (using an IPv4 address and a subnet mask), see ``ip4.snet`` or ``ip4.dnet``.
    * - ``not``
    * - ``in``
      - ``{$ADDR[,...]}``
    * - :rspan:`2` Destination address
      - :rspan:`2` ``ip4.daddr``
      - ``eq``
      - :rspan:`1` ``$ADDR``
    * - ``not``
    * - ``in``
      - ``{$ADDR[,...]}``
    * - :rspan:`2` Source network
      - :rspan:`2` ``ip4.snet``
      - ``eq``
      - :rspan:`1` ``$ADDR/$MASK``
      - :rspan:`5` ``$ADDR`` is an IPv4 network address in dotted-decimal format, \"ddd.ddd.ddd.ddd\", where ddd is a decimal number of up to three digits in the range 0 to 255, ``$MASK`` is a subnet mask in the range 0 to 32.
    * - ``not``
    * - ``in``
      - ``{$ADDR/$MASK[,...]}``
    * - :rspan:`2` Destination network
      - :rspan:`2` ``ip4.dnet``
      - ``eq``
      - :rspan:`1` ``$ADDR/$MASK``
    * - ``not``
    * - ``in``
      - ``{$ADDR/$MASK[,...]}``
    * - :rspan:`1` Protocol
      - :rspan:`1` ``ip4.proto``
      - ``eq``
      - :rspan:`1` ``$PROTOCOL``
      - :rspan:`1` ``$PROTOCOL`` must be a transport layer protocol name (e.g. "ICMP", case insensitive), or a valid decimal `internet protocol number`_.
    * - ``not``


IPv6
####

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`1` Source address
      - :rspan:`1` ``ip6.saddr``
      - ``eq``
      - :rspan:`3` ``$ADDR``
      - :rspan:`3` ``$ADDR`` must be an IPv6 address composed of 8 hexadecimal numbers (abbreviations are supported). To filter on an IPv6 network (using an IPv6 address and a subnet mask), see ``ip6.snet`` or ``ip6.dnet``.
    * - ``not``
    * - :rspan:`1` Destination address
      - :rspan:`1` ``ip6.daddr``
      - ``eq``
    * - ``not``
    * - :rspan:`2` Source network
      - :rspan:`2` ``ip6.snet``
      - ``eq``
      - :rspan:`1` ``$ADDR/$MASK``
      - :rspan:`5` ``$ADDR`` must be an IPv6 address composed of 8 hexadecimal numbers (abbreviations are supported), ``$MASK`` is a subnet mask in the range 0 to 128.
    * - ``not``
    * - ``in``
      - ``{$ADDR/$MASK[,...]}``
    * - :rspan:`2` Destination network
      - :rspan:`2` ``ip6.dnet``
      - ``eq``
      - :rspan:`1` ``$ADDR/$MASK``
    * - ``not``
    * - ``in``
      - ``{$ADDR/$MASK[,...]}``
    * - :rspan:`1` Next header
      - :rspan:`1` ``ip6.nexthdr``
      - ``eq``
      - :rspan:`3` ``$NEXT_HEADER``
      - :rspan:`3` ``$NEXT_HEADER`` is a transport layer protocol name (e.g. "ICMP", case insensitive), an IPv6 extension header name, or a valid decimal `internet protocol number`_.
    * - ``not``

.. tip::

    The following IPv6 extension header names are recognized by bpfilter: hop, route, frag, ah, dst, mh.

TCP
###

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`2` Source port
      - :rspan:`2` ``tcp.sport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.
    * - :rspan:`2` Destination port
      - :rspan:`2` ``tcp.dport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.
    * - :rspan:`3` Flags
      - :rspan:`3` ``tcp.flags``
      - ``eq``
      - :rspan:`3` ``$FLAG[,...]``
      - :rspan:`3` ``$FLAG`` is a comma-separated list of one or more TCP flags (``fin``, ``syn``, ``rst``, ``psh``, ``ack``, ``urg``, ``ece``, or ``cwr``). Flags are case-insensitive.
    * - ``not``
    * - ``any``
    * - ``all``

.. tip::

   The ``tcp.flags`` operators can be confusing, as they can be used to match all, some, or none of the flags available in the TCP header. This section aims to provide clarity to their exact behavior:

   - ``eq``: the TCP header must contain the exact same flags as defined in the rule. The matcher ``tcp.flags eq syn,ack`` will match ``syn,ack``, but not ``syn,ack,fin`` nor ``rst``.
   - ``not``: opposite of ``eq``, the TCP header must not contain the exact same flags as defined in the rule. The matcher ``tcp.flags eq syn,ack`` will match ``syn,ack,fin`` or ``rst``, but not ``syn,ack``.
   - ``any``: the TCP header must contain any of the flags defined in the rule. The matcher ``tcp.flags eq syn,ack`` will match ``syn``, or ``ack``, or ``syn,ack``, but not ``fin``.
   - ``all``: the TCP header must contain at least the flags defined in the rule. The matcher ``tcp.flags all syn,ack`` will match ``syn,ack,fin``, but not ``syn``, or ``ack,fin``.


UDP
###

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`2` Source port
      - :rspan:`2` ``udp.sport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.
    * - :rspan:`2` Destination port
      - :rspan:`2` ``udp.dport``
      - ``eq``
      - :rspan:`1` ``$PORT``
      - :rspan:`1` ``$PORT`` must be a valid decimal port number.
    * - ``not``
    * - ``range``
      - ``$START-$END``
      - ``$START`` and ``$END`` are valid port values, as decimal integers.

ICMP
####

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`1` Type
      - :rspan:`1` ``icmp.type``
      - ``eq``
      - :rspan:`1` ``$TYPE``
      - :rspan:`1` ``$TYPE`` is an ICMP type name (e.g. "echo-reply", case insensitive), or a decimal or hexadecimal `ICMP type value`_.
    * - ``not``
    * - :rspan:`1` Code
      - :rspan:`1` ``icmp.code``
      - ``eq``
      - :rspan:`1` ``$CODE``
      - :rspan:`1` ``$CODE`` is a decimal or hexadecimal `ICMP code value`_.
    * - ``not``

.. tip::

    The following ICMP type name are recognized by bpfilter: echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation.

ICMPv6
######

.. flat-table::
    :header-rows: 1
    :widths: 2 2 1 4 12
    :fill-cells:

    * - Matches
      - Type
      - Operator
      - Payload
      - Notes
    * - :rspan:`1` Type
      - :rspan:`1` ``icmpv6.type``
      - ``eq``
      - :rspan:`1` ``$TYPE``
      - :rspan:`1` ``$TYPE`` is an ICMPv6 type name (e.g. "echo-reply", case insensitive), or a decimal or hexadecimal `ICMPv6 type value`_.
    * - ``not``
    * - :rspan:`1` Code
      - :rspan:`1` ``icmpv6.code``
      - ``eq``
      - :rspan:`1` ``$CODE``
      - :rspan:`1` ``$CODE`` is a decimal or hexadecimal `ICMPv6 code value`_.
    * - ``not``

.. tip::

    The following ICMPv6 type name are recognized by bpfilter: destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, parameter-problem, mld2-listener-report.


.. _IEEE 802 number: https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml cli,core: convert meta.l3_proto to new framework)
.. _internet protocol number: https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
.. _ICMP type value: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-types
.. _ICMP code value: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-codes
.. _ICMPv6 type value: https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2
.. _ICMPv6 code value: https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-3