diff options
| author | Daniel Borkmann <dborkman@redhat.com> | 2013-12-11 17:43:45 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-12-11 20:28:35 -0500 |
| commit | 7924cd5e0b3acaeafd0d7628d9e9fb8488b8fb13 (patch) | |
| tree | c7a08d552aaa73d1f1186ad0da0f23bd8083d5be | |
| parent | 3f356385e8a449e1d7cfc6b6f8d634ac4f5581a0 (diff) | |
filter: doc: improve BPF documentation
This patch significantly updates the BPF documentation and describes
its internal architecture, Linux extensions, and handling of the
kernel's BPF and JIT engine, plus documents how development can be
facilitated with the help of bpf_dbg, bpf_asm, bpf_jit_disasm.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | Documentation/networking/filter.txt | 608 |
1 files changed, 561 insertions, 47 deletions
diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index cdb3e40b9d14..a06b48d2f5cc 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt | |||
| @@ -1,49 +1,563 @@ | |||
| 1 | filter.txt: Linux Socket Filtering | 1 | Linux Socket Filtering aka Berkeley Packet Filter (BPF) |
| 2 | Written by: Jay Schulist <jschlst@samba.org> | 2 | ======================================================= |
| 3 | 3 | ||
| 4 | Introduction | 4 | Introduction |
| 5 | ============ | 5 | ------------ |
| 6 | 6 | ||
| 7 | Linux Socket Filtering is derived from the Berkeley | 7 | Linux Socket Filtering (LSF) is derived from the Berkeley Packet Filter. |
| 8 | Packet Filter. There are some distinct differences between | 8 | Though there are some distinct differences between the BSD and Linux |
| 9 | the BSD and Linux Kernel Filtering. | 9 | Kernel filtering, but when we speak of BPF or LSF in Linux context, we |
| 10 | 10 | mean the very same mechanism of filtering in the Linux kernel. | |
| 11 | Linux Socket Filtering (LSF) allows a user-space program to | 11 | |
| 12 | attach a filter onto any socket and allow or disallow certain | 12 | BPF allows a user-space program to attach a filter onto any socket and |
| 13 | types of data to come through the socket. LSF follows exactly | 13 | allow or disallow certain types of data to come through the socket. LSF |
| 14 | the same filter code structure as the BSD Berkeley Packet Filter | 14 | follows exactly the same filter code structure as BSD's BPF, so referring |
| 15 | (BPF), so referring to the BSD bpf.4 manpage is very helpful in | 15 | to the BSD bpf.4 manpage is very helpful in creating filters. |
| 16 | creating filters. | 16 | |
| 17 | 17 | On Linux, BPF is much simpler than on BSD. One does not have to worry | |
| 18 | LSF is much simpler than BPF. One does not have to worry about | 18 | about devices or anything like that. You simply create your filter code, |
| 19 | devices or anything like that. You simply create your filter | 19 | send it to the kernel via the SO_ATTACH_FILTER option and if your filter |
| 20 | code, send it to the kernel via the SO_ATTACH_FILTER option and | 20 | code passes the kernel check on it, you then immediately begin filtering |
| 21 | if your filter code passes the kernel check on it, you then | 21 | data on that socket. |
| 22 | immediately begin filtering data on that socket. | 22 | |
| 23 | 23 | You can also detach filters from your socket via the SO_DETACH_FILTER | |
| 24 | You can also detach filters from your socket via the | 24 | option. This will probably not be used much since when you close a socket |
| 25 | SO_DETACH_FILTER option. This will probably not be used much | 25 | that has a filter on it the filter is automagically removed. The other |
| 26 | since when you close a socket that has a filter on it the | 26 | less common case may be adding a different filter on the same socket where |
| 27 | filter is automagically removed. The other less common case | 27 | you had another filter that is still running: the kernel takes care of |
| 28 | may be adding a different filter on the same socket where you had another | 28 | removing the old one and placing your new one in its place, assuming your |
| 29 | filter that is still running: the kernel takes care of removing | 29 | filter has passed the checks, otherwise if it fails the old filter will |
| 30 | the old one and placing your new one in its place, assuming your | 30 | remain on that socket. |
| 31 | filter has passed the checks, otherwise if it fails the old filter | 31 | |
| 32 | will remain on that socket. | 32 | SO_LOCK_FILTER option allows to lock the filter attached to a socket. Once |
| 33 | 33 | set, a filter cannot be removed or changed. This allows one process to | |
| 34 | SO_LOCK_FILTER option allows to lock the filter attached to a | 34 | setup a socket, attach a filter, lock it then drop privileges and be |
| 35 | socket. Once set, a filter cannot be removed or changed. This allows | 35 | assured that the filter will be kept until the socket is closed. |
| 36 | one process to setup a socket, attach a filter, lock it then drop | 36 | |
| 37 | privileges and be assured that the filter will be kept until the | 37 | The biggest user of this construct might be libpcap. Issuing a high-level |
| 38 | socket is closed. | 38 | filter command like `tcpdump -i em1 port 22` passes through the libpcap |
| 39 | 39 | internal compiler that generates a structure that can eventually be loaded | |
| 40 | Examples | 40 | via SO_ATTACH_FILTER to the kernel. `tcpdump -i em1 port 22 -ddd` |
| 41 | ======== | 41 | displays what is being placed into this structure. |
| 42 | 42 | ||
| 43 | Ioctls- | 43 | Although we were only speaking about sockets here, BPF in Linux is used |
| 44 | setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter)); | 44 | in many more places. There's xt_bpf for netfilter, cls_bpf in the kernel |
| 45 | setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &value, sizeof(value)); | 45 | qdisc layer, SECCOMP-BPF (SECure COMPuting [1]), and lots of other places |
| 46 | setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &value, sizeof(value)); | 46 | such as team driver, PTP code, etc where BPF is being used. |
| 47 | 47 | ||
| 48 | See the BSD bpf.4 manpage and the BSD Packet Filter paper written by | 48 | [1] Documentation/prctl/seccomp_filter.txt |
| 49 | Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. | 49 | |
| 50 | Original BPF paper: | ||
| 51 | |||
| 52 | Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new | ||
| 53 | architecture for user-level packet capture. In Proceedings of the | ||
| 54 | USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 | ||
| 55 | Conference Proceedings (USENIX'93). USENIX Association, Berkeley, | ||
| 56 | CA, USA, 2-2. [http://www.tcpdump.org/papers/bpf-usenix93.pdf] | ||
| 57 | |||
| 58 | Structure | ||
| 59 | --------- | ||
| 60 | |||
| 61 | User space applications include <linux/filter.h> which contains the | ||
| 62 | following relevant structures: | ||
| 63 | |||
| 64 | struct sock_filter { /* Filter block */ | ||
| 65 | __u16 code; /* Actual filter code */ | ||
| 66 | __u8 jt; /* Jump true */ | ||
| 67 | __u8 jf; /* Jump false */ | ||
| 68 | __u32 k; /* Generic multiuse field */ | ||
| 69 | }; | ||
| 70 | |||
| 71 | Such a structure is assembled as an array of 4-tuples, that contains | ||
| 72 | a code, jt, jf and k value. jt and jf are jump offsets and k a generic | ||
| 73 | value to be used for a provided code. | ||
| 74 | |||
| 75 | struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ | ||
| 76 | unsigned short len; /* Number of filter blocks */ | ||
| 77 | struct sock_filter __user *filter; | ||
| 78 | }; | ||
| 79 | |||
| 80 | For socket filtering, a pointer to this structure (as shown in | ||
| 81 | follow-up example) is being passed to the kernel through setsockopt(2). | ||
| 82 | |||
| 83 | Example | ||
| 84 | ------- | ||
| 85 | |||
| 86 | #include <sys/socket.h> | ||
| 87 | #include <sys/types.h> | ||
| 88 | #include <arpa/inet.h> | ||
| 89 | #include <linux/if_ether.h> | ||
| 90 | /* ... */ | ||
| 91 | |||
| 92 | /* From the example above: tcpdump -i em1 port 22 -dd */ | ||
| 93 | struct sock_filter code[] = { | ||
| 94 | { 0x28, 0, 0, 0x0000000c }, | ||
| 95 | { 0x15, 0, 8, 0x000086dd }, | ||
| 96 | { 0x30, 0, 0, 0x00000014 }, | ||
| 97 | { 0x15, 2, 0, 0x00000084 }, | ||
| 98 | { 0x15, 1, 0, 0x00000006 }, | ||
| 99 | { 0x15, 0, 17, 0x00000011 }, | ||
| 100 | { 0x28, 0, 0, 0x00000036 }, | ||
| 101 | { 0x15, 14, 0, 0x00000016 }, | ||
| 102 | { 0x28, 0, 0, 0x00000038 }, | ||
| 103 | { 0x15, 12, 13, 0x00000016 }, | ||
| 104 | { 0x15, 0, 12, 0x00000800 }, | ||
| 105 | { 0x30, 0, 0, 0x00000017 }, | ||
| 106 | { 0x15, 2, 0, 0x00000084 }, | ||
| 107 | { 0x15, 1, 0, 0x00000006 }, | ||
| 108 | { 0x15, 0, 8, 0x00000011 }, | ||
| 109 | { 0x28, 0, 0, 0x00000014 }, | ||
| 110 | { 0x45, 6, 0, 0x00001fff }, | ||
| 111 | { 0xb1, 0, 0, 0x0000000e }, | ||
| 112 | { 0x48, 0, 0, 0x0000000e }, | ||
| 113 | { 0x15, 2, 0, 0x00000016 }, | ||
| 114 | { 0x48, 0, 0, 0x00000010 }, | ||
| 115 | { 0x15, 0, 1, 0x00000016 }, | ||
| 116 | { 0x06, 0, 0, 0x0000ffff }, | ||
| 117 | { 0x06, 0, 0, 0x00000000 }, | ||
| 118 | }; | ||
| 119 | |||
| 120 | struct sock_fprog bpf = { | ||
| 121 | .len = ARRAY_SIZE(code), | ||
| 122 | .filter = code, | ||
| 123 | }; | ||
| 124 | |||
| 125 | sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | ||
| 126 | if (sock < 0) | ||
| 127 | /* ... bail out ... */ | ||
| 128 | |||
| 129 | ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); | ||
| 130 | if (ret < 0) | ||
| 131 | /* ... bail out ... */ | ||
| 132 | |||
| 133 | /* ... */ | ||
| 134 | close(sock); | ||
| 135 | |||
| 136 | The above example code attaches a socket filter for a PF_PACKET socket | ||
| 137 | in order to let all IPv4/IPv6 packets with port 22 pass. The rest will | ||
| 138 | be dropped for this socket. | ||
| 139 | |||
| 140 | The setsockopt(2) call to SO_DETACH_FILTER doesn't need any arguments | ||
| 141 | and SO_LOCK_FILTER for preventing the filter to be detached, takes an | ||
| 142 | integer value with 0 or 1. | ||
| 143 | |||
| 144 | Note that socket filters are not restricted to PF_PACKET sockets only, | ||
| 145 | but can also be used on other socket families. | ||
| 146 | |||
| 147 | Summary of system calls: | ||
| 148 | |||
| 149 | * setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &val, sizeof(val)); | ||
| 150 | * setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val)); | ||
| 151 | * setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &val, sizeof(val)); | ||
| 152 | |||
| 153 | Normally, most use cases for socket filtering on packet sockets will be | ||
