mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-24 18:29:06 +08:00
Compare commits
1533 Commits
v0.0.5
...
libbpf_1_0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
862b60f205 | ||
|
|
a0325403af | ||
|
|
7436656dbf | ||
|
|
7984737fbf | ||
|
|
a0d1e22c77 | ||
|
|
e58c615210 | ||
|
|
aec0b1cd7d | ||
|
|
a202bd7433 | ||
|
|
ba81a5b778 | ||
|
|
f7cee4152f | ||
|
|
06c4624c8c | ||
|
|
c8f4b9c878 | ||
|
|
079bc8536d | ||
|
|
8be13ee80b | ||
|
|
3db7585378 | ||
|
|
69938da6d7 | ||
|
|
bfdf7653e0 | ||
|
|
d700dcf162 | ||
|
|
c03b9f6d0b | ||
|
|
66b788c1a4 | ||
|
|
e3c2b8a48d | ||
|
|
13a26d78f3 | ||
|
|
6b92311c3a | ||
|
|
6fdbfb00f1 | ||
|
|
45dca19bd2 | ||
|
|
2fe1958ec8 | ||
|
|
cbd9b7e5d8 | ||
|
|
0cc6bfab39 | ||
|
|
41c612167e | ||
|
|
69d537ba0b | ||
|
|
bd1e5cff31 | ||
|
|
3d484ca473 | ||
|
|
c25544735b | ||
|
|
179c7940eb | ||
|
|
f6692dc4e8 | ||
|
|
693de729d0 | ||
|
|
0667206913 | ||
|
|
a2ebd9ceff | ||
|
|
0e43565ad8 | ||
|
|
5b795f7b30 | ||
|
|
3fa2c28d2c | ||
|
|
0fa013e705 | ||
|
|
d8e2c9d965 | ||
|
|
b2d7228d7c | ||
|
|
427f2a0c83 | ||
|
|
8663289b51 | ||
|
|
77e514d626 | ||
|
|
b44b214118 | ||
|
|
610707057a | ||
|
|
7e567b8761 | ||
|
|
1fe0248c61 | ||
|
|
0862e4e54d | ||
|
|
fd6c9d906a | ||
|
|
d56d93baff | ||
|
|
1648fa16b5 | ||
|
|
9b6f4eb157 | ||
|
|
b3fe4be0b3 | ||
|
|
6d5026e434 | ||
|
|
ca60209447 | ||
|
|
b31ca3fa0e | ||
|
|
295a4aae35 | ||
|
|
8498996f9f | ||
|
|
aa13a6ff58 | ||
|
|
bace4782cd | ||
|
|
ab2221de84 | ||
|
|
d8a50bfe35 | ||
|
|
95971ddd48 | ||
|
|
7410ddc0f4 | ||
|
|
1b80b97a30 | ||
|
|
434b56c497 | ||
|
|
d060a88aa5 | ||
|
|
9340d9b650 | ||
|
|
70599f3a1e | ||
|
|
b78c75fcb3 | ||
|
|
f42d136c1c | ||
|
|
812a95fdf7 | ||
|
|
f9f7f2d30a | ||
|
|
25ba007681 | ||
|
|
9bdb296ec6 | ||
|
|
f009af7889 | ||
|
|
62e8af46d2 | ||
|
|
fcd1b668c6 | ||
|
|
0eb12dca7e | ||
|
|
fedeba74b7 | ||
|
|
bf51e3c336 | ||
|
|
d8454ba8ad | ||
|
|
ec3bbc05c0 | ||
|
|
d32e7ea952 | ||
|
|
6abeb4203d | ||
|
|
e28a540c59 | ||
|
|
e8802d6319 | ||
|
|
9476dce6fe | ||
|
|
8ee1202ff4 | ||
|
|
7013b92fef | ||
|
|
20f0330235 | ||
|
|
29869d6ef0 | ||
|
|
72dbaf2ac3 | ||
|
|
bc3673cdd5 | ||
|
|
78909b8caf | ||
|
|
ec718073b0 | ||
|
|
9c73b6d422 | ||
|
|
0c84902331 | ||
|
|
4cb682229d | ||
|
|
0304a3c027 | ||
|
|
a459010926 | ||
|
|
e5ff285a44 | ||
|
|
2d91c46d1a | ||
|
|
d3e41fc1aa | ||
|
|
645500dd7d | ||
|
|
5497411f48 | ||
|
|
74b22b6c8a | ||
|
|
416351822c | ||
|
|
3f9d041e19 | ||
|
|
a945df2439 | ||
|
|
f429a582bf | ||
|
|
25238de149 | ||
|
|
c3f8eecb16 | ||
|
|
25fd7a1cf5 | ||
|
|
0167a88355 | ||
|
|
23e3d8cf31 | ||
|
|
9a976c6b98 | ||
|
|
e93b1010f3 | ||
|
|
76fc1ad6d5 | ||
|
|
33c5f2bec3 | ||
|
|
d4998cbb6c | ||
|
|
eb1d1ad83f | ||
|
|
8aa946389d | ||
|
|
ad0783c430 | ||
|
|
55638904af | ||
|
|
a5d75daa8c | ||
|
|
37218f49fa | ||
|
|
bdbce77631 | ||
|
|
242c116f04 | ||
|
|
4d9cd51e7e | ||
|
|
f035838503 | ||
|
|
7ed5bf8f4c | ||
|
|
1a0f5d1c87 | ||
|
|
c68a2738fd | ||
|
|
97009215cb | ||
|
|
4c39a3e1aa | ||
|
|
cb11988cf4 | ||
|
|
7e8d4234ac | ||
|
|
00f40c01fb | ||
|
|
881eba7ef5 | ||
|
|
4eb6485c08 | ||
|
|
eaf9123419 | ||
|
|
cc904c1a74 | ||
|
|
f3b96c873d | ||
|
|
47595c2f08 | ||
|
|
e4f2e6e865 | ||
|
|
86eb09863c | ||
|
|
d43fc5a42f | ||
|
|
12e932ac0e | ||
|
|
75452cd290 | ||
|
|
ae67bfbae3 | ||
|
|
650adc5118 | ||
|
|
babc92b9f1 | ||
|
|
e335f3fa5f | ||
|
|
7062757357 | ||
|
|
aec48fffee | ||
|
|
c116ae6130 | ||
|
|
99b21d41e3 | ||
|
|
7a443259de | ||
|
|
b3197662ba | ||
|
|
486b1a080b | ||
|
|
ba9850c048 | ||
|
|
5c1d6799df | ||
|
|
1f30788b41 | ||
|
|
a8bc578af9 | ||
|
|
d46f1aaa7c | ||
|
|
1a18c6f051 | ||
|
|
97ab064bc0 | ||
|
|
eee09dc704 | ||
|
|
87dff0a2c7 | ||
|
|
14777c3784 | ||
|
|
3a4e26307d | ||
|
|
ef6f1fdfff | ||
|
|
c3f58eb6cf | ||
|
|
2c3a55bfe7 | ||
|
|
e2d8a820cb | ||
|
|
aaaeea6499 | ||
|
|
f2e994e0b7 | ||
|
|
eb22de1f7d | ||
|
|
0a901dd1cd | ||
|
|
36582ee432 | ||
|
|
e7f46e2cae | ||
|
|
179ca056b0 | ||
|
|
56dff81d46 | ||
|
|
0d4cefc4fc | ||
|
|
5954a6c4aa | ||
|
|
38be0379c9 | ||
|
|
5fa8bb6b42 | ||
|
|
c5b91a333e | ||
|
|
8073e03491 | ||
|
|
eb2b216081 | ||
|
|
bddd106e80 | ||
|
|
e205664ddb | ||
|
|
557499a13e | ||
|
|
ffd4015f3b | ||
|
|
68e7624e9f | ||
|
|
b221db664f | ||
|
|
7bf9ee2dba | ||
|
|
533c7666eb | ||
|
|
dea5ae9fc9 | ||
|
|
8bc3e510fc | ||
|
|
14414c6ea5 | ||
|
|
ea10235072 | ||
|
|
f3cc144922 | ||
|
|
b69f8ee93e | ||
|
|
bbfb018473 | ||
|
|
1ce956ab3a | ||
|
|
5016f30a24 | ||
|
|
075c96c298 | ||
|
|
f044607934 | ||
|
|
4fd682d358 | ||
|
|
3663820dda | ||
|
|
fcb67a3e70 | ||
|
|
73b8386f2e | ||
|
|
462e3f600a | ||
|
|
13fe7fedfa | ||
|
|
b974879969 | ||
|
|
2b674f2b21 | ||
|
|
5810af7446 | ||
|
|
042471d356 | ||
|
|
f7833c0819 | ||
|
|
c562444fb0 | ||
|
|
750c9fb595 | ||
|
|
08cc701fae | ||
|
|
fa323673c5 | ||
|
|
876b933999 | ||
|
|
406386b441 | ||
|
|
1b4b798916 | ||
|
|
f5390e4f07 | ||
|
|
00cd090f81 | ||
|
|
0167a314e7 | ||
|
|
8dcb95d509 | ||
|
|
d112c9ce24 | ||
|
|
4a7fa5b2bc | ||
|
|
ff845b85e8 | ||
|
|
fee7b9400a | ||
|
|
360ed84faa | ||
|
|
3fbed0f1b2 | ||
|
|
67a4b14643 | ||
|
|
7db9ce5fda | ||
|
|
f1b6bc31a5 | ||
|
|
3ef1813702 | ||
|
|
d580bc49d1 | ||
|
|
cc4ef17c78 | ||
|
|
e7084d4363 | ||
|
|
c2ec92f0ee | ||
|
|
05acce9e03 | ||
|
|
2e6e39ef80 | ||
|
|
42f78dd5ac | ||
|
|
50ae8c25d2 | ||
|
|
e85e26492d | ||
|
|
9fb154ee77 | ||
|
|
34d57cc0eb | ||
|
|
a557610d11 | ||
|
|
5ad674a007 | ||
|
|
d647265e4b | ||
|
|
21cd83a1d1 | ||
|
|
6e77ef94f0 | ||
|
|
c84815ee37 | ||
|
|
4282f3cdec | ||
|
|
3591deb9bc | ||
|
|
767badc609 | ||
|
|
8e654d74c4 | ||
|
|
dac1e23c97 | ||
|
|
dc679587eb | ||
|
|
0d834905d8 | ||
|
|
0a43bc8905 | ||
|
|
5d491d5d07 | ||
|
|
9b53decb02 | ||
|
|
426672106e | ||
|
|
c85a8bbe9c | ||
|
|
e7997e49ea | ||
|
|
4c560383a6 | ||
|
|
9c44c8a8e0 | ||
|
|
1c173e5fc8 | ||
|
|
93c570ca4b | ||
|
|
33201b7ebd | ||
|
|
6edaacad4f | ||
|
|
af29a83fe2 | ||
|
|
6387d3900f | ||
|
|
196da61f1d | ||
|
|
db8dc47ce8 | ||
|
|
f7d89c3910 | ||
|
|
0d6262ad0a | ||
|
|
7593fc7a85 | ||
|
|
67f813c8a8 | ||
|
|
2cd2d03f63 | ||
|
|
74c16e9a0c | ||
|
|
528094c0c1 | ||
|
|
37493e639f | ||
|
|
b0a3b9e8fe | ||
|
|
f7e08b4a8f | ||
|
|
9f6e3a7a59 | ||
|
|
f1a756d793 | ||
|
|
32c19d8505 | ||
|
|
497ec1d35c | ||
|
|
8a28842a20 | ||
|
|
50b4d99bbc | ||
|
|
f5bd7054f9 | ||
|
|
1ceec54cb0 | ||
|
|
d6783c28b4 | ||
|
|
cdef8257a8 | ||
|
|
fd181bc349 | ||
|
|
47673bd255 | ||
|
|
20442822c0 | ||
|
|
a9cd83ae25 | ||
|
|
352c13cdee | ||
|
|
a7a3a8811c | ||
|
|
bd402dccaf | ||
|
|
c245b0eeaf | ||
|
|
74dcd1bf6a | ||
|
|
9f276b240b | ||
|
|
9a64065733 | ||
|
|
ae220adbb2 | ||
|
|
fec0813359 | ||
|
|
1e702e8ffe | ||
|
|
bad4fa116c | ||
|
|
b2a7b16287 | ||
|
|
638311dcb8 | ||
|
|
e72ac682ae | ||
|
|
d2818a8f2c | ||
|
|
c0c3f46ca6 | ||
|
|
1af0f62fac | ||
|
|
04aef6ce9b | ||
|
|
a9491bb920 | ||
|
|
fb0b8a7cea | ||
|
|
4ae89237d4 | ||
|
|
9af0e19376 | ||
|
|
57df70e180 | ||
|
|
da06e3efcc | ||
|
|
b4b6e4dc20 | ||
|
|
0ee425cdd7 | ||
|
|
f1085fe3c3 | ||
|
|
393a058d06 | ||
|
|
3febb8a165 | ||
|
|
5daafdccf9 | ||
|
|
78e816a15d | ||
|
|
d2ea0e2d03 | ||
|
|
8fbe7eec3a | ||
|
|
d788cd57b5 | ||
|
|
ab022c8eb4 | ||
|
|
75c7c722f5 | ||
|
|
0f99d97a9c | ||
|
|
8404d1396c | ||
|
|
be89b28f96 | ||
|
|
7b8e97bffc | ||
|
|
5b6dfd7f6b | ||
|
|
e0de05d1b1 | ||
|
|
d5daf275c7 | ||
|
|
cde5b418dd | ||
|
|
060c8a99c4 | ||
|
|
22411acc4b | ||
|
|
e99f34e144 | ||
|
|
4449d71509 | ||
|
|
12932191c6 | ||
|
|
8440112546 | ||
|
|
b0c3d7133f | ||
|
|
c2f2c26cb2 | ||
|
|
2e52e09bc2 | ||
|
|
0171976dc5 | ||
|
|
3f592a59d7 | ||
|
|
0557ad0a9c | ||
|
|
7c382f0df9 | ||
|
|
ceba6a788a | ||
|
|
bf7aacea49 | ||
|
|
af2da673d8 | ||
|
|
1321a8bb49 | ||
|
|
287d0d097b | ||
|
|
9fab7c81ec | ||
|
|
96268bf0c2 | ||
|
|
168cf9b8ae | ||
|
|
8e706ddc6c | ||
|
|
dc49f2d07b | ||
|
|
19656636a9 | ||
|
|
61acde2308 | ||
|
|
266e897ad2 | ||
|
|
7152ecf163 | ||
|
|
216eaa760e | ||
|
|
a4e725f8f5 | ||
|
|
df5689f1c8 | ||
|
|
6894f573d2 | ||
|
|
2b0d408764 | ||
|
|
ac20634cdc | ||
|
|
04804b4710 | ||
|
|
16bb788578 | ||
|
|
5eb804a2db | ||
|
|
bcf58fc7a5 | ||
|
|
1f83414ea4 | ||
|
|
a0ddf21c92 | ||
|
|
bb14c6f5b5 | ||
|
|
c7dedfe23f | ||
|
|
f13e766fa4 | ||
|
|
90910812b5 | ||
|
|
eb9d74e7ad | ||
|
|
d9b3fae391 | ||
|
|
dc1df24314 | ||
|
|
0504b7ff22 | ||
|
|
3c93f7ddb2 | ||
|
|
896a3ae0d0 | ||
|
|
728b1721e5 | ||
|
|
04941813a5 | ||
|
|
c3c540b402 | ||
|
|
b633ace366 | ||
|
|
d761220e33 | ||
|
|
ac1c007607 | ||
|
|
01b2b45e8d | ||
|
|
a7935b996f | ||
|
|
5f887b332c | ||
|
|
20e7ed521a | ||
|
|
d785a21c71 | ||
|
|
8e43882e53 | ||
|
|
2be7e6a830 | ||
|
|
b9bd1f8682 | ||
|
|
c4da8092cc | ||
|
|
b2b45a3131 | ||
|
|
73c8768db7 | ||
|
|
bafda72319 | ||
|
|
33ec2ca026 | ||
|
|
7e89be4022 | ||
|
|
e61e089911 | ||
|
|
93e89b3474 | ||
|
|
b9d46530c3 | ||
|
|
4884bf3dbd | ||
|
|
690d0531f9 | ||
|
|
7cda69caeb | ||
|
|
1f7db672e4 | ||
|
|
385b2d1738 | ||
|
|
7f11cd48d6 | ||
|
|
4374bad784 | ||
|
|
55b057565f | ||
|
|
472c0726e8 | ||
|
|
c86cb27d5b | ||
|
|
3ef05a585e | ||
|
|
493bfa8a59 | ||
|
|
9f006f1ed6 | ||
|
|
5fc0d66cad | ||
|
|
37c3e92657 | ||
|
|
25eb5c4e02 | ||
|
|
07e4e0cb04 | ||
|
|
316b60fa89 | ||
|
|
6cfb97c561 | ||
|
|
5c31bcf220 | ||
|
|
5b4dbd8141 | ||
|
|
14e12f4290 | ||
|
|
60ce9af668 | ||
|
|
d29571725a | ||
|
|
842c5b7bff | ||
|
|
9109d6a4b4 | ||
|
|
eab19ffead | ||
|
|
94a49850c5 | ||
|
|
d71409b508 | ||
|
|
f0ecdeed3a | ||
|
|
d924fa62ee | ||
|
|
0f5a62b2d8 | ||
|
|
5ca49d2b32 | ||
|
|
219c8e11e0 | ||
|
|
140b902274 | ||
|
|
1987a34fc9 | ||
|
|
3b1714aa92 | ||
|
|
554054d876 | ||
|
|
26e196d449 | ||
|
|
3fac0b3d08 | ||
|
|
ac4a0fa400 | ||
|
|
6ad73f5083 | ||
|
|
8a52e49575 | ||
|
|
5b9d079c7f | ||
|
|
bc66d28b68 | ||
|
|
98181e0546 | ||
|
|
d932a1a46b | ||
|
|
011a01594c | ||
|
|
b9a88a4533 | ||
|
|
969018545d | ||
|
|
0e80b7dc3f | ||
|
|
932800b20b | ||
|
|
cfc69268e5 | ||
|
|
9b2bbdefd5 | ||
|
|
c7236a5342 | ||
|
|
a611094604 | ||
|
|
9b422137af | ||
|
|
65cdd0c73d | ||
|
|
6b2db898cc | ||
|
|
ea6c242fc6 | ||
|
|
86175df408 | ||
|
|
26e768783c | ||
|
|
88209a3c44 | ||
|
|
2ab2615926 | ||
|
|
c03b183a6e | ||
|
|
36cc591ac8 | ||
|
|
3acf7c289a | ||
|
|
a383b3e200 | ||
|
|
2f52e2afc0 | ||
|
|
738277b773 | ||
|
|
16dfb4ffe4 | ||
|
|
826770613d | ||
|
|
277846bc6c | ||
|
|
1e97e84c86 | ||
|
|
17d7f04e7c | ||
|
|
c4f9ee9fbb | ||
|
|
6fd2ee5486 | ||
|
|
7beaa2ef90 | ||
|
|
a0195b3078 | ||
|
|
bedab00b50 | ||
|
|
c95bf6714d | ||
|
|
8e697cf9fd | ||
|
|
1dd20d7144 | ||
|
|
28c8a2c179 | ||
|
|
11f873fd5b | ||
|
|
50041f432d | ||
|
|
87a9622982 | ||
|
|
5b732fc1d8 | ||
|
|
ffc5139acd | ||
|
|
cfbdceb99d | ||
|
|
9871f15dd6 | ||
|
|
93c109c9ee | ||
|
|
eaea2bce02 | ||
|
|
f05791d8cf | ||
|
|
2bb8f041b0 | ||
|
|
50ae3acfe9 | ||
|
|
07ba0eeb8e | ||
|
|
b15d479ef7 | ||
|
|
d374094d8c | ||
|
|
19d260d144 | ||
|
|
f1558d7a23 | ||
|
|
596c9a2d77 | ||
|
|
eb10610a3b | ||
|
|
d7982f3948 | ||
|
|
76b4bf4295 | ||
|
|
5bf62459b1 | ||
|
|
421213a052 | ||
|
|
4cafbf7527 | ||
|
|
f687443178 | ||
|
|
38fb8cfc0c | ||
|
|
45115706b6 | ||
|
|
bde69b0ee0 | ||
|
|
19c6144c09 | ||
|
|
760c39208c | ||
|
|
fa93001e85 | ||
|
|
50028712c4 | ||
|
|
0f3ba10651 | ||
|
|
ebf17ac628 | ||
|
|
06390e2371 | ||
|
|
720324afab | ||
|
|
92c1e61a60 | ||
|
|
133e3603ec | ||
|
|
f9f6e92458 | ||
|
|
b05bace770 | ||
|
|
7022527a7b | ||
|
|
d3169df794 | ||
|
|
d665ca0bb0 | ||
|
|
744fd961c7 | ||
|
|
13ebb60ab6 | ||
|
|
3298393748 | ||
|
|
0141d9dded | ||
|
|
7dde8f8f8d | ||
|
|
962f241379 | ||
|
|
8c2d905ff4 | ||
|
|
531be4d879 | ||
|
|
f49c65d216 | ||
|
|
b0feb9b4d5 | ||
|
|
e671a47bc2 | ||
|
|
151e3cb314 | ||
|
|
2cfeea135c | ||
|
|
3fe8ee2edb | ||
|
|
823881b4f6 | ||
|
|
20c1aa11b1 | ||
|
|
62ea715f71 | ||
|
|
3c5c62097e | ||
|
|
fba5f02401 | ||
|
|
bb833f8129 | ||
|
|
cb12e83136 | ||
|
|
09b528e847 | ||
|
|
9ecc0dcc19 | ||
|
|
246b61780b | ||
|
|
cdf14ff22b | ||
|
|
e1966114cc | ||
|
|
989d7189cd | ||
|
|
18922504c3 | ||
|
|
029273039d | ||
|
|
b177fac2e2 | ||
|
|
3e7c04669e | ||
|
|
599b999f5d | ||
|
|
e856a7d560 | ||
|
|
0a76ce1395 | ||
|
|
1eba3a6470 | ||
|
|
7d365e49f3 | ||
|
|
980777cc16 | ||
|
|
24dbcb3a30 | ||
|
|
42da89eb16 | ||
|
|
627cbb395b | ||
|
|
7e7f59d658 | ||
|
|
966ba8918d | ||
|
|
fad7357469 | ||
|
|
a6188fc5b4 | ||
|
|
d328ba7768 | ||
|
|
27d14b6e3b | ||
|
|
f3c744997f | ||
|
|
749b3942a0 | ||
|
|
8ade99a6f8 | ||
|
|
0c0f4a57da | ||
|
|
03f31a6aed | ||
|
|
f8983f7fb0 | ||
|
|
514bb47ac5 | ||
|
|
05d95ef6fa | ||
|
|
eda1ebe520 | ||
|
|
7c26fe30f3 | ||
|
|
5579664205 | ||
|
|
860b201cd0 | ||
|
|
50e13993a1 | ||
|
|
72fd44da53 | ||
|
|
d6e9681b0d | ||
|
|
517762deca | ||
|
|
1670e6100b | ||
|
|
ed529685db | ||
|
|
c92a5d043e | ||
|
|
aea40f7179 | ||
|
|
8bdc267e7b | ||
|
|
d0c398be4f | ||
|
|
7d9cc837ef | ||
|
|
a3c0cc19d4 | ||
|
|
7c6d34a2c9 | ||
|
|
a69c52bb11 | ||
|
|
6d67d53143 | ||
|
|
91259bc676 | ||
|
|
a3f8c5a306 | ||
|
|
d23679b415 | ||
|
|
9923f25600 | ||
|
|
40160ed4d4 | ||
|
|
7b22fc4cdb | ||
|
|
152882e17a | ||
|
|
0e7520949e | ||
|
|
c3f7daaab5 | ||
|
|
1a1e7a0612 | ||
|
|
827963ffb3 | ||
|
|
4ab24e7d62 | ||
|
|
b2a63c974d | ||
|
|
88649fe655 | ||
|
|
1778e0b1bd | ||
|
|
64f027efda | ||
|
|
6bf8babb33 | ||
|
|
70ad3e8314 | ||
|
|
dbdd8f3b34 | ||
|
|
52e96052a2 | ||
|
|
41db5534d8 | ||
|
|
54a7bc87d5 | ||
|
|
9979463ccf | ||
|
|
b91ca01922 | ||
|
|
8ded7c6db0 | ||
|
|
7df4ea0f0d | ||
|
|
02efadd0b0 | ||
|
|
02333ba360 | ||
|
|
2805c2a4ca | ||
|
|
6921017d25 | ||
|
|
e65d128903 | ||
|
|
512b472d97 | ||
|
|
73788dd22f | ||
|
|
a180eb551e | ||
|
|
9d2b7e471b | ||
|
|
3a0fc666ef | ||
|
|
7c25b1d569 | ||
|
|
d41e821ccf | ||
|
|
2fe57e40ac | ||
|
|
f81dbd3475 | ||
|
|
035fd6aca0 | ||
|
|
e44c8486c6 | ||
|
|
14f5433b2e | ||
|
|
d7a2de020b | ||
|
|
bb92e7ab4d | ||
|
|
3f22535d56 | ||
|
|
f8ab8bde8e | ||
|
|
506a544834 | ||
|
|
ec2c78c034 | ||
|
|
030ff87857 | ||
|
|
0db006d28e | ||
|
|
6e6f18ac5d | ||
|
|
deca7932c3 | ||
|
|
ebcae72279 | ||
|
|
64362b8896 | ||
|
|
df01b246df | ||
|
|
6eb5e25905 | ||
|
|
a603965dad | ||
|
|
f61c3b318b | ||
|
|
8235032464 | ||
|
|
dc2c53b7f6 | ||
|
|
fb3809e940 | ||
|
|
74d3571880 | ||
|
|
be570b29c1 | ||
|
|
9aa71e1040 | ||
|
|
b3ffd258fc | ||
|
|
4447ac82d4 | ||
|
|
8fa229c455 | ||
|
|
8a670b7422 | ||
|
|
21f90f61b0 | ||
|
|
c8b1d14b03 | ||
|
|
c0b2ceba1d | ||
|
|
bd25fc7df1 | ||
|
|
4920031c88 | ||
|
|
8fa50e86c1 | ||
|
|
330a158982 | ||
|
|
a524ae0bbf | ||
|
|
97e2a9c9a1 | ||
|
|
bef77595ca | ||
|
|
6f7839f477 | ||
|
|
90aba5e582 | ||
|
|
4dc3aeb072 | ||
|
|
4ce0551ee5 | ||
|
|
f8411901c4 | ||
|
|
9ff2b76693 | ||
|
|
df023f5cfc | ||
|
|
ae62c159ec | ||
|
|
8bf016110e | ||
|
|
d3e4039a0a | ||
|
|
dd34504b43 | ||
|
|
bec2ae0c6e | ||
|
|
1d6106cf45 | ||
|
|
95e51c1dbe | ||
|
|
db132757c9 | ||
|
|
41cddf18f4 | ||
|
|
f883bbf3f4 | ||
|
|
db8982bcaa | ||
|
|
d1571ab5ce | ||
|
|
03b0787342 | ||
|
|
a1bd8104a9 | ||
|
|
ccead28901 | ||
|
|
0b59d75ecd | ||
|
|
a5ee05d505 | ||
|
|
42ebbbce7d | ||
|
|
26497b9a88 | ||
|
|
5d5af3f07e | ||
|
|
899c45baa2 | ||
|
|
95008d47dd | ||
|
|
13acc0af00 | ||
|
|
1b9138e452 | ||
|
|
2da7f66d3f | ||
|
|
9d5ac4931d | ||
|
|
5bfbb36440 | ||
|
|
343f63e245 | ||
|
|
0dccb885a3 | ||
|
|
8e3a63ea48 | ||
|
|
7c7ba067fc | ||
|
|
12eb2666d9 | ||
|
|
234dea015b | ||
|
|
c3c2e52201 | ||
|
|
b79c698300 | ||
|
|
546199a723 | ||
|
|
b44566c71b | ||
|
|
594960b3db | ||
|
|
694a70c522 | ||
|
|
c96f2f1b29 | ||
|
|
ac2095783a | ||
|
|
fecf2cf6dd | ||
|
|
c1f36fb3e3 | ||
|
|
6eac86910c | ||
|
|
64a654f398 | ||
|
|
34eb4fb3f1 | ||
|
|
007709011e | ||
|
|
db9614b6bd | ||
|
|
57375504c6 | ||
|
|
d71ff87a2d | ||
|
|
01515b8f05 | ||
|
|
6028cec50c | ||
|
|
68695d0173 | ||
|
|
72cdd6ed42 | ||
|
|
b5bfbab488 | ||
|
|
1cf1c245d1 | ||
|
|
076dd5dadb | ||
|
|
6f585ab88f | ||
|
|
c5389a965b | ||
|
|
a58b8ca93e | ||
|
|
1691c37b39 | ||
|
|
242842b34c | ||
|
|
6b14cfa56e | ||
|
|
b8b1faa3d4 | ||
|
|
9e123fa5d2 | ||
|
|
4ccc1f0b9f | ||
|
|
b9278634aa | ||
|
|
af47e6c199 | ||
|
|
b2c06aec99 | ||
|
|
29e4840915 | ||
|
|
7078c5eae4 | ||
|
|
692ae888bc | ||
|
|
24b5d82967 | ||
|
|
4dcf439178 | ||
|
|
d9b9d4a43a | ||
|
|
7b106ea4b1 | ||
|
|
3319982d34 | ||
|
|
2e430712f5 | ||
|
|
120a21852b | ||
|
|
f4da689d90 | ||
|
|
30755d3a1c | ||
|
|
dda0dd6a87 | ||
|
|
c21f91bd35 | ||
|
|
552dec12dc | ||
|
|
678e8c8e49 | ||
|
|
f6de59dc3e | ||
|
|
823648416c | ||
|
|
02dbcbea28 | ||
|
|
a7502f2707 | ||
|
|
bab780e6f9 | ||
|
|
915f3abe94 | ||
|
|
0c248143d4 | ||
|
|
9f0e42b512 | ||
|
|
174d0b7b49 | ||
|
|
95f83b8b0c | ||
|
|
416343d95c | ||
|
|
4f932c1ee9 | ||
|
|
37e838f959 | ||
|
|
d98e968707 | ||
|
|
d4beac571a | ||
|
|
bea42d49f8 | ||
|
|
4e8d8d5cd2 | ||
|
|
8628610c32 | ||
|
|
2e51adc9bc | ||
|
|
1ccb9d99d6 | ||
|
|
90e052e6dd | ||
|
|
7ef7ed2a5d | ||
|
|
7036f3356e | ||
|
|
e5d7cbe15a | ||
|
|
e35afcb289 | ||
|
|
a18b72b920 | ||
|
|
2bd682d23e | ||
|
|
99bc176337 | ||
|
|
ea5752c641 | ||
|
|
1d2d2d0034 | ||
|
|
582b8fe21b | ||
|
|
3ea10e46cb | ||
|
|
3118d38a2e | ||
|
|
b09a4999d9 | ||
|
|
53f0e7d8ec | ||
|
|
d4d3a88b5a | ||
|
|
7b1f3e310b | ||
|
|
b156979d19 | ||
|
|
bd81770e10 | ||
|
|
4fdc36418d | ||
|
|
861ad35ceb | ||
|
|
7fc514acf1 | ||
|
|
74e94c40fe | ||
|
|
082a5c6020 | ||
|
|
75a2e3bda8 | ||
|
|
c8bfeae778 | ||
|
|
a0ad81d9c4 | ||
|
|
b727e2deca | ||
|
|
27db7104d5 | ||
|
|
c14f7e5dcf | ||
|
|
bbc65156d7 | ||
|
|
c903b3ab70 | ||
|
|
186ffbe0b5 | ||
|
|
1d483b45fc | ||
|
|
d64f8d3207 | ||
|
|
4f2e1ecbd9 | ||
|
|
21f523f235 | ||
|
|
18c0f03e2d | ||
|
|
fade1c32e6 | ||
|
|
8c2c7e5bcf | ||
|
|
092a606856 | ||
|
|
986962fade | ||
|
|
471e7c241d | ||
|
|
617f781804 | ||
|
|
473899d4f7 | ||
|
|
7e03685b8d | ||
|
|
7065a809fc | ||
|
|
18b55bc136 | ||
|
|
712f6587c9 | ||
|
|
60aa32b17a | ||
|
|
f3612e4117 | ||
|
|
587d2ab628 | ||
|
|
6cc16d6401 | ||
|
|
f0753b5259 | ||
|
|
642655629b | ||
|
|
14a61e86f0 | ||
|
|
d142d4a382 | ||
|
|
99e6a464b8 | ||
|
|
1015d47c2b | ||
|
|
06ee116fb1 | ||
|
|
e1a90f3768 | ||
|
|
f2a926ba46 | ||
|
|
b0b5ec0006 | ||
|
|
adaf538bca | ||
|
|
f35e87ddc4 | ||
|
|
767d82caab | ||
|
|
a199b85415 | ||
|
|
649f9dc746 | ||
|
|
eb56f8fb12 | ||
|
|
6e01a23cf6 | ||
|
|
16d7f413e2 | ||
|
|
f037b92465 | ||
|
|
4adbb7b2c7 | ||
|
|
d2b784d370 | ||
|
|
ac86f42e4a | ||
|
|
03fbe22a59 | ||
|
|
f15814c93a | ||
|
|
0db7da9a4a | ||
|
|
0de8b9a906 | ||
|
|
d52e5f5f88 | ||
|
|
a26ae1b254 | ||
|
|
c1d4bbb8c7 | ||
|
|
7c2a94f4f8 | ||
|
|
051a4009f9 | ||
|
|
a3a5e9688a | ||
|
|
5569404346 | ||
|
|
e05f9be4f4 | ||
|
|
4d3535ff7b | ||
|
|
c66a9770e3 | ||
|
|
8262be6034 | ||
|
|
182e9dde0d | ||
|
|
30e2c16571 | ||
|
|
ebcae62e7e | ||
|
|
252ad1f3eb | ||
|
|
3e68c60659 | ||
|
|
42baefba71 | ||
|
|
46ecf7aef3 | ||
|
|
2981bb8d26 | ||
|
|
2042df2fed | ||
|
|
8c2c4c3451 | ||
|
|
21ae7bb113 | ||
|
|
b2a34784b2 | ||
|
|
d95b12da56 | ||
|
|
a1fd6dab54 | ||
|
|
fde1be5a9c | ||
|
|
6b08519a69 | ||
|
|
aff8028b6e | ||
|
|
10e321f100 | ||
|
|
8051a539d8 | ||
|
|
691c22dc0c | ||
|
|
5fe9c1217a | ||
|
|
78c76a1015 | ||
|
|
a741bc6479 | ||
|
|
65e4be6f5d | ||
|
|
3a2739aa8a | ||
|
|
dd2369d2a8 | ||
|
|
39f5b2e75e | ||
|
|
6969a44914 | ||
|
|
de2edae80d | ||
|
|
2ea4ba9c96 | ||
|
|
2dd5965052 | ||
|
|
ef8820fea8 | ||
|
|
eae38a781c | ||
|
|
83c2c20acb | ||
|
|
00ae5bac8f | ||
|
|
f99c252cbc | ||
|
|
5ae2a2621c | ||
|
|
5af3d86b5a | ||
|
|
c55abf0752 | ||
|
|
e30f758aab | ||
|
|
8caff995c7 | ||
|
|
539aa6bea5 | ||
|
|
224db2db07 | ||
|
|
e6725d2467 | ||
|
|
658ac1ec19 | ||
|
|
dd36215834 | ||
|
|
2811d54f8b | ||
|
|
be2dc73ee2 | ||
|
|
4953827790 | ||
|
|
d1fd50d475 | ||
|
|
f0c6b6bdfb | ||
|
|
475ee87969 | ||
|
|
f754860e35 | ||
|
|
78d61150e9 | ||
|
|
49280406a2 | ||
|
|
de58d0cccf | ||
|
|
6fa81d4dbe | ||
|
|
bc94c2b82f | ||
|
|
d47094a2ce | ||
|
|
4672fb6790 | ||
|
|
a8a505a36f | ||
|
|
e3b9cf7aaa | ||
|
|
76764b891b | ||
|
|
8ef6a6e709 | ||
|
|
44d5bc1709 | ||
|
|
95848b59b9 | ||
|
|
1bc08143b5 | ||
|
|
b9682e291d | ||
|
|
54fe2f1e26 | ||
|
|
fd28e0130a | ||
|
|
f908087023 | ||
|
|
b3b297aa16 | ||
|
|
6d0fcc3bd5 | ||
|
|
3706bf773b | ||
|
|
09718f4ecd | ||
|
|
8205f37a56 | ||
|
|
ecbd504994 | ||
|
|
b6dd2f2b7d | ||
|
|
a132697261 | ||
|
|
2d0aa12ea3 | ||
|
|
317ef1c295 | ||
|
|
80c7838600 | ||
|
|
750801a0d5 | ||
|
|
b5fd4c774d | ||
|
|
5a10cd2060 | ||
|
|
ff797cc905 | ||
|
|
21ea184818 | ||
|
|
760f71ec87 | ||
|
|
91e666c94c | ||
|
|
e40af4de0c | ||
|
|
5e359219aa | ||
|
|
488110df60 | ||
|
|
f007a6bfdf | ||
|
|
6f90197ab0 | ||
|
|
a388fcb0f5 | ||
|
|
2654268c79 | ||
|
|
e7647823a1 | ||
|
|
3cfff16611 | ||
|
|
7ac1547f32 | ||
|
|
897a0e79bd | ||
|
|
063eed6105 | ||
|
|
71e8af71c5 | ||
|
|
4023fbd99e | ||
|
|
b2e50daea8 | ||
|
|
b6f1385458 | ||
|
|
146bdd7535 | ||
|
|
76ee807ee3 | ||
|
|
32e5add48f | ||
|
|
120e99ccd8 | ||
|
|
3cf3c6cd26 | ||
|
|
f38fccf3cc | ||
|
|
08dc84e54a | ||
|
|
0102f65d72 | ||
|
|
f700cf6667 | ||
|
|
99921245f0 | ||
|
|
37c5973bb7 | ||
|
|
2200fefd87 | ||
|
|
5f50b4b8c9 | ||
|
|
787abf721e | ||
|
|
820813bd1b | ||
|
|
8333e57e91 | ||
|
|
8052936468 | ||
|
|
8b14cb43ff | ||
|
|
011700e68d | ||
|
|
106e7dcf58 | ||
|
|
3a2ebfc21e | ||
|
|
91001a9923 | ||
|
|
6384ee1968 | ||
|
|
3f9447bf92 | ||
|
|
3b80b6c77e | ||
|
|
78cdb58bdf | ||
|
|
4b60f82516 | ||
|
|
2b28b4fa4d | ||
|
|
448789ba27 | ||
|
|
a3abae5122 | ||
|
|
bb5e70706a | ||
|
|
994aae7fc8 | ||
|
|
a6e9cf1532 | ||
|
|
06ae1b0e38 | ||
|
|
b228eb84f1 | ||
|
|
5bd7cae11d | ||
|
|
a454a08f53 | ||
|
|
829e50fc15 | ||
|
|
66780a46cb | ||
|
|
7bc52e6602 | ||
|
|
7267270f5f | ||
|
|
b16bc44bd3 | ||
|
|
4cdad1b34b | ||
|
|
f557d9e1fc | ||
|
|
e82da07e2d | ||
|
|
c42c140954 | ||
|
|
e565f2bfe9 | ||
|
|
2bd0d158d4 | ||
|
|
bbe442da7a | ||
|
|
3f7b5b32b8 | ||
|
|
5a913e9401 | ||
|
|
cead23ac75 | ||
|
|
66091d267c | ||
|
|
2819b00b74 | ||
|
|
cb4d6d6f1a | ||
|
|
4f160ed607 | ||
|
|
647df00570 | ||
|
|
44fdfd8e6e | ||
|
|
75d2adfe84 | ||
|
|
f0f75f36a7 | ||
|
|
a8fa8b6eea | ||
|
|
8a1acb7dfe | ||
|
|
b6e179e67c | ||
|
|
d81d872279 | ||
|
|
4001a658e0 | ||
|
|
dc1cd8503f | ||
|
|
9a3a42608d | ||
|
|
63c78982c7 | ||
|
|
28e26bdc3e | ||
|
|
7297e38474 | ||
|
|
a44116bb1f | ||
|
|
4069acb787 | ||
|
|
c7d2b1f31b | ||
|
|
b06fb2312c | ||
|
|
1e2c7823f5 | ||
|
|
160917756a | ||
|
|
4a2f7ac55f | ||
|
|
a8a3089b5e | ||
|
|
475843fbf4 | ||
|
|
f89dab0903 | ||
|
|
cdb21b05e5 | ||
|
|
a734ef0803 | ||
|
|
3c4954d5a6 | ||
|
|
c3b1c66810 | ||
|
|
dc70da9c70 | ||
|
|
9106c3028b | ||
|
|
3bde6ca8e8 | ||
|
|
d13e96ee32 | ||
|
|
dc1b3e2a45 | ||
|
|
30c61391bf | ||
|
|
e6f118dddd | ||
|
|
5d4075553b | ||
|
|
5205159359 | ||
|
|
87d7f1a32b | ||
|
|
e8547bd4f7 | ||
|
|
93959e4e43 | ||
|
|
7ee1f12f94 | ||
|
|
ff09ad9dac | ||
|
|
025fcdc306 | ||
|
|
b3405fcb08 | ||
|
|
1194953749 | ||
|
|
1d76180057 | ||
|
|
048bf21dac | ||
|
|
e954437a76 | ||
|
|
c57be0b4d6 | ||
|
|
bf3ab4b0d8 | ||
|
|
663f66decf | ||
|
|
ed187d0400 | ||
|
|
80453d4b2d | ||
|
|
7f96c4b1d2 | ||
|
|
2be293cb4a | ||
|
|
a0334e97aa | ||
|
|
2d97d4097f | ||
|
|
80a52e3252 | ||
|
|
2dc7cbd893 | ||
|
|
0466b9833b | ||
|
|
ba8d45968b | ||
|
|
734b3f0afe | ||
|
|
f56874ba8a | ||
|
|
3f26bf1adf | ||
|
|
ab01213b35 | ||
|
|
8af35e73a2 | ||
|
|
a290d45322 | ||
|
|
3f6b428909 | ||
|
|
5efd8395ef | ||
|
|
b1720407ff | ||
|
|
698820a9d9 | ||
|
|
6d92249be0 | ||
|
|
1736996279 | ||
|
|
f9f5f054d2 | ||
|
|
4a5aecf034 | ||
|
|
77f11b3674 | ||
|
|
cd46c9d67e | ||
|
|
41054a32df | ||
|
|
852b4c8e73 | ||
|
|
de60a31eba | ||
|
|
8ec7d86efe | ||
|
|
c3984343bc | ||
|
|
5255eb2799 | ||
|
|
8b5e81a17a | ||
|
|
cd016d93f7 | ||
|
|
deaee9541d | ||
|
|
daa2c7f851 | ||
|
|
006904d416 | ||
|
|
e47ebc895d | ||
|
|
3b2837e296 | ||
|
|
90716e9e14 | ||
|
|
d5a36e2070 | ||
|
|
133543c202 | ||
|
|
abb82202da | ||
|
|
5020fdf8fc | ||
|
|
a846caca79 | ||
|
|
1b42b15b5e | ||
|
|
a2b27a1b62 | ||
|
|
7b9d71b21d | ||
|
|
89f7f0796a | ||
|
|
c054d91247 | ||
|
|
9c104b1637 | ||
|
|
d08d57cd91 | ||
|
|
803243cc33 | ||
|
|
d707f8027b | ||
|
|
652f2c0a40 | ||
|
|
2fcd394505 | ||
|
|
af3c9f9fc4 | ||
|
|
a62b08dd0c | ||
|
|
318ed9d544 | ||
|
|
47370741be | ||
|
|
26e5e7dcb0 | ||
|
|
cd469e21e8 | ||
|
|
18bfe12dc1 | ||
|
|
fef856084a | ||
|
|
6f8e021c3c | ||
|
|
143213eb82 | ||
|
|
ac74ee188d | ||
|
|
15943906dc | ||
|
|
85749135a6 | ||
|
|
3b320677cd | ||
|
|
15fee53503 | ||
|
|
169d35c746 | ||
|
|
d8d4713476 | ||
|
|
ef26b4c37f | ||
|
|
d7b2934cf9 | ||
|
|
c83d2166e8 | ||
|
|
fb27968bf1 | ||
|
|
d6ae406429 | ||
|
|
cb174c5b8d | ||
|
|
17f747ed38 | ||
|
|
bf34234885 | ||
|
|
46c272f9b4 | ||
|
|
40e69c9538 | ||
|
|
a975d8ea28 | ||
|
|
45f7113925 | ||
|
|
6816734203 | ||
|
|
11d2a59689 | ||
|
|
8c7527ea88 | ||
|
|
c569e03985 | ||
|
|
1862741fb0 | ||
|
|
6a269cf458 | ||
|
|
6e15a022db | ||
|
|
20d9816471 | ||
|
|
538b3f4ce7 | ||
|
|
f2610ca9cf | ||
|
|
adb5dd203c | ||
|
|
3aadd91e97 | ||
|
|
1206ab0e75 | ||
|
|
70eac9941d | ||
|
|
2fdbf42f98 | ||
|
|
365e4805a1 | ||
|
|
890f25520a | ||
|
|
fbdee96fa1 | ||
|
|
f54c56be0d | ||
|
|
8dc4b38871 | ||
|
|
ed023acd35 | ||
|
|
ff3116bfcb | ||
|
|
65f4b3ba4c | ||
|
|
e1bf7a787e | ||
|
|
17a6d61898 | ||
|
|
ff2322b879 | ||
|
|
ab1b4f3844 | ||
|
|
df9a526f99 | ||
|
|
3b23942542 | ||
|
|
90941cde5f | ||
|
|
97a0d1e7b5 | ||
|
|
d650751a9b | ||
|
|
dcb0c5ac44 | ||
|
|
2c892f1aa1 | ||
|
|
46407182c7 | ||
|
|
a00d463bb9 | ||
|
|
d8fdd1e848 | ||
|
|
b8482d74a1 | ||
|
|
3cd9cac8fb | ||
|
|
70e6075d1d | ||
|
|
d71e9baa8b | ||
|
|
b41c6d34a4 | ||
|
|
9029d18d9b | ||
|
|
f81f504e12 | ||
|
|
021e35fba2 | ||
|
|
7112841ade | ||
|
|
940f4df57b | ||
|
|
46c906b6d1 | ||
|
|
9dc3736a7f | ||
|
|
8b3cbf12a2 | ||
|
|
dfa07417ff | ||
|
|
5c1c96c579 | ||
|
|
83f269b088 | ||
|
|
597d350e4a | ||
|
|
7fc4d5025b | ||
|
|
bd9e2feb2a | ||
|
|
814ed5011f | ||
|
|
f8faf2b33d | ||
|
|
3cb0b3fd52 | ||
|
|
edb1aaa8dc | ||
|
|
f3271942dd | ||
|
|
040f73a7c7 | ||
|
|
35283f89c6 | ||
|
|
1c4c845e79 | ||
|
|
2a374b5df0 | ||
|
|
7878754030 | ||
|
|
da5aa114e2 | ||
|
|
625f64a126 | ||
|
|
ba344d9494 | ||
|
|
976e29343d | ||
|
|
b3da63d59d | ||
|
|
902ba3fd33 | ||
|
|
cf3fc46ea8 | ||
|
|
6a1615c263 | ||
|
|
e66d297441 | ||
|
|
632afdff45 | ||
|
|
6e706b38bd | ||
|
|
850293ba1c | ||
|
|
fb528063b2 | ||
|
|
97ada10bd8 | ||
|
|
9a35753b42 | ||
|
|
c4af2093cc | ||
|
|
1543a19f36 | ||
|
|
8b41602694 | ||
|
|
cecb299ac4 | ||
|
|
90e89264b9 | ||
|
|
f69cc97272 | ||
|
|
a6e9750c8a | ||
|
|
60bade6674 | ||
|
|
e13c1b7b85 | ||
|
|
1d8451ccaf | ||
|
|
fad6e249ea | ||
|
|
64f7fa917c | ||
|
|
240b8fa098 | ||
|
|
3756d20499 | ||
|
|
9e8b23289f | ||
|
|
902eca48e5 | ||
|
|
9f0d55c24a | ||
|
|
e53dd1c436 | ||
|
|
da790d6014 | ||
|
|
3d81b13b36 | ||
|
|
64bd9e074b | ||
|
|
53d473dd8e | ||
|
|
6d64d927a2 | ||
|
|
cd87f1568e | ||
|
|
c417a4cb6f | ||
|
|
fa21d33fff | ||
|
|
84cf76de9c | ||
|
|
2ef4fdac6c | ||
|
|
1d72c9c382 | ||
|
|
7930230b43 | ||
|
|
483a8c238f | ||
|
|
26cbe2384c | ||
|
|
cb4a430c8a | ||
|
|
f67d535cdb | ||
|
|
ef4785f065 | ||
|
|
9a424bea42 | ||
|
|
10e4311ad7 | ||
|
|
50febacba1 | ||
|
|
ef7d57fcec | ||
|
|
7e7a15321e | ||
|
|
77ac09c3eb | ||
|
|
40a08ef216 | ||
|
|
b6683d1aeb | ||
|
|
5247b0b0dc | ||
|
|
c2b01ad4f3 | ||
|
|
c4468dec74 | ||
|
|
40229b3ffd | ||
|
|
7f2d538c27 | ||
|
|
b7c162a433 | ||
|
|
36c26f12f1 | ||
|
|
22d5d40493 | ||
|
|
17c26b7da6 | ||
|
|
e287979374 | ||
|
|
552af3d963 | ||
|
|
c772c9cbde | ||
|
|
031a38cceb | ||
|
|
6ff5062480 | ||
|
|
fdff85e63e | ||
|
|
5c7661fd5e | ||
|
|
1feb21b081 | ||
|
|
fa8cb316fb | ||
|
|
f72fe00e70 | ||
|
|
583bddce6b | ||
|
|
a52fb86a96 | ||
|
|
e5dbc1a96f | ||
|
|
96333403ca | ||
|
|
928f2fc146 | ||
|
|
8fd8b5bb46 | ||
|
|
b999e8f2c1 | ||
|
|
c6c86a53f2 | ||
|
|
c69f0d12f3 | ||
|
|
033ad7ee78 | ||
|
|
397db2175d | ||
|
|
6756bdc96e | ||
|
|
9c1ae55dbd | ||
|
|
091f073ff0 | ||
|
|
ad51a528dc | ||
|
|
fa29cc01ff | ||
|
|
a2bec08412 | ||
|
|
080fd68e9c | ||
|
|
437f57042c | ||
|
|
f4f271b068 | ||
|
|
bd35a43bb3 | ||
|
|
d91f681d3b | ||
|
|
1e51491d05 | ||
|
|
37440e95d1 | ||
|
|
681f2f9291 | ||
|
|
0e4638ec14 | ||
|
|
234a45a128 | ||
|
|
8687395198 | ||
|
|
0cccc9ff28 | ||
|
|
b50eb28758 | ||
|
|
8d936a1570 | ||
|
|
2c8602eb54 | ||
|
|
1ef23426e7 | ||
|
|
d2100072b9 | ||
|
|
f3edca46e5 | ||
|
|
cabb077325 | ||
|
|
b95b281039 | ||
|
|
5033d7177e | ||
|
|
49058f8c6f | ||
|
|
8b20ffa4b9 | ||
|
|
1b1e30679f | ||
|
|
e7a82fc033 | ||
|
|
7c5583ab2d | ||
|
|
0d9d85e345 | ||
|
|
c8c4edf4c9 | ||
|
|
23983fd75b | ||
|
|
4bbdefdce1 | ||
|
|
5bc09e54fa | ||
|
|
9f61b5b95c | ||
|
|
baa3268b13 | ||
|
|
f5599ef856 | ||
|
|
99c65fed78 | ||
|
|
e9adfa851f | ||
|
|
8363b8d4e6 | ||
|
|
f892b464d0 | ||
|
|
a4132d1590 | ||
|
|
303916a126 | ||
|
|
8eea7ed8e8 | ||
|
|
fa030ffd20 | ||
|
|
ea06bc30fa | ||
|
|
531ac0e65f | ||
|
|
e35cb347ce | ||
|
|
68fa3f0b57 | ||
|
|
1c145f0fda | ||
|
|
418c07226a | ||
|
|
5ec0ba6530 | ||
|
|
600ba1c5e1 | ||
|
|
aa73e35dc3 | ||
|
|
dca6176410 | ||
|
|
6f88f26945 | ||
|
|
f7af143516 | ||
|
|
4f3c7b3e13 | ||
|
|
b85e83f6cb | ||
|
|
33d1fbea57 | ||
|
|
b234d12c97 | ||
|
|
7a1d185108 | ||
|
|
76d5bb6a13 | ||
|
|
c42bfcbf0e | ||
|
|
c2fc7c15a3 | ||
|
|
4060a65222 | ||
|
|
a26f6b1375 | ||
|
|
6e686c26fa | ||
|
|
ab067ed371 | ||
|
|
9b69fbe4d1 | ||
|
|
04d8fc50ab | ||
|
|
ceff1e0363 | ||
|
|
d28acc595f | ||
|
|
9ef191ea7d | ||
|
|
1add860402 | ||
|
|
c658f21738 | ||
|
|
9f519af7f4 | ||
|
|
b7bdc604ef | ||
|
|
354dd9844e | ||
|
|
9b91dce691 | ||
|
|
83535cb2bf | ||
|
|
3f05b513d4 | ||
|
|
0d0d05de08 | ||
|
|
44409068f7 | ||
|
|
16ecc53e73 | ||
|
|
38f66776db | ||
|
|
e9d33df74d | ||
|
|
05b515de7d | ||
|
|
c2bbeaa900 | ||
|
|
799d153f41 | ||
|
|
69ff3960eb | ||
|
|
b91f53ec5f | ||
|
|
dd8f1bdd45 | ||
|
|
3720f31852 | ||
|
|
c51c492a65 | ||
|
|
d3e68e036e | ||
|
|
6ce8910d4d | ||
|
|
79b1d813f9 | ||
|
|
26954e103d | ||
|
|
c8c02fca3a | ||
|
|
0e2f5f9615 | ||
|
|
b539321838 | ||
|
|
0f15f88443 | ||
|
|
bada95a5f3 | ||
|
|
fb929625dc | ||
|
|
1a828b3d58 | ||
|
|
330f4683e2 | ||
|
|
2ef7f5607c | ||
|
|
4da243c179 | ||
|
|
4d8fc6d438 | ||
|
|
6d4abdda08 | ||
|
|
67ab4c0f82 | ||
|
|
df45cf7a3e | ||
|
|
4438972ccc | ||
|
|
09cd9ff2db | ||
|
|
e7d860d2fc | ||
|
|
ff3d2702d8 | ||
|
|
44f9712f79 | ||
|
|
fe4cb796df | ||
|
|
15de8ad80d | ||
|
|
d7a137510a | ||
|
|
91e4f27dd7 | ||
|
|
1339ef70a3 | ||
|
|
c204e3d610 | ||
|
|
32d0a03332 | ||
|
|
05346cfd90 | ||
|
|
a7a32b899c | ||
|
|
68a051f2d2 | ||
|
|
8e80367637 | ||
|
|
9a5adecc62 | ||
|
|
b923d0e3c6 | ||
|
|
f02e248ae1 | ||
|
|
e152510d72 | ||
|
|
59ac1946b0 | ||
|
|
5150a4a0fb | ||
|
|
2a25957df6 | ||
|
|
e441f55089 | ||
|
|
beb9f88080 | ||
|
|
c7b5116f71 | ||
|
|
2b0cd55bf5 | ||
|
|
188276ca5f | ||
|
|
87c4984da8 | ||
|
|
a5611ba6e8 | ||
|
|
c6e01425b6 | ||
|
|
58e3a8fac1 | ||
|
|
1b27702c14 | ||
|
|
39cf9fc90f | ||
|
|
bc4a6e9709 | ||
|
|
4a50ceb043 | ||
|
|
4d86cae4f0 | ||
|
|
33b374395f | ||
|
|
ade4409352 | ||
|
|
2f9abb2a26 | ||
|
|
fca60960ea | ||
|
|
0db22b01a1 | ||
|
|
807b9d7be1 | ||
|
|
a3d02f9ab4 | ||
|
|
54aac21f7e | ||
|
|
d8dd0beb98 | ||
|
|
e94f57a9ab | ||
|
|
bda436be4a | ||
|
|
a30df5c09f | ||
|
|
e776bf7ec7 | ||
|
|
46688687d5 | ||
|
|
19cbbd8f52 | ||
|
|
c87b3a6065 | ||
|
|
4c55ba2b19 | ||
|
|
104006a054 | ||
|
|
bf83a95dee | ||
|
|
732f598282 | ||
|
|
de3c5a17cb | ||
|
|
1a8a75037b |
30
.github/actions/build-selftests/action.yml
vendored
Normal file
30
.github/actions/build-selftests/action.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: 'build-selftests'
|
||||||
|
description: 'Build BPF selftests'
|
||||||
|
inputs:
|
||||||
|
repo-path:
|
||||||
|
description: 'where is the source code'
|
||||||
|
required: true
|
||||||
|
kernel:
|
||||||
|
description: 'kernel version or LATEST'
|
||||||
|
required: true
|
||||||
|
default: 'LATEST'
|
||||||
|
vmlinux:
|
||||||
|
description: 'where is vmlinux file'
|
||||||
|
required: true
|
||||||
|
default: '${{ github.workspace }}/vmlinux'
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::Setup Env"
|
||||||
|
sudo apt-get install -y qemu-kvm zstd binutils-dev elfutils libcap-dev libelf-dev libdw-dev python3-docutils
|
||||||
|
echo "::endgroup::"
|
||||||
|
- shell: bash
|
||||||
|
run: |
|
||||||
|
export KERNEL=${{ inputs.kernel }}
|
||||||
|
export REPO_ROOT="${{ github.workspace }}"
|
||||||
|
export REPO_PATH="${{ inputs.repo-path }}"
|
||||||
|
export VMLINUX_BTF="${{ inputs.vmlinux }}"
|
||||||
|
${{ github.action_path }}/build_selftests.sh
|
||||||
42
.github/actions/build-selftests/build_selftests.sh
vendored
Executable file
42
.github/actions/build-selftests/build_selftests.sh
vendored
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
THISDIR="$(cd $(dirname $0) && pwd)"
|
||||||
|
|
||||||
|
source ${THISDIR}/helpers.sh
|
||||||
|
|
||||||
|
foldable start prepare_selftests "Building selftests"
|
||||||
|
|
||||||
|
LLVM_VER=16
|
||||||
|
LIBBPF_PATH="${REPO_ROOT}"
|
||||||
|
|
||||||
|
PREPARE_SELFTESTS_SCRIPT=${THISDIR}/prepare_selftests-${KERNEL}.sh
|
||||||
|
if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then
|
||||||
|
(cd "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT})
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||||
|
VMLINUX_H=
|
||||||
|
else
|
||||||
|
VMLINUX_H=${THISDIR}/vmlinux.h
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ${REPO_ROOT}/${REPO_PATH}
|
||||||
|
make \
|
||||||
|
CLANG=clang-${LLVM_VER} \
|
||||||
|
LLC=llc-${LLVM_VER} \
|
||||||
|
LLVM_STRIP=llvm-strip-${LLVM_VER} \
|
||||||
|
VMLINUX_BTF="${VMLINUX_BTF}" \
|
||||||
|
VMLINUX_H=${VMLINUX_H} \
|
||||||
|
-C "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
|
||||||
|
-j $((4*$(nproc))) > /dev/null
|
||||||
|
cd -
|
||||||
|
mkdir ${LIBBPF_PATH}/selftests
|
||||||
|
cp -R "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
|
||||||
|
${LIBBPF_PATH}/selftests
|
||||||
|
cd ${LIBBPF_PATH}
|
||||||
|
rm selftests/bpf/.gitignore
|
||||||
|
git add selftests
|
||||||
|
|
||||||
|
foldable end prepare_selftests
|
||||||
36
.github/actions/build-selftests/helpers.sh
vendored
Normal file
36
.github/actions/build-selftests/helpers.sh
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# $1 - start or end
|
||||||
|
# $2 - fold identifier, no spaces
|
||||||
|
# $3 - fold section description
|
||||||
|
foldable() {
|
||||||
|
local YELLOW='\033[1;33m'
|
||||||
|
local NOCOLOR='\033[0m'
|
||||||
|
if [ $1 = "start" ]; then
|
||||||
|
line="::group::$2"
|
||||||
|
if [ ! -z "${3:-}" ]; then
|
||||||
|
line="$line - ${YELLOW}$3${NOCOLOR}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
line="::endgroup::"
|
||||||
|
fi
|
||||||
|
echo -e "$line"
|
||||||
|
}
|
||||||
|
|
||||||
|
__print() {
|
||||||
|
local TITLE=""
|
||||||
|
if [[ -n $2 ]]; then
|
||||||
|
TITLE=" title=$2"
|
||||||
|
fi
|
||||||
|
echo "::$1${TITLE}::$3"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - title
|
||||||
|
# $2 - message
|
||||||
|
print_error() {
|
||||||
|
__print error $1 $2
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - title
|
||||||
|
# $2 - message
|
||||||
|
print_notice() {
|
||||||
|
__print notice $1 $2
|
||||||
|
}
|
||||||
3
.github/actions/build-selftests/prepare_selftests-4.9.0.sh
vendored
Executable file
3
.github/actions/build-selftests/prepare_selftests-4.9.0.sh
vendored
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||||
3
.github/actions/build-selftests/prepare_selftests-5.5.0.sh
vendored
Executable file
3
.github/actions/build-selftests/prepare_selftests-5.5.0.sh
vendored
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||||
93846
.github/actions/build-selftests/vmlinux.h
vendored
Normal file
93846
.github/actions/build-selftests/vmlinux.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
.github/actions/debian/action.yml
vendored
Normal file
16
.github/actions/debian/action.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: 'debian'
|
||||||
|
description: 'Build'
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
description: 'Run target'
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
source /tmp/ci_setup
|
||||||
|
bash -x $CI_ROOT/managers/debian.sh SETUP
|
||||||
|
bash -x $CI_ROOT/managers/debian.sh ${{ inputs.target }}
|
||||||
|
bash -x $CI_ROOT/managers/debian.sh CLEANUP
|
||||||
|
shell: bash
|
||||||
|
|
||||||
23
.github/actions/setup/action.yml
vendored
Normal file
23
.github/actions/setup/action.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: 'setup'
|
||||||
|
description: 'setup env, create /tmp/ci_setup'
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- id: variables
|
||||||
|
run: |
|
||||||
|
export REPO_ROOT=$GITHUB_WORKSPACE
|
||||||
|
export CI_ROOT=$REPO_ROOT/travis-ci
|
||||||
|
# this is somewhat ugly, but that is the easiest way to share this code with
|
||||||
|
# arch specific docker
|
||||||
|
echo 'echo ::group::Env setup' > /tmp/ci_setup
|
||||||
|
echo export DEBIAN_FRONTEND=noninteractive >> /tmp/ci_setup
|
||||||
|
echo sudo apt-get update >> /tmp/ci_setup
|
||||||
|
echo sudo apt-get install -y aptitude qemu-kvm zstd binutils-dev elfutils libcap-dev libelf-dev libdw-dev libguestfs-tools >> /tmp/ci_setup
|
||||||
|
echo export PROJECT_NAME='libbpf' >> /tmp/ci_setup
|
||||||
|
echo export AUTHOR_EMAIL="$(git log -1 --pretty=\"%aE\")" >> /tmp/ci_setup
|
||||||
|
echo export REPO_ROOT=$GITHUB_WORKSPACE >> /tmp/ci_setup
|
||||||
|
echo export CI_ROOT=$REPO_ROOT/travis-ci >> /tmp/ci_setup
|
||||||
|
echo export VMTEST_ROOT=$CI_ROOT/vmtest >> /tmp/ci_setup
|
||||||
|
echo 'echo ::endgroup::' >> /tmp/ci_setup
|
||||||
|
shell: bash
|
||||||
|
|
||||||
89
.github/actions/vmtest/action.yml
vendored
Normal file
89
.github/actions/vmtest/action.yml
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
name: 'vmtest'
|
||||||
|
description: 'Build + run vmtest'
|
||||||
|
inputs:
|
||||||
|
kernel:
|
||||||
|
description: 'kernel version or LATEST'
|
||||||
|
required: true
|
||||||
|
default: 'LATEST'
|
||||||
|
arch:
|
||||||
|
description: 'what arch to test'
|
||||||
|
required: true
|
||||||
|
default: 'x86_64'
|
||||||
|
pahole:
|
||||||
|
description: 'pahole rev or master'
|
||||||
|
required: true
|
||||||
|
default: 'master'
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
# setup environment
|
||||||
|
- name: Setup environment
|
||||||
|
uses: libbpf/ci/setup-build-env@master
|
||||||
|
with:
|
||||||
|
pahole: ${{ inputs.pahole }}
|
||||||
|
# 1. download CHECKPOINT kernel source
|
||||||
|
- name: Get checkpoint commit
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cat CHECKPOINT-COMMIT
|
||||||
|
echo "CHECKPOINT=$(cat CHECKPOINT-COMMIT)" >> $GITHUB_ENV
|
||||||
|
- name: Get kernel source at checkpoint
|
||||||
|
uses: libbpf/ci/get-linux-source@master
|
||||||
|
with:
|
||||||
|
repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git'
|
||||||
|
rev: ${{ env.CHECKPOINT }}
|
||||||
|
dest: '${{ github.workspace }}/.kernel'
|
||||||
|
- name: Patch kernel source
|
||||||
|
uses: libbpf/ci/patch-kernel@master
|
||||||
|
with:
|
||||||
|
patches-root: '${{ github.workspace }}/travis-ci/diffs'
|
||||||
|
repo-root: '.kernel'
|
||||||
|
- name: Prepare to build BPF selftests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::Prepare building selftest"
|
||||||
|
cd .kernel
|
||||||
|
cat tools/testing/selftests/bpf/config \
|
||||||
|
tools/testing/selftests/bpf/config.${{ inputs.arch }} > .config
|
||||||
|
make olddefconfig && make prepare
|
||||||
|
cd -
|
||||||
|
echo "::endgroup::"
|
||||||
|
# 2. if kernel == LATEST, build kernel image from tree
|
||||||
|
- name: Build kernel image
|
||||||
|
if: ${{ inputs.kernel == 'LATEST' }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "::group::Build Kernel Image"
|
||||||
|
cd .kernel
|
||||||
|
make -j $((4*$(nproc))) all > /dev/null
|
||||||
|
cp vmlinux ${{ github.workspace }}
|
||||||
|
cd -
|
||||||
|
echo "::endgroup::"
|
||||||
|
# else, just download prebuilt kernel image
|
||||||
|
- name: Download prebuilt kernel
|
||||||
|
if: ${{ inputs.kernel != 'LATEST' }}
|
||||||
|
uses: libbpf/ci/download-vmlinux@master
|
||||||
|
with:
|
||||||
|
kernel: ${{ inputs.kernel }}
|
||||||
|
arch: ${{ inputs.arch }}
|
||||||
|
# 3. build selftests
|
||||||
|
- name: Build BPF selftests
|
||||||
|
uses: ./.github/actions/build-selftests
|
||||||
|
with:
|
||||||
|
repo-path: '.kernel'
|
||||||
|
kernel: ${{ inputs.kernel }}
|
||||||
|
# 4. prepare rootfs
|
||||||
|
- name: prepare rootfs
|
||||||
|
uses: libbpf/ci/prepare-rootfs@master
|
||||||
|
with:
|
||||||
|
kernel: ${{ inputs.kernel }}
|
||||||
|
project-name: 'libbpf'
|
||||||
|
arch: ${{ inputs.arch }}
|
||||||
|
image-output: '/tmp/root.img'
|
||||||
|
# 5. run selftest in QEMU
|
||||||
|
- name: Run selftests
|
||||||
|
uses: libbpf/ci/run-qemu@master
|
||||||
|
with:
|
||||||
|
img: '/tmp/root.img'
|
||||||
|
vmlinuz: 'vmlinuz'
|
||||||
|
arch: ${{ inputs.arch }}
|
||||||
81
.github/workflows/build.yml
vendored
Normal file
81
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: libbpf-build
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 18 * * *'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-build-${{ github.head_ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
debian:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Debian Build (${{ matrix.name }})
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: default
|
||||||
|
target: RUN
|
||||||
|
- name: ASan+UBSan
|
||||||
|
target: RUN_ASAN
|
||||||
|
- name: clang
|
||||||
|
target: RUN_CLANG
|
||||||
|
- name: clang ASan+UBSan
|
||||||
|
target: RUN_CLANG_ASAN
|
||||||
|
- name: gcc-10
|
||||||
|
target: RUN_GCC10
|
||||||
|
- name: gcc-10 ASan+UBSan
|
||||||
|
target: RUN_GCC10_ASAN
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
name: Setup
|
||||||
|
- uses: ./.github/actions/debian
|
||||||
|
name: Build
|
||||||
|
with:
|
||||||
|
target: ${{ matrix.target }}
|
||||||
|
|
||||||
|
ubuntu:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Ubuntu Focal Build (${{ matrix.arch }})
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: aarch64
|
||||||
|
- arch: ppc64le
|
||||||
|
- arch: s390x
|
||||||
|
- arch: x86
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
name: Pre-Setup
|
||||||
|
- run: source /tmp/ci_setup && sudo -E $CI_ROOT/managers/ubuntu.sh
|
||||||
|
if: matrix.arch == 'x86'
|
||||||
|
name: Setup
|
||||||
|
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||||
|
name: Build in docker
|
||||||
|
if: matrix.arch != 'x86'
|
||||||
|
with:
|
||||||
|
distro:
|
||||||
|
ubuntu20.04
|
||||||
|
arch:
|
||||||
|
${{ matrix.arch }}
|
||||||
|
setup:
|
||||||
|
cp /tmp/ci_setup $GITHUB_WORKSPACE
|
||||||
|
dockerRunArgs: |
|
||||||
|
--volume "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}"
|
||||||
|
shell: /bin/bash
|
||||||
|
install: |
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
export TZ="America/Los_Angeles"
|
||||||
|
apt-get update -y
|
||||||
|
apt-get install -y tzdata build-essential sudo
|
||||||
|
run: source ${GITHUB_WORKSPACE}/ci_setup && $CI_ROOT/managers/ubuntu.sh
|
||||||
40
.github/workflows/cifuzz.yml
vendored
Normal file
40
.github/workflows/cifuzz.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
# https://google.github.io/oss-fuzz/getting-started/continuous-integration/
|
||||||
|
name: CIFuzz
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
Fuzzing:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'libbpf/libbpf'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
sanitizer: [address, undefined, memory]
|
||||||
|
steps:
|
||||||
|
- name: Build Fuzzers (${{ matrix.sanitizer }})
|
||||||
|
id: build
|
||||||
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||||
|
with:
|
||||||
|
oss-fuzz-project-name: 'libbpf'
|
||||||
|
dry-run: false
|
||||||
|
allowed-broken-targets-percentage: 0
|
||||||
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
|
- name: Run Fuzzers (${{ matrix.sanitizer }})
|
||||||
|
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||||
|
with:
|
||||||
|
oss-fuzz-project-name: 'libbpf'
|
||||||
|
fuzz-seconds: 300
|
||||||
|
dry-run: false
|
||||||
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
|
- name: Upload Crash
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
if: failure() && steps.build.outcome == 'success'
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.sanitizer }}-artifacts
|
||||||
|
path: ./out/artifacts
|
||||||
31
.github/workflows/coverity.yml
vendored
Normal file
31
.github/workflows/coverity.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
name: libbpf-ci-coverity
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 18 * * *'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
coverity:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'libbpf/libbpf'
|
||||||
|
name: Coverity
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- name: Run coverity
|
||||||
|
run: |
|
||||||
|
echo ::group::Setup CI env
|
||||||
|
source /tmp/ci_setup
|
||||||
|
export COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
|
||||||
|
export COVERITY_SCAN_BRANCH_PATTERN=${GITHUB_REF##refs/*/}
|
||||||
|
export TRAVIS_BRANCH=${COVERITY_SCAN_BRANCH_PATTERN}
|
||||||
|
echo ::endgroup::
|
||||||
|
scripts/coverity.sh
|
||||||
|
env:
|
||||||
|
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
|
COVERITY_SCAN_PROJECT_NAME: libbpf
|
||||||
|
COVERITY_SCAN_BUILD_COMMAND_PREPEND: 'cd src/'
|
||||||
|
COVERITY_SCAN_BUILD_COMMAND: 'make'
|
||||||
|
- name: SCM log
|
||||||
|
run: cat /home/runner/work/libbpf/libbpf/src/cov-int/scm_log.txt
|
||||||
36
.github/workflows/ondemand.yml
vendored
Normal file
36
.github/workflows/ondemand.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: ondemand
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
kernel-origin:
|
||||||
|
description: 'git repo for linux kernel'
|
||||||
|
default: 'https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git'
|
||||||
|
required: true
|
||||||
|
kernel-rev:
|
||||||
|
description: 'rev/tag/branch for linux kernel'
|
||||||
|
default: "master"
|
||||||
|
required: true
|
||||||
|
pahole-origin:
|
||||||
|
description: 'git repo for pahole'
|
||||||
|
default: 'https://git.kernel.org/pub/scm/devel/pahole/pahole.git'
|
||||||
|
required: true
|
||||||
|
pahole-rev:
|
||||||
|
description: 'ref/tag/branch for pahole'
|
||||||
|
default: "master"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
vmtest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: vmtest with customized pahole/Kernel
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- uses: ./.github/actions/vmtest
|
||||||
|
with:
|
||||||
|
kernel: 'LATEST'
|
||||||
|
kernel-rev: ${{ github.event.inputs.kernel-rev }}
|
||||||
|
kernel-origin: ${{ github.event.inputs.kernel-origin }}
|
||||||
|
pahole: ${{ github.event.inputs.pahole-rev }}
|
||||||
|
pahole-origin: ${{ github.event.inputs.pahole-origin }}
|
||||||
20
.github/workflows/pahole.yml
vendored
Normal file
20
.github/workflows/pahole.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: pahole-staging
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 18 * * *'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
vmtest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Kernel LATEST + staging pahole
|
||||||
|
env:
|
||||||
|
STAGING: tmp.master
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
- uses: ./.github/actions/vmtest
|
||||||
|
with:
|
||||||
|
kernel: LATEST
|
||||||
|
pahole: $STAGING
|
||||||
42
.github/workflows/test.yml
vendored
Normal file
42
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: libbpf-ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 18 * * *'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-test-${{ github.head_ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
vmtest:
|
||||||
|
runs-on: ${{ matrix.runs_on }}
|
||||||
|
name: Kernel ${{ matrix.kernel }} on ${{ matrix.runs_on }} + selftests
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- kernel: 'LATEST'
|
||||||
|
runs_on: ubuntu-latest
|
||||||
|
arch: 'x86_64'
|
||||||
|
- kernel: '5.5.0'
|
||||||
|
runs_on: ubuntu-latest
|
||||||
|
arch: 'x86_64'
|
||||||
|
- kernel: '4.9.0'
|
||||||
|
runs_on: ubuntu-latest
|
||||||
|
arch: 'x86_64'
|
||||||
|
- kernel: 'LATEST'
|
||||||
|
runs_on: z15
|
||||||
|
arch: 's390x'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
name: Checkout
|
||||||
|
- uses: ./.github/actions/setup
|
||||||
|
name: Setup
|
||||||
|
- uses: ./.github/actions/vmtest
|
||||||
|
name: vmtest
|
||||||
|
with:
|
||||||
|
kernel: ${{ matrix.kernel }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
14
.lgtm.yml
Normal file
14
.lgtm.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# vi: set ts=2 sw=2:
|
||||||
|
extraction:
|
||||||
|
cpp:
|
||||||
|
prepare:
|
||||||
|
packages:
|
||||||
|
- libelf-dev
|
||||||
|
- pkg-config
|
||||||
|
after_prepare:
|
||||||
|
# As the buildsystem detection by LGTM is performed _only_ during the
|
||||||
|
# 'configure' phase, we need to trick LGTM we use a supported build
|
||||||
|
# system (configure, meson, cmake, etc.). This way LGTM correctly detects
|
||||||
|
# that our sources are in the src/ subfolder.
|
||||||
|
- touch src/configure
|
||||||
|
- chmod +x src/configure
|
||||||
22
.readthedocs.yaml
Normal file
22
.readthedocs.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# .readthedocs.yaml
|
||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
|
sphinx:
|
||||||
|
builder: html
|
||||||
|
configuration: docs/conf.py
|
||||||
|
|
||||||
|
formats:
|
||||||
|
- htmlzip
|
||||||
|
- pdf
|
||||||
|
- epub
|
||||||
|
|
||||||
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
|
python:
|
||||||
|
version: 3.7
|
||||||
|
install:
|
||||||
|
- requirements: docs/sphinx/requirements.txt
|
||||||
122
.travis.yml
122
.travis.yml
@@ -1,122 +0,0 @@
|
|||||||
sudo: required
|
|
||||||
dist: xenial
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
|
|
||||||
- CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
|
|
||||||
- REPO_ROOT="$TRAVIS_BUILD_DIR"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- stage: Build & test
|
|
||||||
name: Debian Testing
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Debian Testing (ASan+UBSan)
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN_ASAN
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Debian Testing (clang)
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN_CLANG
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Debian Testing (clang ASan+UBSan)
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN_CLANG_ASAN
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Debian Testing (gcc-8)
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN_GCC8
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Debian Testing (gcc-8 ASan+UBSan)
|
|
||||||
language: bash
|
|
||||||
env:
|
|
||||||
- DEBIAN_RELEASE="testing"
|
|
||||||
- CONT_NAME="libbpf-debian-$DEBIAN_RELEASE"
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
|
||||||
- docker --version
|
|
||||||
install:
|
|
||||||
- $CI_MANAGERS/debian.sh SETUP
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- $CI_MANAGERS/debian.sh RUN_GCC8_ASAN
|
|
||||||
- set +e
|
|
||||||
after_script:
|
|
||||||
- $CI_MANAGERS/debian.sh CLEANUP
|
|
||||||
|
|
||||||
- name: Ubuntu Xenial
|
|
||||||
language: bash
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- sudo $CI_MANAGERS/xenial.sh
|
|
||||||
- set +e
|
|
||||||
@@ -1 +1 @@
|
|||||||
1bd63524593b964934a33afd442df16b8f90e2b5
|
14b20b784f59bdd95f6f1cfb112c9818bcec4d84
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
02dc96ef6c25f990452c114c59d75c368a1f4c8f
|
e34cfee65ec891a319ce79797dda18083af33a76
|
||||||
|
|||||||
32
LICENSE.BSD-2-Clause
Normal file
32
LICENSE.BSD-2-Clause
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Valid-License-Identifier: BSD-2-Clause
|
||||||
|
SPDX-URL: https://spdx.org/licenses/BSD-2-Clause.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use the BSD 2-clause "Simplified" License put the following SPDX
|
||||||
|
tag/value pair into a comment according to the placement guidelines in
|
||||||
|
the licensing rules documentation:
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
Copyright (c) 2015 The Libbpf Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
503
LICENSE.LGPL-2.1
Normal file
503
LICENSE.LGPL-2.1
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
Valid-License-Identifier: LGPL-2.1
|
||||||
|
Valid-License-Identifier: LGPL-2.1+
|
||||||
|
SPDX-URL: https://spdx.org/licenses/LGPL-2.1.html
|
||||||
|
Usage-Guide:
|
||||||
|
To use this license in source code, put one of the following SPDX
|
||||||
|
tag/value pairs into a comment according to the placement
|
||||||
|
guidelines in the licensing rules documentation.
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 only' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1
|
||||||
|
For 'GNU Lesser General Public License (LGPL) version 2.1 or any later
|
||||||
|
version' use:
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
License-Text:
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts as
|
||||||
|
the successor of the GNU Library Public License, version 2, hence the
|
||||||
|
version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your freedom to
|
||||||
|
share and change it. By contrast, the GNU General Public Licenses are
|
||||||
|
intended to guarantee your freedom to share and change free software--to
|
||||||
|
make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some specially
|
||||||
|
designated software packages--typically libraries--of the Free Software
|
||||||
|
Foundation and other authors who decide to use it. You can use it too, but
|
||||||
|
we suggest you first think carefully about whether this license or the
|
||||||
|
ordinary General Public License is the better strategy to use in any
|
||||||
|
particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you have
|
||||||
|
the freedom to distribute copies of free software (and charge for this
|
||||||
|
service if you wish); that you receive source code or can get it if you
|
||||||
|
want it; that you can change the software and use pieces of it in new free
|
||||||
|
programs; and that you are informed that you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis or for
|
||||||
|
a fee, you must give the recipients all the rights that we gave you. You
|
||||||
|
must make sure that they, too, receive or can get the source code. If you
|
||||||
|
link other code with the library, you must provide complete object files to
|
||||||
|
the recipients, so that they can relink them with the library after making
|
||||||
|
changes to the library and recompiling it. And you must show them these
|
||||||
|
terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that there is no
|
||||||
|
warranty for the free library. Also, if the library is modified by someone
|
||||||
|
else and passed on, the recipients should know that what they have is not
|
||||||
|
the original version, so that the original author's reputation will not be
|
||||||
|
affected by problems that might be introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of any
|
||||||
|
free program. We wish to make sure that a company cannot effectively
|
||||||
|
restrict the users of a free program by obtaining a restrictive license
|
||||||
|
from a patent holder. Therefore, we insist that any patent license obtained
|
||||||
|
for a version of the library must be consistent with the full freedom of
|
||||||
|
use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary GNU
|
||||||
|
General Public License. This license, the GNU Lesser General Public
|
||||||
|
License, applies to certain designated libraries, and is quite different
|
||||||
|
from the ordinary General Public License. We use this license for certain
|
||||||
|
libraries in order to permit linking those libraries into non-free
|
||||||
|
programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using a
|
||||||
|
shared library, the combination of the two is legally speaking a combined
|
||||||
|
work, a derivative of the original library. The ordinary General Public
|
||||||
|
License therefore permits such linking only if the entire combination fits
|
||||||
|
its criteria of freedom. The Lesser General Public License permits more lax
|
||||||
|
criteria for linking other code with the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it does
|
||||||
|
Less to protect the user's freedom than the ordinary General Public
|
||||||
|
License. It also provides other free software developers Less of an
|
||||||
|
advantage over competing non-free programs. These disadvantages are the
|
||||||
|
reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to encourage
|
||||||
|
the widest possible use of a certain library, so that it becomes a de-facto
|
||||||
|
standard. To achieve this, non-free programs must be allowed to use the
|
||||||
|
library. A more frequent case is that a free library does the same job as
|
||||||
|
widely used non-free libraries. In this case, there is little to gain by
|
||||||
|
limiting the free library to free software only, so we use the Lesser
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free programs
|
||||||
|
enables a greater number of people to use a large body of free
|
||||||
|
software. For example, permission to use the GNU C Library in non-free
|
||||||
|
programs enables many more people to use the whole GNU operating system, as
|
||||||
|
well as its variant, the GNU/Linux operating system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the users'
|
||||||
|
freedom, it does ensure that the user of a program that is linked with the
|
||||||
|
Library has the freedom and the wherewithal to run that program using a
|
||||||
|
modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification
|
||||||
|
follow. Pay close attention to the difference between a "work based on the
|
||||||
|
library" and a "work that uses the library". The former contains code
|
||||||
|
derived from the library, whereas the latter must be combined with the
|
||||||
|
library in order to run.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other program
|
||||||
|
which contains a notice placed by the copyright holder or other
|
||||||
|
authorized party saying it may be distributed under the terms of this
|
||||||
|
Lesser General Public License (also called "this License"). Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work which
|
||||||
|
has been distributed under these terms. A "work based on the Library"
|
||||||
|
means either the Library or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Library or a portion of it, either
|
||||||
|
verbatim or with modifications and/or translated straightforwardly into
|
||||||
|
another language. (Hereinafter, translation is included without
|
||||||
|
limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for making
|
||||||
|
modifications to it. For a library, complete source code means all the
|
||||||
|
source code for all modules it contains, plus any associated interface
|
||||||
|
definition files, plus the scripts used to control compilation and
|
||||||
|
installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of running
|
||||||
|
a program using the Library is not restricted, and output from such a
|
||||||
|
program is covered only if its contents constitute a work based on the
|
||||||
|
Library (independent of the use of the Library in a tool for writing
|
||||||
|
it). Whether that is true depends on what the Library does and what the
|
||||||
|
program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's complete
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||||
|
that refer to this License and to the absence of any warranty; and
|
||||||
|
distribute a copy of this License along with the Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion of it,
|
||||||
|
thus forming a work based on the Library, and copy and distribute such
|
||||||
|
modifications or work under the terms of Section 1 above, provided that
|
||||||
|
you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices stating
|
||||||
|
that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no charge to
|
||||||
|
all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a table
|
||||||
|
of data to be supplied by an application program that uses the
|
||||||
|
facility, other than as an argument passed when the facility is
|
||||||
|
invoked, then you must make a good faith effort to ensure that, in
|
||||||
|
the event an application does not supply such function or table, the
|
||||||
|
facility still operates, and performs whatever part of its purpose
|
||||||
|
remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has a
|
||||||
|
purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must be
|
||||||
|
optional: if the application does not supply it, the square root
|
||||||
|
function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library, and
|
||||||
|
can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based on
|
||||||
|
the Library, the distribution of the whole must be on the terms of this
|
||||||
|
License, whose permissions for other licensees extend to the entire
|
||||||
|
whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of a
|
||||||
|
storage or distribution medium does not bring the other work under the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so that
|
||||||
|
they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in these
|
||||||
|
notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for that
|
||||||
|
copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of the
|
||||||
|
Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or derivative of
|
||||||
|
it, under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you accompany it with the
|
||||||
|
complete corresponding machine-readable source code, which must be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy from a
|
||||||
|
designated place, then offering equivalent access to copy the source
|
||||||
|
code from the same place satisfies the requirement to distribute the
|
||||||
|
source code, even though third parties are not compelled to copy the
|
||||||
|
source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the Library, but
|
||||||
|
is designed to work with the Library by being compiled or linked with
|
||||||
|
it, is called a "work that uses the Library". Such a work, in isolation,
|
||||||
|
is not a derivative work of the Library, and therefore falls outside the
|
||||||
|
scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library creates
|
||||||
|
an executable that is a derivative of the Library (because it contains
|
||||||
|
portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License. Section 6
|
||||||
|
states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is
|
||||||
|
not. Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data structure
|
||||||
|
layouts and accessors, and small macros and small inline functions (ten
|
||||||
|
lines or less in length), then the use of the object file is
|
||||||
|
unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section
|
||||||
|
6. Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or link a
|
||||||
|
"work that uses the Library" with the Library to produce a work
|
||||||
|
containing portions of the Library, and distribute that work under terms
|
||||||
|
of your choice, provided that the terms permit modification of the work
|
||||||
|
for the customer's own use and reverse engineering for debugging such
|
||||||
|
modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work during
|
||||||
|
execution displays copyright notices, you must include the copyright
|
||||||
|
notice for the Library among them, as well as a reference directing the
|
||||||
|
user to the copy of this License. Also, you must do one of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding machine-readable
|
||||||
|
source code for the Library including whatever changes were used in
|
||||||
|
the work (which must be distributed under Sections 1 and 2 above);
|
||||||
|
and, if the work is an executable linked with the Library, with the
|
||||||
|
complete machine-readable "work that uses the Library", as object
|
||||||
|
code and/or source code, so that the user can modify the Library and
|
||||||
|
then relink to produce a modified executable containing the modified
|
||||||
|
Library. (It is understood that the user who changes the contents of
|
||||||
|
definitions files in the Library will not necessarily be able to
|
||||||
|
recompile the application to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a copy
|
||||||
|
of the library already present on the user's computer system, rather
|
||||||
|
than copying library functions into the executable, and (2) will
|
||||||
|
operate properly with a modified version of the library, if the user
|
||||||
|
installs one, as long as the modified version is interface-compatible
|
||||||
|
with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at least three
|
||||||
|
years, to give the same user the materials specified in Subsection
|
||||||
|
6a, above, for a charge no more than the cost of performing this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy from a
|
||||||
|
designated place, offer equivalent access to copy the above specified
|
||||||
|
materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these materials
|
||||||
|
or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the Library"
|
||||||
|
must include any data and utility programs needed for reproducing the
|
||||||
|
executable from it. However, as a special exception, the materials to be
|
||||||
|
distributed need not include anything that is normally distributed (in
|
||||||
|
either source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable runs,
|
||||||
|
unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license restrictions
|
||||||
|
of other proprietary libraries that do not normally accompany the
|
||||||
|
operating system. Such a contradiction means you cannot use both them
|
||||||
|
and the Library together in an executable that you distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the Library
|
||||||
|
side-by-side in a single library together with other library facilities
|
||||||
|
not covered by this License, and distribute such a combined library,
|
||||||
|
provided that the separate distribution of the work based on the Library
|
||||||
|
and of the other library facilities is otherwise permitted, and provided
|
||||||
|
that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based on
|
||||||
|
the Library, uncombined with any other library facilities. This must
|
||||||
|
be distributed under the terms of the Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact that part
|
||||||
|
of it is a work based on the Library, and explaining where to find
|
||||||
|
the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||||
|
Library is void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights, from you
|
||||||
|
under this License will not have their licenses terminated so long as
|
||||||
|
such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not signed
|
||||||
|
it. However, nothing else grants you permission to modify or distribute
|
||||||
|
the Library or its derivative works. These actions are prohibited by law
|
||||||
|
if you do not accept this License. Therefore, by modifying or
|
||||||
|
distributing the Library (or any work based on the Library), you
|
||||||
|
indicate your acceptance of this License to do so, and all its terms and
|
||||||
|
conditions for copying, distributing or modifying the Library or works
|
||||||
|
based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted
|
||||||
|
herein. You are not responsible for enforcing compliance by third
|
||||||
|
parties with this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent license
|
||||||
|
would not permit royalty-free redistribution of the Library by all
|
||||||
|
those who receive copies directly or indirectly through you, then the
|
||||||
|
only way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply, and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is implemented
|
||||||
|
by public license practices. Many people have made generous
|
||||||
|
contributions to the wide range of software distributed through that
|
||||||
|
system in reliance on consistent application of that system; it is up
|
||||||
|
to the author/donor to decide if he or she is willing to distribute
|
||||||
|
software through any other system and a licensee cannot impose that
|
||||||
|
choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in certain
|
||||||
|
countries either by patents or by copyrighted interfaces, the original
|
||||||
|
copyright holder who places the Library under this License may add an
|
||||||
|
explicit geographical distribution limitation excluding those
|
||||||
|
countries, so that distribution is permitted only in or among countries
|
||||||
|
not thus excluded. In such case, this License incorporates the
|
||||||
|
limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the Lesser General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in
|
||||||
|
detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a license
|
||||||
|
version number, you may choose any version ever published by the Free
|
||||||
|
Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||||
|
guided by the two goals of preserving the free status of all
|
||||||
|
derivatives of our free software and of promoting the sharing and reuse
|
||||||
|
of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||||
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||||
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||||
|
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||||
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||||
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||||
|
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||||
|
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||||
|
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||||
|
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||||
|
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
one line to give the library's name and an idea of what it does.
|
||||||
|
Copyright (C) year name of author
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or (at
|
||||||
|
your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this library; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add
|
||||||
|
information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in
|
||||||
|
the library `Frob' (a library for tweaking knobs) written
|
||||||
|
by James Random Hacker.
|
||||||
|
|
||||||
|
signature of Ty Coon, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
That's all there is to it!
|
||||||
172
README.md
172
README.md
@@ -1,29 +1,62 @@
|
|||||||
|
<img src="https://user-images.githubusercontent.com/508075/185997470-2f427d3d-f040-4eef-afc5-ae4f766615b2.png" width="40%" >
|
||||||
|
|
||||||
This is a mirror of [bpf-next linux tree](https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next)'s
|
libbpf
|
||||||
`tools/lib/bpf` directory plus its supporting header files.
|
[](https://github.com/libbpf/libbpf/actions/workflows/test.yml)
|
||||||
|
[](https://lgtm.com/projects/g/libbpf/libbpf/alerts/)
|
||||||
|
[](https://scan.coverity.com/projects/libbpf)
|
||||||
|
[](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libbpf)
|
||||||
|
======
|
||||||
|
|
||||||
The following files will by sync'ed with bpf-next repo:
|
**This is the official home of the libbpf library.**
|
||||||
- `src/` <-> `bpf-next/tools/lib/bpf/`
|
|
||||||
- `include/uapi/linux/bpf_common.h` <-> `bpf-next/tools/include/uapi/linux/bpf_common.h`
|
|
||||||
- `include/uapi/linux/bpf.h` <-> `bpf-next/tools/include/uapi/linux/bpf.h`
|
|
||||||
- `include/uapi/linux/btf.h` <-> `bpf-next/tools/include/uapi/linux/btf.h`
|
|
||||||
- `include/uapi/linux/if_link.h` <-> `bpf-next/tools/include/uapi/linux/if_link.h`
|
|
||||||
- `include/uapi/linux/if_xdp.h` <-> `bpf-next/tools/include/uapi/linux/if_xdp.h`
|
|
||||||
- `include/uapi/linux/netlink.h` <-> `bpf-next/tools/include/uapi/linux/netlink.h`
|
|
||||||
- `include/tools/libc_compat.h` <-> `bpf-next/tools/include/tools/libc_compat.h`
|
|
||||||
|
|
||||||
Other header files at this repo (`include/linux/*.h`) are reduced versions of
|
*Please use this Github repository for building and packaging libbpf
|
||||||
their counterpart files at bpf-next's `tools/include/linux/*.h` to make compilation
|
and when using it in your projects through Git submodule.*
|
||||||
successful.
|
|
||||||
|
|
||||||
Build [](https://travis-ci.org/libbpf/libbpf)
|
Libbpf *authoritative source code* is developed as part of [bpf-next Linux source
|
||||||
=====
|
tree](https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next) under
|
||||||
|
`tools/lib/bpf` subdirectory and is periodically synced to Github. As such, all the
|
||||||
|
libbpf changes should be sent to [BPF mailing list](http://vger.kernel.org/vger-lists.html#bpf),
|
||||||
|
please don't open PRs here unless you are changing Github-specific parts of libbpf
|
||||||
|
(e.g., Github-specific Makefile).
|
||||||
|
|
||||||
|
Libbpf and general BPF usage questions
|
||||||
|
======================================
|
||||||
|
|
||||||
|
Libbpf documentation can be found [here](https://libbpf.readthedocs.io/en/latest/api.html).
|
||||||
|
It's an ongoing effort and has ways to go, but please take a look and consider contributing as well.
|
||||||
|
|
||||||
|
Please check out [libbpf-bootstrap](https://github.com/libbpf/libbpf-bootstrap)
|
||||||
|
and [the companion blog post](https://nakryiko.com/posts/libbpf-bootstrap/) for
|
||||||
|
the examples of building BPF applications with libbpf.
|
||||||
|
[libbpf-tools](https://github.com/iovisor/bcc/tree/master/libbpf-tools) are also
|
||||||
|
a good source of the real-world libbpf-based tracing tools.
|
||||||
|
|
||||||
|
See also ["BPF CO-RE reference guide"](https://nakryiko.com/posts/bpf-core-reference-guide/)
|
||||||
|
for the coverage of practical aspects of building BPF CO-RE applications and
|
||||||
|
["BPF CO-RE"](https://nakryiko.com/posts/bpf-portability-and-co-re/) for
|
||||||
|
general introduction into BPF portability issues and BPF CO-RE origins.
|
||||||
|
|
||||||
|
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||||
|
their application, should be sent to bpf@vger.kernel.org mailing list. You can
|
||||||
|
subscribe to it [here](http://vger.kernel.org/vger-lists.html#bpf) and search
|
||||||
|
its archive [here](https://lore.kernel.org/bpf/). Please search the archive
|
||||||
|
before asking new questions. It very well might be that this was already
|
||||||
|
addressed or answered before.
|
||||||
|
|
||||||
|
bpf@vger.kernel.org is monitored by many more people and they will happily try
|
||||||
|
to help you with whatever issue you have. This repository's PRs and issues
|
||||||
|
should be opened only for dealing with issues pertaining to specific way this
|
||||||
|
libbpf mirror repo is set up and organized.
|
||||||
|
|
||||||
|
Building libbpf
|
||||||
|
===============
|
||||||
libelf is an internal dependency of libbpf and thus it is required to link
|
libelf is an internal dependency of libbpf and thus it is required to link
|
||||||
against and must be installed on the system for applications to work.
|
against and must be installed on the system for applications to work.
|
||||||
pkg-config is used by default to find libelf, and the program called can be
|
pkg-config is used by default to find libelf, and the program called can be
|
||||||
overridden with `PKG_CONFIG`.
|
overridden with `PKG_CONFIG`.
|
||||||
If using `pkg-config` at build time is not desired, it can be disabled by setting
|
|
||||||
`NO_PKG_CONFIG=1` when calling make.
|
If using `pkg-config` at build time is not desired, it can be disabled by
|
||||||
|
setting `NO_PKG_CONFIG=1` when calling make.
|
||||||
|
|
||||||
To build both static libbpf.a and shared libbpf.so:
|
To build both static libbpf.a and shared libbpf.so:
|
||||||
```bash
|
```bash
|
||||||
@@ -47,3 +80,106 @@ headers in a build directory /build/root/:
|
|||||||
$ cd src
|
$ cd src
|
||||||
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make install
|
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
BPF CO-RE (Compile Once – Run Everywhere)
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
Libbpf supports building BPF CO-RE-enabled applications, which, in contrast to
|
||||||
|
[BCC](https://github.com/iovisor/bcc/), do not require Clang/LLVM runtime
|
||||||
|
being deployed to target servers and doesn't rely on kernel-devel headers
|
||||||
|
being available.
|
||||||
|
|
||||||
|
It does rely on kernel to be built with [BTF type
|
||||||
|
information](https://www.kernel.org/doc/html/latest/bpf/btf.html), though.
|
||||||
|
Some major Linux distributions come with kernel BTF already built in:
|
||||||
|
- Fedora 31+
|
||||||
|
- RHEL 8.2+
|
||||||
|
- OpenSUSE Tumbleweed (in the next release, as of 2020-06-04)
|
||||||
|
- Arch Linux (from kernel 5.7.1.arch1-1)
|
||||||
|
- Manjaro (from kernel 5.4 if compiled after 2021-06-18)
|
||||||
|
- Ubuntu 20.10
|
||||||
|
- Debian 11 (amd64/arm64)
|
||||||
|
|
||||||
|
If your kernel doesn't come with BTF built-in, you'll need to build custom
|
||||||
|
kernel. You'll need:
|
||||||
|
- `pahole` 1.16+ tool (part of `dwarves` package), which performs DWARF to
|
||||||
|
BTF conversion;
|
||||||
|
- kernel built with `CONFIG_DEBUG_INFO_BTF=y` option;
|
||||||
|
- you can check if your kernel has BTF built-in by looking for
|
||||||
|
`/sys/kernel/btf/vmlinux` file:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ ls -la /sys/kernel/btf/vmlinux
|
||||||
|
-r--r--r--. 1 root root 3541561 Jun 2 18:16 /sys/kernel/btf/vmlinux
|
||||||
|
```
|
||||||
|
|
||||||
|
To develop and build BPF programs, you'll need Clang/LLVM 10+. The following
|
||||||
|
distributions have Clang/LLVM 10+ packaged by default:
|
||||||
|
- Fedora 32+
|
||||||
|
- Ubuntu 20.04+
|
||||||
|
- Arch Linux
|
||||||
|
- Ubuntu 20.10 (LLVM 11)
|
||||||
|
- Debian 11 (LLVM 11)
|
||||||
|
- Alpine 3.13+
|
||||||
|
|
||||||
|
Otherwise, please make sure to update it on your system.
|
||||||
|
|
||||||
|
The following resources are useful to understand what BPF CO-RE is and how to
|
||||||
|
use it:
|
||||||
|
- [BPF CO-RE reference guide](https://nakryiko.com/posts/bpf-core-reference-guide/)
|
||||||
|
- [BPF Portability and CO-RE](https://nakryiko.com/posts/bpf-portability-and-co-re/)
|
||||||
|
- [HOWTO: BCC to libbpf conversion](https://nakryiko.com/posts/bcc-to-libbpf-howto-guide/)
|
||||||
|
- [libbpf-tools in BCC repo](https://github.com/iovisor/bcc/tree/master/libbpf-tools)
|
||||||
|
contain lots of real-world tools converted from BCC to BPF CO-RE. Consider
|
||||||
|
converting some more to both contribute to the BPF community and gain some
|
||||||
|
more experience with it.
|
||||||
|
|
||||||
|
Distributions
|
||||||
|
=============
|
||||||
|
|
||||||
|
Distributions packaging libbpf from this mirror:
|
||||||
|
- [Fedora](https://src.fedoraproject.org/rpms/libbpf)
|
||||||
|
- [Gentoo](https://packages.gentoo.org/packages/dev-libs/libbpf)
|
||||||
|
- [Debian](https://packages.debian.org/source/sid/libbpf)
|
||||||
|
- [Arch](https://www.archlinux.org/packages/extra/x86_64/libbpf/)
|
||||||
|
- [Ubuntu](https://packages.ubuntu.com/source/impish/libbpf)
|
||||||
|
- [Alpine](https://pkgs.alpinelinux.org/packages?name=libbpf)
|
||||||
|
|
||||||
|
Benefits of packaging from the mirror over packaging from kernel sources:
|
||||||
|
- Consistent versioning across distributions.
|
||||||
|
- No ties to any specific kernel, transparent handling of older kernels.
|
||||||
|
Libbpf is designed to be kernel-agnostic and work across multitude of
|
||||||
|
kernel versions. It has built-in mechanisms to gracefully handle older
|
||||||
|
kernels, that are missing some of the features, by working around or
|
||||||
|
gracefully degrading functionality. Thus libbpf is not tied to a specific
|
||||||
|
kernel version and can/should be packaged and versioned independently.
|
||||||
|
- Continuous integration testing via
|
||||||
|
[GitHub Actions](https://github.com/libbpf/libbpf/actions).
|
||||||
|
- Static code analysis via [LGTM](https://lgtm.com/projects/g/libbpf/libbpf)
|
||||||
|
and [Coverity](https://scan.coverity.com/projects/libbpf).
|
||||||
|
|
||||||
|
Package dependencies of libbpf, package names may vary across distros:
|
||||||
|
- zlib
|
||||||
|
- libelf
|
||||||
|
|
||||||
|
[](https://repology.org/project/libbpf/versions)
|
||||||
|
|
||||||
|
|
||||||
|
bpf-next to Github sync
|
||||||
|
=======================
|
||||||
|
|
||||||
|
All the gory details of syncing can be found in `scripts/sync-kernel.sh`
|
||||||
|
script.
|
||||||
|
|
||||||
|
Some header files in this repo (`include/linux/*.h`) are reduced versions of
|
||||||
|
their counterpart files at
|
||||||
|
[bpf-next](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/)'s
|
||||||
|
`tools/include/linux/*.h` to make compilation successful.
|
||||||
|
|
||||||
|
License
|
||||||
|
=======
|
||||||
|
|
||||||
|
This work is dual-licensed under BSD 2-clause license and GNU LGPL v2.1 license.
|
||||||
|
You can choose between one of them if you use this work.
|
||||||
|
|
||||||
|
`SPDX-License-Identifier: BSD-2-Clause OR LGPL-2.1`
|
||||||
|
|||||||
0
ci/diffs/.do_not_use_dot_patch_here
Normal file
0
ci/diffs/.do_not_use_dot_patch_here
Normal file
35
ci/diffs/001-fix-oob-write-in-test_verifier.diff
Normal file
35
ci/diffs/001-fix-oob-write-in-test_verifier.diff
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
||||||
|
To: bpf@vger.kernel.org
|
||||||
|
Cc: Alexei Starovoitov <ast@kernel.org>,
|
||||||
|
Daniel Borkmann <daniel@iogearbox.net>,
|
||||||
|
Andrii Nakryiko <andrii@kernel.org>
|
||||||
|
Subject: [PATCH bpf-next] selftests/bpf: Fix OOB write in test_verifier
|
||||||
|
Date: Tue, 14 Dec 2021 07:18:00 +0530 [thread overview]
|
||||||
|
Message-ID: <20211214014800.78762-1-memxor@gmail.com> (raw)
|
||||||
|
|
||||||
|
The commit referenced below added fixup_map_timer support (to create a
|
||||||
|
BPF map containing timers), but failed to increase the size of the
|
||||||
|
map_fds array, leading to out of bounds write. Fix this by changing
|
||||||
|
MAX_NR_MAPS to 22.
|
||||||
|
|
||||||
|
Fixes: e60e6962c503 ("selftests/bpf: Add tests for restricted helpers")
|
||||||
|
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
|
||||||
|
---
|
||||||
|
tools/testing/selftests/bpf/test_verifier.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
|
||||||
|
index ad5d30bafd93..33e2ecb3bef9 100644
|
||||||
|
--- a/tools/testing/selftests/bpf/test_verifier.c
|
||||||
|
+++ b/tools/testing/selftests/bpf/test_verifier.c
|
||||||
|
@@ -54,7 +54,7 @@
|
||||||
|
#define MAX_INSNS BPF_MAXINSNS
|
||||||
|
#define MAX_TEST_INSNS 1000000
|
||||||
|
#define MAX_FIXUPS 8
|
||||||
|
-#define MAX_NR_MAPS 21
|
||||||
|
+#define MAX_NR_MAPS 22
|
||||||
|
#define MAX_TEST_RUNS 8
|
||||||
|
#define POINTER_VALUE 0xcafe4all
|
||||||
|
#define TEST_DATA_LEN 64
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
@@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
|
PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
|
||||||
DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}"
|
DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}"
|
||||||
CONT_NAME="${CONT_NAME:-debian-$DEBIAN_RELEASE-$RANDOM}"
|
CONT_NAME="${CONT_NAME:-libbpf-debian-$DEBIAN_RELEASE}"
|
||||||
ENV_VARS="${ENV_VARS:-}"
|
ENV_VARS="${ENV_VARS:-}"
|
||||||
DOCKER_RUN="${DOCKER_RUN:-docker run}"
|
DOCKER_RUN="${DOCKER_RUN:-docker run}"
|
||||||
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||||
ADDITIONAL_DEPS=(clang pkg-config gcc-8)
|
ADDITIONAL_DEPS=(clang pkg-config gcc-10)
|
||||||
CFLAGS="-g -O2 -Werror -Wall"
|
EXTRA_CFLAGS=""
|
||||||
|
EXTRA_LDFLAGS=""
|
||||||
|
|
||||||
function info() {
|
function info() {
|
||||||
echo -e "\033[33;1m$1\033[0m"
|
echo -e "\033[33;1m$1\033[0m"
|
||||||
@@ -18,10 +19,10 @@ function error() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function docker_exec() {
|
function docker_exec() {
|
||||||
docker exec $ENV_VARS -it $CONT_NAME "$@"
|
docker exec $ENV_VARS $CONT_NAME "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
set -e
|
set -eu
|
||||||
|
|
||||||
source "$(dirname $0)/travis_wait.bash"
|
source "$(dirname $0)/travis_wait.bash"
|
||||||
|
|
||||||
@@ -30,32 +31,42 @@ for phase in "${PHASES[@]}"; do
|
|||||||
SETUP)
|
SETUP)
|
||||||
info "Setup phase"
|
info "Setup phase"
|
||||||
info "Using Debian $DEBIAN_RELEASE"
|
info "Using Debian $DEBIAN_RELEASE"
|
||||||
|
|
||||||
|
docker --version
|
||||||
|
|
||||||
docker pull debian:$DEBIAN_RELEASE
|
docker pull debian:$DEBIAN_RELEASE
|
||||||
info "Starting container $CONT_NAME"
|
info "Starting container $CONT_NAME"
|
||||||
$DOCKER_RUN -v $REPO_ROOT:/build:rw \
|
$DOCKER_RUN -v $REPO_ROOT:/build:rw \
|
||||||
-w /build --privileged=true --name $CONT_NAME \
|
-w /build --privileged=true --name $CONT_NAME \
|
||||||
-dit --net=host debian:$DEBIAN_RELEASE /bin/bash
|
-dit --net=host debian:$DEBIAN_RELEASE /bin/bash
|
||||||
|
echo -e "::group::Build Env Setup"
|
||||||
docker_exec bash -c "echo deb-src http://deb.debian.org/debian $DEBIAN_RELEASE main >>/etc/apt/sources.list"
|
docker_exec bash -c "echo deb-src http://deb.debian.org/debian $DEBIAN_RELEASE main >>/etc/apt/sources.list"
|
||||||
docker_exec apt-get -y update
|
docker_exec apt-get -y update
|
||||||
docker_exec apt-get -y build-dep libelf-dev
|
docker_exec apt-get -y install aptitude
|
||||||
docker_exec apt-get -y install libelf-dev
|
docker_exec aptitude -y build-dep libelf-dev
|
||||||
docker_exec apt-get -y install "${ADDITIONAL_DEPS[@]}"
|
docker_exec aptitude -y install libelf-dev
|
||||||
|
docker_exec aptitude -y install "${ADDITIONAL_DEPS[@]}"
|
||||||
|
echo -e "::endgroup::"
|
||||||
;;
|
;;
|
||||||
RUN|RUN_CLANG|RUN_GCC8|RUN_ASAN|RUN_CLANG_ASAN|RUN_GCC8_ASAN)
|
RUN|RUN_CLANG|RUN_GCC10|RUN_ASAN|RUN_CLANG_ASAN|RUN_GCC10_ASAN)
|
||||||
|
CC="cc"
|
||||||
if [[ "$phase" = *"CLANG"* ]]; then
|
if [[ "$phase" = *"CLANG"* ]]; then
|
||||||
ENV_VARS="-e CC=clang -e CXX=clang++"
|
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||||
CC="clang"
|
CC="clang"
|
||||||
elif [[ "$phase" = *"GCC8"* ]]; then
|
elif [[ "$phase" = *"GCC10"* ]]; then
|
||||||
ENV_VARS="-e CC=gcc-8 -e CXX=g++-8"
|
ENV_VARS="-e CC=gcc-10 -e CXX=g++-10"
|
||||||
CC="gcc-8"
|
CC="gcc-10"
|
||||||
|
else
|
||||||
|
EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-stringop-truncation"
|
||||||
fi
|
fi
|
||||||
if [[ "$phase" = *"ASAN"* ]]; then
|
if [[ "$phase" = *"ASAN"* ]]; then
|
||||||
CFLAGS="${CFLAGS} -fsanitize=address,undefined"
|
EXTRA_CFLAGS="${EXTRA_CFLAGS} -fsanitize=address,undefined"
|
||||||
|
EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -fsanitize=address,undefined"
|
||||||
fi
|
fi
|
||||||
docker_exec mkdir build install
|
docker_exec mkdir build install
|
||||||
docker_exec ${CC:-cc} --version
|
docker_exec ${CC} --version
|
||||||
info "build"
|
info "build"
|
||||||
docker_exec make CFLAGS="${CFLAGS}" -C ./src -B OBJDIR=../build
|
docker_exec make -j$((4*$(nproc))) EXTRA_CFLAGS="${EXTRA_CFLAGS}" EXTRA_LDFLAGS="${EXTRA_LDFLAGS}" -C ./src -B OBJDIR=../build
|
||||||
info "ldd build/libbpf.so:"
|
info "ldd build/libbpf.so:"
|
||||||
docker_exec ldd build/libbpf.so
|
docker_exec ldd build/libbpf.so
|
||||||
if ! docker_exec ldd build/libbpf.so | grep -q libelf; then
|
if ! docker_exec ldd build/libbpf.so | grep -q libelf; then
|
||||||
@@ -63,8 +74,9 @@ for phase in "${PHASES[@]}"; do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
info "install"
|
info "install"
|
||||||
docker_exec make -C src OBJDIR=../build DESTDIR=../install install
|
docker_exec make -j$((4*$(nproc))) -C src OBJDIR=../build DESTDIR=../install install
|
||||||
docker_exec rm -rf build install
|
info "link binary"
|
||||||
|
docker_exec bash -c "EXTRA_CFLAGS=\"${EXTRA_CFLAGS}\" EXTRA_LDFLAGS=\"${EXTRA_LDFLAGS}\" ./ci/managers/test_compile.sh"
|
||||||
;;
|
;;
|
||||||
CLEANUP)
|
CLEANUP)
|
||||||
info "Cleanup phase"
|
info "Cleanup phase"
|
||||||
15
ci/managers/test_compile.sh
Executable file
15
ci/managers/test_compile.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euox pipefail
|
||||||
|
|
||||||
|
EXTRA_CFLAGS=${EXTRA_CFLAGS:-}
|
||||||
|
EXTRA_LDFLAGS=${EXTRA_LDFLAGS:-}
|
||||||
|
|
||||||
|
cat << EOF > main.c
|
||||||
|
#include <bpf/libbpf.h>
|
||||||
|
int main() {
|
||||||
|
return bpf_object__open(0) < 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# static linking
|
||||||
|
${CC:-cc} ${EXTRA_CFLAGS} ${EXTRA_LDFLAGS} -o main -I./include/uapi -I./install/usr/include main.c ./build/libbpf.a -lelf -lz
|
||||||
24
ci/managers/ubuntu.sh
Executable file
24
ci/managers/ubuntu.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
RELEASE="focal"
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y pkg-config
|
||||||
|
|
||||||
|
source "$(dirname $0)/travis_wait.bash"
|
||||||
|
|
||||||
|
cd $REPO_ROOT
|
||||||
|
|
||||||
|
EXTRA_CFLAGS="-Werror -Wall -fsanitize=address,undefined"
|
||||||
|
EXTRA_LDFLAGS="-Werror -Wall -fsanitize=address,undefined"
|
||||||
|
mkdir build install
|
||||||
|
cc --version
|
||||||
|
make -j$((4*$(nproc))) EXTRA_CFLAGS="${EXTRA_CFLAGS}" EXTRA_LDFLAGS="${EXTRA_LDFLAGS}" -C ./src -B OBJDIR=../build
|
||||||
|
ldd build/libbpf.so
|
||||||
|
if ! ldd build/libbpf.so | grep -q libelf; then
|
||||||
|
echo "FAIL: No reference to libelf.so in libbpf.so!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
make -j$((4*$(nproc))) -C src OBJDIR=../build DESTDIR=../install install
|
||||||
|
EXTRA_CFLAGS=${EXTRA_CFLAGS} EXTRA_LDFLAGS=${EXTRA_LDFLAGS} $(dirname $0)/test_compile.sh
|
||||||
107
ci/rootfs/mkrootfs_arch.sh
Executable file
107
ci/rootfs/mkrootfs_arch.sh
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script is based on drgn script for generating Arch Linux bootstrap
|
||||||
|
# images.
|
||||||
|
# https://github.com/osandov/drgn/blob/master/scripts/vmtest/mkrootfs.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
USAGE_STRING="usage: $0 [NAME]
|
||||||
|
$0 -h
|
||||||
|
|
||||||
|
Build an Arch Linux root filesystem image for testing libbpf in a virtual
|
||||||
|
machine.
|
||||||
|
|
||||||
|
The image is generated as a zstd-compressed tarball.
|
||||||
|
|
||||||
|
This must be run as root, as most of the installation is done in a chroot.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
NAME name of generated image file (default:
|
||||||
|
libbpf-vmtest-rootfs-\$DATE.tar.zst)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h display this help message and exit"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
out)
|
||||||
|
echo "$USAGE_STRING"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
err)
|
||||||
|
echo "$USAGE_STRING" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts "h" OPT; do
|
||||||
|
case "$OPT" in
|
||||||
|
h)
|
||||||
|
usage out
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage err
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [[ $OPTIND -eq $# ]]; then
|
||||||
|
NAME="${!OPTIND}"
|
||||||
|
elif [[ $OPTIND -gt $# ]]; then
|
||||||
|
NAME="libbpf-vmtest-rootfs-$(date +%Y.%m.%d).tar.zst"
|
||||||
|
else
|
||||||
|
usage err
|
||||||
|
fi
|
||||||
|
|
||||||
|
pacman_conf=
|
||||||
|
root=
|
||||||
|
trap 'rm -rf "$pacman_conf" "$root"' EXIT
|
||||||
|
pacman_conf="$(mktemp -p "$PWD")"
|
||||||
|
cat > "$pacman_conf" << "EOF"
|
||||||
|
[options]
|
||||||
|
Architecture = x86_64
|
||||||
|
CheckSpace
|
||||||
|
SigLevel = Required DatabaseOptional
|
||||||
|
[core]
|
||||||
|
Include = /etc/pacman.d/mirrorlist
|
||||||
|
[extra]
|
||||||
|
Include = /etc/pacman.d/mirrorlist
|
||||||
|
[community]
|
||||||
|
Include = /etc/pacman.d/mirrorlist
|
||||||
|
EOF
|
||||||
|
root="$(mktemp -d -p "$PWD")"
|
||||||
|
|
||||||
|
packages=(
|
||||||
|
busybox
|
||||||
|
# libbpf dependencies.
|
||||||
|
libelf
|
||||||
|
zlib
|
||||||
|
# selftests test_progs dependencies.
|
||||||
|
binutils
|
||||||
|
elfutils
|
||||||
|
ethtool
|
||||||
|
glibc
|
||||||
|
iproute2
|
||||||
|
# selftests test_verifier dependencies.
|
||||||
|
libcap
|
||||||
|
)
|
||||||
|
|
||||||
|
pacstrap -C "$pacman_conf" -cGM "$root" "${packages[@]}"
|
||||||
|
|
||||||
|
# Remove unnecessary files from the chroot.
|
||||||
|
|
||||||
|
# We don't need the pacman databases anymore.
|
||||||
|
rm -rf "$root/var/lib/pacman/sync/"
|
||||||
|
# We don't need D, Fortran, or Go.
|
||||||
|
rm -f "$root/usr/lib/libgdruntime."* \
|
||||||
|
"$root/usr/lib/libgphobos."* \
|
||||||
|
"$root/usr/lib/libgfortran."* \
|
||||||
|
"$root/usr/lib/libgo."*
|
||||||
|
# We don't need any documentation.
|
||||||
|
rm -rf "$root/usr/share/{doc,help,man,texinfo}"
|
||||||
|
|
||||||
|
"$(dirname "$0")"/mkrootfs_tweak.sh "$root"
|
||||||
|
|
||||||
|
tar -C "$root" -c . | zstd -T0 -19 -o "$NAME"
|
||||||
|
chmod 644 "$NAME"
|
||||||
52
ci/rootfs/mkrootfs_debian.sh
Executable file
52
ci/rootfs/mkrootfs_debian.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script builds a Debian root filesystem image for testing libbpf in a
|
||||||
|
# virtual machine. Requires debootstrap >= 1.0.95 and zstd.
|
||||||
|
|
||||||
|
# Use e.g. ./mkrootfs_debian.sh --arch=s390x to generate a rootfs for a
|
||||||
|
# foreign architecture. Requires configured binfmt_misc, e.g. using
|
||||||
|
# Debian/Ubuntu's qemu-user-binfmt package or
|
||||||
|
# https://github.com/multiarch/qemu-user-static.
|
||||||
|
|
||||||
|
set -e -u -x -o pipefail
|
||||||
|
|
||||||
|
# Check whether we are root now in order to avoid confusing errors later.
|
||||||
|
if [ "$(id -u)" != 0 ]; then
|
||||||
|
echo "$0 must run as root" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a working directory and schedule its deletion.
|
||||||
|
root=$(mktemp -d -p "$PWD")
|
||||||
|
trap 'rm -r "$root"' EXIT
|
||||||
|
|
||||||
|
# Install packages.
|
||||||
|
packages=(
|
||||||
|
binutils
|
||||||
|
busybox
|
||||||
|
elfutils
|
||||||
|
ethtool
|
||||||
|
iproute2
|
||||||
|
iptables
|
||||||
|
libcap2
|
||||||
|
libelf1
|
||||||
|
strace
|
||||||
|
zlib1g
|
||||||
|
)
|
||||||
|
packages=$(IFS=, && echo "${packages[*]}")
|
||||||
|
debootstrap --include="$packages" --variant=minbase "$@" bookworm "$root"
|
||||||
|
|
||||||
|
# Remove the init scripts (tests use their own). Also remove various
|
||||||
|
# unnecessary files in order to save space.
|
||||||
|
rm -rf \
|
||||||
|
"$root"/etc/rcS.d \
|
||||||
|
"$root"/usr/share/{doc,info,locale,man,zoneinfo} \
|
||||||
|
"$root"/var/cache/apt/archives/* \
|
||||||
|
"$root"/var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Apply common tweaks.
|
||||||
|
"$(dirname "$0")"/mkrootfs_tweak.sh "$root"
|
||||||
|
|
||||||
|
# Save the result.
|
||||||
|
name="libbpf-vmtest-rootfs-$(date +%Y.%m.%d).tar.zst"
|
||||||
|
rm -f "$name"
|
||||||
|
tar -C "$root" -c . | zstd -T0 -19 -o "$name"
|
||||||
61
ci/rootfs/mkrootfs_tweak.sh
Executable file
61
ci/rootfs/mkrootfs_tweak.sh
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script prepares a mounted root filesystem for testing libbpf in a virtual
|
||||||
|
# machine.
|
||||||
|
set -e -u -x -o pipefail
|
||||||
|
root=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
chroot "${root}" /bin/busybox --install
|
||||||
|
|
||||||
|
cat > "$root/etc/inittab" << "EOF"
|
||||||
|
::sysinit:/etc/init.d/rcS
|
||||||
|
::ctrlaltdel:/sbin/reboot
|
||||||
|
::shutdown:/sbin/swapoff -a
|
||||||
|
::shutdown:/bin/umount -a -r
|
||||||
|
::restart:/sbin/init
|
||||||
|
EOF
|
||||||
|
chmod 644 "$root/etc/inittab"
|
||||||
|
|
||||||
|
mkdir -m 755 -p "$root/etc/init.d" "$root/etc/rcS.d"
|
||||||
|
cat > "$root/etc/rcS.d/S10-mount" << "EOF"
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
/bin/mount proc /proc -t proc
|
||||||
|
|
||||||
|
# Mount devtmpfs if not mounted
|
||||||
|
if [[ -z $(/bin/mount -t devtmpfs) ]]; then
|
||||||
|
/bin/mount devtmpfs /dev -t devtmpfs
|
||||||
|
fi
|
||||||
|
|
||||||
|
/bin/mount sysfs /sys -t sysfs
|
||||||
|
/bin/mount bpffs /sys/fs/bpf -t bpf
|
||||||
|
/bin/mount debugfs /sys/kernel/debug -t debugfs
|
||||||
|
|
||||||
|
echo 'Listing currently mounted file systems'
|
||||||
|
/bin/mount
|
||||||
|
EOF
|
||||||
|
chmod 755 "$root/etc/rcS.d/S10-mount"
|
||||||
|
|
||||||
|
cat > "$root/etc/rcS.d/S40-network" << "EOF"
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
ip link set lo up
|
||||||
|
EOF
|
||||||
|
chmod 755 "$root/etc/rcS.d/S40-network"
|
||||||
|
|
||||||
|
cat > "$root/etc/init.d/rcS" << "EOF"
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
for path in /etc/rcS.d/S*; do
|
||||||
|
[ -x "$path" ] && "$path"
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
chmod 755 "$root/etc/init.d/rcS"
|
||||||
|
|
||||||
|
chmod 755 "$root"
|
||||||
107
ci/rootfs/s390x-self-hosted-builder/README.md
Normal file
107
ci/rootfs/s390x-self-hosted-builder/README.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# IBM Z self-hosted builder
|
||||||
|
|
||||||
|
libbpf CI uses an IBM-provided z15 self-hosted builder. There are no IBM Z
|
||||||
|
builds of GitHub (GH) Actions runner, and stable qemu-user has problems with .NET
|
||||||
|
apps, so the builder runs the x86_64 runner version with qemu-user built from
|
||||||
|
the master branch.
|
||||||
|
|
||||||
|
We are currently supporting runners for the following repositories:
|
||||||
|
* libbpf/libbpf
|
||||||
|
* kernel-patches/bpf
|
||||||
|
* kernel-patches/vmtest
|
||||||
|
|
||||||
|
Below instructions are directly applicable to libbpf, and require minor
|
||||||
|
modifications for kernel-patches repos. Currently, qemu-user-static Docker
|
||||||
|
image is shared between all GitHub runners, but separate actions-runner-\*
|
||||||
|
service / Docker image is created for each runner type.
|
||||||
|
|
||||||
|
## Configuring the builder.
|
||||||
|
|
||||||
|
### Install prerequisites.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt install -y docker.io # Ubuntu
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add services.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo cp *.service /etc/systemd/system/
|
||||||
|
$ sudo systemctl daemon-reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create a config file.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo tee /etc/actions-runner-libbpf
|
||||||
|
repo=<owner>/<name>
|
||||||
|
access_token=<ghp_***>
|
||||||
|
```
|
||||||
|
|
||||||
|
Access token should have the repo scope, consult
|
||||||
|
https://docs.github.com/en/rest/reference/actions#create-a-registration-token-for-a-repository
|
||||||
|
for details.
|
||||||
|
|
||||||
|
### Autostart the x86_64 emulation support.
|
||||||
|
|
||||||
|
This step is important, you would not be able to build docker container
|
||||||
|
without having this service running. If container build fails, make sure
|
||||||
|
service is running properly.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl enable --now qemu-user-static
|
||||||
|
```
|
||||||
|
|
||||||
|
### Autostart the runner.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl enable --now actions-runner-libbpf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rebuilding the image
|
||||||
|
|
||||||
|
In order to update the `iiilinuxibmcom/actions-runner-libbpf` image, e.g. to
|
||||||
|
get the latest OS security fixes, use the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo docker build \
|
||||||
|
--pull \
|
||||||
|
-f actions-runner-libbpf.Dockerfile \
|
||||||
|
-t iiilinuxibmcom/actions-runner-libbpf \
|
||||||
|
.
|
||||||
|
$ sudo systemctl restart actions-runner-libbpf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Removing persistent data
|
||||||
|
|
||||||
|
The `actions-runner-libbpf` service stores various temporary data, such as
|
||||||
|
runner registration information, work directories and logs, in the
|
||||||
|
`actions-runner-libbpf` volume. In order to remove it and start from scratch,
|
||||||
|
e.g. when upgrading the runner or switching it to a different repository, use
|
||||||
|
the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl stop actions-runner-libbpf
|
||||||
|
$ sudo docker rm -f actions-runner-libbpf
|
||||||
|
$ sudo docker volume rm actions-runner-libbpf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
In order to check if service is running, use the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo systemctl status <service name>
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to get logs for service:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ journalctl -u <service name>
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to check which containers are currently active:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo docker ps
|
||||||
|
```
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Self-Hosted IBM Z Github Actions Runner.
|
||||||
|
|
||||||
|
# Temporary image: amd64 dependencies.
|
||||||
|
FROM amd64/ubuntu:20.04 as ld-prefix
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN apt-get update && apt-get -y install ca-certificates libicu66 libssl1.1
|
||||||
|
|
||||||
|
# Main image.
|
||||||
|
FROM s390x/ubuntu:20.04
|
||||||
|
|
||||||
|
# Packages for libbpf testing that are not installed by .github/actions/setup.
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
RUN apt-get update && apt-get -y install \
|
||||||
|
bc \
|
||||||
|
bison \
|
||||||
|
cmake \
|
||||||
|
cpu-checker \
|
||||||
|
curl \
|
||||||
|
flex \
|
||||||
|
git \
|
||||||
|
jq \
|
||||||
|
linux-image-generic \
|
||||||
|
qemu-system-s390x \
|
||||||
|
rsync \
|
||||||
|
software-properties-common \
|
||||||
|
sudo \
|
||||||
|
tree
|
||||||
|
|
||||||
|
# amd64 dependencies.
|
||||||
|
COPY --from=ld-prefix / /usr/x86_64-linux-gnu/
|
||||||
|
RUN ln -fs ../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /usr/x86_64-linux-gnu/lib64/
|
||||||
|
RUN ln -fs /etc/resolv.conf /usr/x86_64-linux-gnu/etc/
|
||||||
|
ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu
|
||||||
|
|
||||||
|
# amd64 Github Actions Runner.
|
||||||
|
ARG version=2.285.0
|
||||||
|
RUN useradd -m actions-runner
|
||||||
|
RUN echo "actions-runner ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
|
||||||
|
RUN echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >>/etc/sudoers
|
||||||
|
RUN usermod -a -G kvm actions-runner
|
||||||
|
USER actions-runner
|
||||||
|
ENV USER=actions-runner
|
||||||
|
WORKDIR /home/actions-runner
|
||||||
|
RUN curl -L https://github.com/actions/runner/releases/download/v${version}/actions-runner-linux-x64-${version}.tar.gz | tar -xz
|
||||||
|
VOLUME /home/actions-runner
|
||||||
|
|
||||||
|
# Scripts.
|
||||||
|
COPY fs/ /
|
||||||
|
ENTRYPOINT ["/usr/bin/entrypoint"]
|
||||||
|
CMD ["/usr/bin/actions-runner"]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Self-Hosted IBM Z Github Actions Runner
|
||||||
|
Wants=qemu-user-static
|
||||||
|
After=qemu-user-static
|
||||||
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Restart=always
|
||||||
|
ExecStart=/usr/bin/docker run \
|
||||||
|
--device=/dev/kvm \
|
||||||
|
--env-file=/etc/actions-runner-libbpf \
|
||||||
|
--init \
|
||||||
|
--interactive \
|
||||||
|
--name=actions-runner-libbpf \
|
||||||
|
--rm \
|
||||||
|
--volume=actions-runner-libbpf:/home/actions-runner \
|
||||||
|
iiilinuxibmcom/actions-runner-libbpf
|
||||||
|
ExecStop=/bin/sh -c "docker exec actions-runner-libbpf kill -INT -- -1"
|
||||||
|
ExecStop=/bin/sh -c "docker wait actions-runner-libbpf"
|
||||||
|
ExecStop=/bin/sh -c "docker rm actions-runner-libbpf"
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
40
ci/rootfs/s390x-self-hosted-builder/fs/usr/bin/actions-runner
Executable file
40
ci/rootfs/s390x-self-hosted-builder/fs/usr/bin/actions-runner
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ephemeral runner startup script.
|
||||||
|
#
|
||||||
|
# Expects the following environment variables:
|
||||||
|
#
|
||||||
|
# - repo=<owner>/<name>
|
||||||
|
# - access_token=<ghp_***>
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e -u
|
||||||
|
|
||||||
|
# Check the cached registration token.
|
||||||
|
token_file=registration-token.json
|
||||||
|
set +e
|
||||||
|
expires_at=$(jq --raw-output .expires_at "$token_file" 2>/dev/null)
|
||||||
|
status=$?
|
||||||
|
set -e
|
||||||
|
if [[ $status -ne 0 || $(date +%s) -ge $(date -d "$expires_at" +%s) ]]; then
|
||||||
|
# Refresh the cached registration token.
|
||||||
|
curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-H "Authorization: token $access_token" \
|
||||||
|
"https://api.github.com/repos/$repo/actions/runners/registration-token" \
|
||||||
|
-o "$token_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# (Re-)register the runner.
|
||||||
|
registration_token=$(jq --raw-output .token "$token_file")
|
||||||
|
./config.sh remove --token "$registration_token" || true
|
||||||
|
./config.sh \
|
||||||
|
--url "https://github.com/$repo" \
|
||||||
|
--token "$registration_token" \
|
||||||
|
--labels z15 \
|
||||||
|
--ephemeral
|
||||||
|
|
||||||
|
# Run one job.
|
||||||
|
./run.sh
|
||||||
35
ci/rootfs/s390x-self-hosted-builder/fs/usr/bin/entrypoint
Executable file
35
ci/rootfs/s390x-self-hosted-builder/fs/usr/bin/entrypoint
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Container entrypoint that waits for all spawned processes.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e -u
|
||||||
|
|
||||||
|
# /dev/kvm has host permissions, fix it.
|
||||||
|
if [ -e /dev/kvm ]; then
|
||||||
|
sudo chown root:kvm /dev/kvm
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a FIFO and start reading from its read end.
|
||||||
|
tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX")
|
||||||
|
trap 'rm -r "$tempdir"' EXIT
|
||||||
|
done="$tempdir/pipe"
|
||||||
|
mkfifo "$done"
|
||||||
|
cat "$done" & waiter=$!
|
||||||
|
|
||||||
|
# Start the workload. Its descendants will inherit the FIFO's write end.
|
||||||
|
status=0
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
bash 9>"$done" || status=$?
|
||||||
|
else
|
||||||
|
"$@" 9>"$done" || status=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# When the workload and all of its descendants exit, the FIFO's write end will
|
||||||
|
# be closed and `cat "$done"` will exit. Wait until it happens. This is needed
|
||||||
|
# in order to handle SelfUpdater, which the workload may start in background
|
||||||
|
# before exiting.
|
||||||
|
wait "$waiter"
|
||||||
|
|
||||||
|
exit "$status"
|
||||||
11
ci/rootfs/s390x-self-hosted-builder/qemu-user-static.service
Normal file
11
ci/rootfs/s390x-self-hosted-builder/qemu-user-static.service
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Support for transparent execution of non-native binaries with QEMU user emulation
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
# The source code for iiilinuxibmcom/qemu-user-static is at https://github.com/iii-i/qemu-user-static/tree/v6.1.0-1
|
||||||
|
# TODO: replace it with multiarch/qemu-user-static once version >6.1 is available
|
||||||
|
ExecStart=/usr/bin/docker run --rm --interactive --privileged iiilinuxibmcom/qemu-user-static --reset -p yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
8
ci/vmtest/configs/ALLOWLIST-4.9.0
Normal file
8
ci/vmtest/configs/ALLOWLIST-4.9.0
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# btf_dump -- need to disable data dump sub-tests
|
||||||
|
core_retro
|
||||||
|
cpu_mask
|
||||||
|
hashmap
|
||||||
|
legacy_printk
|
||||||
|
perf_buffer
|
||||||
|
section_names
|
||||||
|
|
||||||
55
ci/vmtest/configs/ALLOWLIST-5.5.0
Normal file
55
ci/vmtest/configs/ALLOWLIST-5.5.0
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# attach_probe
|
||||||
|
autoload
|
||||||
|
bpf_verif_scale
|
||||||
|
cgroup_attach_autodetach
|
||||||
|
cgroup_attach_override
|
||||||
|
core_autosize
|
||||||
|
core_extern
|
||||||
|
core_read_macros
|
||||||
|
core_reloc
|
||||||
|
core_retro
|
||||||
|
cpu_mask
|
||||||
|
endian
|
||||||
|
get_branch_snapshot
|
||||||
|
get_stackid_cannot_attach
|
||||||
|
global_data
|
||||||
|
global_data_init
|
||||||
|
global_func_args
|
||||||
|
hashmap
|
||||||
|
l4lb_all
|
||||||
|
legacy_printk
|
||||||
|
linked_funcs
|
||||||
|
linked_maps
|
||||||
|
map_lock
|
||||||
|
obj_name
|
||||||
|
perf_buffer
|
||||||
|
perf_event_stackmap
|
||||||
|
pinning
|
||||||
|
pkt_md_access
|
||||||
|
probe_user
|
||||||
|
queue_stack_map
|
||||||
|
raw_tp_writable_reject_nbd_invalid
|
||||||
|
raw_tp_writable_test_run
|
||||||
|
rdonly_maps
|
||||||
|
section_names
|
||||||
|
signal_pending
|
||||||
|
skeleton
|
||||||
|
sockmap_ktls
|
||||||
|
sockopt
|
||||||
|
sockopt_inherit
|
||||||
|
sockopt_multi
|
||||||
|
spinlock
|
||||||
|
stacktrace_map
|
||||||
|
stacktrace_map_raw_tp
|
||||||
|
static_linked
|
||||||
|
task_fd_query_rawtp
|
||||||
|
task_fd_query_tp
|
||||||
|
tc_bpf
|
||||||
|
tcp_estats
|
||||||
|
tcp_rtt
|
||||||
|
tp_attach_query
|
||||||
|
usdt/urand_pid_attach
|
||||||
|
xdp
|
||||||
|
xdp_info
|
||||||
|
xdp_noinline
|
||||||
|
xdp_perf
|
||||||
118
ci/vmtest/configs/DENYLIST-5.5.0
Normal file
118
ci/vmtest/configs/DENYLIST-5.5.0
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# This file is not used and is there for historic purposes only.
|
||||||
|
# See WHITELIST-5.5.0 instead.
|
||||||
|
|
||||||
|
# PERMANENTLY DISABLED
|
||||||
|
align # verifier output format changed
|
||||||
|
atomics # new atomic operations (v5.12+)
|
||||||
|
atomic_bounds # new atomic operations (v5.12+)
|
||||||
|
bind_perm # changed semantics of return values (v5.12+)
|
||||||
|
bpf_cookie # 5.15+
|
||||||
|
bpf_iter # bpf_iter support is missing
|
||||||
|
bpf_obj_id # bpf_link support missing for GET_OBJ_INFO, GET_FD_BY_ID, etc
|
||||||
|
bpf_tcp_ca # STRUCT_OPS is missing
|
||||||
|
btf_map_in_map # inner map leak fixed in 5.8
|
||||||
|
btf_skc_cls_ingress # v5.10+ functionality
|
||||||
|
cg_storage_multi # v5.9+ functionality
|
||||||
|
cgroup_attach_multi # BPF_F_REPLACE_PROG missing
|
||||||
|
cgroup_link # LINK_CREATE is missing
|
||||||
|
cgroup_skb_sk_lookup # bpf_sk_lookup_tcp() helper is missing
|
||||||
|
check_mtu # missing BPF helper (v5.12+)
|
||||||
|
cls_redirect # bpf_csum_level() helper is missing
|
||||||
|
connect_force_port # cgroup/get{peer,sock}name{4,6} support is missing
|
||||||
|
d_path # v5.10+ feature
|
||||||
|
enable_stats # BPF_ENABLE_STATS support is missing
|
||||||
|
fentry_fexit # bpf_prog_test_tracing missing
|
||||||
|
fentry_test # bpf_prog_test_tracing missing
|
||||||
|
fexit_bpf2bpf # freplace is missing
|
||||||
|
fexit_sleep # relies on bpf_trampoline fix in 5.12+
|
||||||
|
fexit_test # bpf_prog_test_tracing missing
|
||||||
|
flow_dissector # bpf_link-based flow dissector is in 5.8+
|
||||||
|
flow_dissector_reattach
|
||||||
|
for_each # v5.12+
|
||||||
|
get_func_ip_test # v5.15+
|
||||||
|
get_stack_raw_tp # exercising BPF verifier bug causing infinite loop
|
||||||
|
hash_large_key # v5.11+
|
||||||
|
ima # v5.11+
|
||||||
|
kfree_skb # 32-bit pointer arith in test_pkt_access
|
||||||
|
ksyms # __start_BTF has different name
|
||||||
|
kfunc_call # v5.13+
|
||||||
|
link_pinning # bpf_link is missing
|
||||||
|
linked_vars # v5.13+
|
||||||
|
load_bytes_relative # new functionality in 5.8
|
||||||
|
lookup_and_delete # v5.14+
|
||||||
|
map_init # per-CPU LRU missing
|
||||||
|
map_ptr # test uses BPF_MAP_TYPE_RINGBUF, added in 5.8
|
||||||
|
metadata # v5.10+
|
||||||
|
migrate_reuseport # v5.14+
|
||||||
|
mmap # 5.5 kernel is too permissive with re-mmaping
|
||||||
|
modify_return # fmod_ret support is missing
|
||||||
|
module_attach # module BTF support missing (v5.11+)
|
||||||
|
netcnt
|
||||||
|
netns_cookie # v5.15+
|
||||||
|
ns_current_pid_tgid # bpf_get_ns_current_pid_tgid() helper is missing
|
||||||
|
pe_preserve_elems # v5.10+
|
||||||
|
perf_branches # bpf_read_branch_records() helper is missing
|
||||||
|
perf_link # v5.15+
|
||||||
|
pkt_access # 32-bit pointer arith in test_pkt_access
|
||||||
|
probe_read_user_str # kernel bug with garbage bytes at the end
|
||||||
|
prog_run_xattr # 32-bit pointer arith in test_pkt_access
|
||||||
|
raw_tp_test_run # v5.10+
|
||||||
|
recursion # v5.12+
|
||||||
|
ringbuf # BPF_MAP_TYPE_RINGBUF is supported in 5.8+
|
||||||
|
|
||||||
|
# bug in verifier w/ tracking references
|
||||||
|
#reference_tracking/classifier/sk_lookup_success
|
||||||
|
reference_tracking
|
||||||
|
|
||||||
|
select_reuseport # UDP support is missing
|
||||||
|
send_signal # bpf_send_signal_thread() helper is missing
|
||||||
|
sk_assign # bpf_sk_assign helper missing
|
||||||
|
sk_lookup # v5.9+
|
||||||
|
sk_storage_tracing # missing bpf_sk_storage_get() helper
|
||||||
|
skb_ctx # ctx_{size, }_{in, out} in BPF_PROG_TEST_RUN is missing
|
||||||
|
skb_helpers # helpers added in 5.8+
|
||||||
|
skeleton # creates too big ARRAY map
|
||||||
|
snprintf # v5.13+
|
||||||
|
snprintf_btf # v5.10+
|
||||||
|
sock_fields # v5.10+
|
||||||
|
socket_cookie # v5.12+
|
||||||
|
sockmap_basic # uses new socket fields, 5.8+
|
||||||
|
sockmap_listen # no listen socket supportin SOCKMAP
|
||||||
|
sockopt_sk
|
||||||
|
sockopt_qos_to_cc # v5.15+
|
||||||
|
stacktrace_build_id # v5.9+
|
||||||
|
stack_var_off # v5.12+
|
||||||
|
syscall # v5.14+
|
||||||
|
task_local_storage # v5.12+
|
||||||
|
task_pt_regs # v5.15+
|
||||||
|
tcp_hdr_options # v5.10+, new TCP header options feature in BPF
|
||||||
|
tcpbpf_user # LINK_CREATE is missing
|
||||||
|
tc_redirect # v5.14+
|
||||||
|
test_bpffs # v5.10+, new CONFIG_BPF_PRELOAD=y and CONFIG_BPF_PRELOAD_UMG=y|m
|
||||||
|
test_bprm_opts # v5.11+
|
||||||
|
test_global_funcs # kernel doesn't support BTF linkage=global on FUNCs
|
||||||
|
test_local_storage # v5.10+ feature
|
||||||
|
test_lsm # no BPF_LSM support
|
||||||
|
test_overhead # no fmod_ret support
|
||||||
|
test_profiler # needs verifier logic improvements from v5.10+
|
||||||
|
test_skb_pkt_end # v5.11+
|
||||||
|
timer # v5.15+
|
||||||
|
timer_mim # v5.15+
|
||||||
|
trace_ext # v5.10+
|
||||||
|
trace_printk # v5.14+
|
||||||
|
trampoline_count # v5.12+ have lower allowed limits
|
||||||
|
udp_limit # no cgroup/sock_release BPF program type (5.9+)
|
||||||
|
varlen # verifier bug fixed in later kernels
|
||||||
|
vmlinux # hrtimer_nanosleep() signature changed incompatibly
|
||||||
|
xdp_adjust_tail # new XDP functionality added in 5.8
|
||||||
|
xdp_attach # IFLA_XDP_EXPECTED_FD support is missing
|
||||||
|
xdp_bonding # v5.15+
|
||||||
|
xdp_bpf2bpf # freplace is missing
|
||||||
|
xdp_context_test_run # v5.15+
|
||||||
|
xdp_cpumap_attach # v5.9+
|
||||||
|
xdp_devmap_attach # new feature in 5.8
|
||||||
|
xdp_link # v5.9+
|
||||||
|
|
||||||
|
# SUBTESTS FAILING (block entire test until blocking subtests works properly)
|
||||||
|
btf # "size check test", "func (Non zero vlen)"
|
||||||
|
tailcalls # tailcall_bpf2bpf_1, tailcall_bpf2bpf_2, tailcall_bpf2bpf_3
|
||||||
6
ci/vmtest/configs/DENYLIST-latest
Normal file
6
ci/vmtest/configs/DENYLIST-latest
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# TEMPORARY
|
||||||
|
get_stack_raw_tp # spams with kernel warnings until next bpf -> bpf-next merge
|
||||||
|
stacktrace_build_id_nmi
|
||||||
|
stacktrace_build_id
|
||||||
|
task_fd_query_rawtp
|
||||||
|
varlen
|
||||||
68
ci/vmtest/configs/DENYLIST-latest.s390x
Normal file
68
ci/vmtest/configs/DENYLIST-latest.s390x
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# TEMPORARY
|
||||||
|
atomics # attach(add): actual -524 <= expected 0 (trampoline)
|
||||||
|
bpf_iter_setsockopt # JIT does not support calling kernel function (kfunc)
|
||||||
|
bloom_filter_map # failed to find kernel BTF type ID of '__x64_sys_getpgid': -3 (?)
|
||||||
|
bpf_tcp_ca # JIT does not support calling kernel function (kfunc)
|
||||||
|
bpf_loop # attaches to __x64_sys_nanosleep
|
||||||
|
bpf_mod_race # BPF trampoline
|
||||||
|
bpf_nf # JIT does not support calling kernel function
|
||||||
|
core_read_macros # unknown func bpf_probe_read#4 (overlapping)
|
||||||
|
d_path # failed to auto-attach program 'prog_stat': -524 (trampoline)
|
||||||
|
dummy_st_ops # test_run unexpected error: -524 (errno 524) (trampoline)
|
||||||
|
fentry_fexit # fentry attach failed: -524 (trampoline)
|
||||||
|
fentry_test # fentry_first_attach unexpected error: -524 (trampoline)
|
||||||
|
fexit_bpf2bpf # freplace_attach_trace unexpected error: -524 (trampoline)
|
||||||
|
fexit_sleep # fexit_skel_load fexit skeleton failed (trampoline)
|
||||||
|
fexit_stress # fexit attach failed prog 0 failed: -524 (trampoline)
|
||||||
|
fexit_test # fexit_first_attach unexpected error: -524 (trampoline)
|
||||||
|
get_func_args_test # trampoline
|
||||||
|
get_func_ip_test # get_func_ip_test__attach unexpected error: -524 (trampoline)
|
||||||
|
get_stack_raw_tp # user_stack corrupted user stack (no backchain userspace)
|
||||||
|
kfree_skb # attach fentry unexpected error: -524 (trampoline)
|
||||||
|
kfunc_call # 'bpf_prog_active': not found in kernel BTF (?)
|
||||||
|
ksyms_module # test_ksyms_module__open_and_load unexpected error: -9 (?)
|
||||||
|
ksyms_module_libbpf # JIT does not support calling kernel function (kfunc)
|
||||||
|
ksyms_module_lskel # test_ksyms_module_lskel__open_and_load unexpected error: -9 (?)
|
||||||
|
modify_return # modify_return attach failed: -524 (trampoline)
|
||||||
|
module_attach # skel_attach skeleton attach failed: -524 (trampoline)
|
||||||
|
mptcp
|
||||||
|
kprobe_multi_test # relies on fentry
|
||||||
|
netcnt # failed to load BPF skeleton 'netcnt_prog': -7 (?)
|
||||||
|
probe_user # check_kprobe_res wrong kprobe res from probe read (?)
|
||||||
|
recursion # skel_attach unexpected error: -524 (trampoline)
|
||||||
|
ringbuf # skel_load skeleton load failed (?)
|
||||||
|
sk_assign # Can't read on server: Invalid argument (?)
|
||||||
|
sk_lookup # endianness problem
|
||||||
|
sk_storage_tracing # test_sk_storage_tracing__attach unexpected error: -524 (trampoline)
|
||||||
|
skc_to_unix_sock # could not attach BPF object unexpected error: -524 (trampoline)
|
||||||
|
socket_cookie # prog_attach unexpected error: -524 (trampoline)
|
||||||
|
stacktrace_build_id # compare_map_keys stackid_hmap vs. stackmap err -2 errno 2 (?)
|
||||||
|
tailcalls # tail_calls are not allowed in non-JITed programs with bpf-to-bpf calls (?)
|
||||||
|
task_local_storage # failed to auto-attach program 'trace_exit_creds': -524 (trampoline)
|
||||||
|
test_bpffs # bpffs test failed 255 (iterator)
|
||||||
|
test_bprm_opts # failed to auto-attach program 'secure_exec': -524 (trampoline)
|
||||||
|
test_ima # failed to auto-attach program 'ima': -524 (trampoline)
|
||||||
|
test_local_storage # failed to auto-attach program 'unlink_hook': -524 (trampoline)
|
||||||
|
test_lsm # failed to find kernel BTF type ID of '__x64_sys_setdomainname': -3 (?)
|
||||||
|
test_overhead # attach_fentry unexpected error: -524 (trampoline)
|
||||||
|
test_profiler # unknown func bpf_probe_read_str#45 (overlapping)
|
||||||
|
timer # failed to auto-attach program 'test1': -524 (trampoline)
|
||||||
|
timer_crash # trampoline
|
||||||
|
timer_mim # failed to auto-attach program 'test1': -524 (trampoline)
|
||||||
|
trace_ext # failed to auto-attach program 'test_pkt_md_access_new': -524 (trampoline)
|
||||||
|
trace_printk # trace_printk__load unexpected error: -2 (errno 2) (?)
|
||||||
|
trace_vprintk # trace_vprintk__open_and_load unexpected error: -9 (?)
|
||||||
|
trampoline_count # prog 'prog1': failed to attach: ERROR: strerror_r(-524)=22 (trampoline)
|
||||||
|
verif_stats # trace_vprintk__open_and_load unexpected error: -9 (?)
|
||||||
|
vmlinux # failed to auto-attach program 'handle__fentry': -524 (trampoline)
|
||||||
|
xdp_adjust_tail # case-128 err 0 errno 28 retval 1 size 128 expect-size 3520 (?)
|
||||||
|
xdp_bonding # failed to auto-attach program 'trace_on_entry': -524 (trampoline)
|
||||||
|
xdp_bpf2bpf # failed to auto-attach program 'trace_on_entry': -524 (trampoline)
|
||||||
|
map_kptr # failed to open_and_load program: -524 (trampoline)
|
||||||
|
bpf_cookie # failed to open_and_load program: -524 (trampoline)
|
||||||
|
xdp_do_redirect # prog_run_max_size unexpected error: -22 (errno 22)
|
||||||
|
send_signal # intermittently fails to receive signal
|
||||||
|
select_reuseport # intermittently fails on new s390x setup
|
||||||
|
xdp_synproxy # JIT does not support calling kernel function (kfunc)
|
||||||
|
unpriv_bpf_disabled # fentry
|
||||||
|
lru_bug
|
||||||
36
ci/vmtest/helpers.sh
Executable file
36
ci/vmtest/helpers.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
# $1 - start or end
|
||||||
|
# $2 - fold identifier, no spaces
|
||||||
|
# $3 - fold section description
|
||||||
|
foldable() {
|
||||||
|
local YELLOW='\033[1;33m'
|
||||||
|
local NOCOLOR='\033[0m'
|
||||||
|
if [ $1 = "start" ]; then
|
||||||
|
line="::group::$2"
|
||||||
|
if [ ! -z "${3:-}" ]; then
|
||||||
|
line="$line - ${YELLOW}$3${NOCOLOR}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
line="::endgroup::"
|
||||||
|
fi
|
||||||
|
echo -e "$line"
|
||||||
|
}
|
||||||
|
|
||||||
|
__print() {
|
||||||
|
local TITLE=""
|
||||||
|
if [[ -n $2 ]]; then
|
||||||
|
TITLE=" title=$2"
|
||||||
|
fi
|
||||||
|
echo "::$1${TITLE}::$3"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - title
|
||||||
|
# $2 - message
|
||||||
|
print_error() {
|
||||||
|
__print error $1 $2
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - title
|
||||||
|
# $2 - message
|
||||||
|
print_notice() {
|
||||||
|
__print notice $1 $2
|
||||||
|
}
|
||||||
76
ci/vmtest/run_selftests.sh
Executable file
76
ci/vmtest/run_selftests.sh
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||||
|
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
|
||||||
|
STATUS_FILE=/exitstatus
|
||||||
|
|
||||||
|
read_lists() {
|
||||||
|
(for path in "$@"; do
|
||||||
|
if [[ -s "$path" ]]; then
|
||||||
|
cat "$path"
|
||||||
|
fi;
|
||||||
|
done) | cut -d'#' -f1 | tr -s ' \t\n' ','
|
||||||
|
}
|
||||||
|
|
||||||
|
test_progs() {
|
||||||
|
if [[ "${KERNEL}" != '4.9.0' ]]; then
|
||||||
|
foldable start test_progs "Testing test_progs"
|
||||||
|
# "&& true" does not change the return code (it is not executed
|
||||||
|
# if the Python script fails), but it prevents exiting on a
|
||||||
|
# failure due to the "set -e".
|
||||||
|
./test_progs ${DENYLIST:+-d$DENYLIST} ${ALLOWLIST:+-a$ALLOWLIST} && true
|
||||||
|
echo "test_progs:$?" >> "${STATUS_FILE}"
|
||||||
|
foldable end test_progs
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_progs_noalu() {
|
||||||
|
foldable start test_progs-no_alu32 "Testing test_progs-no_alu32"
|
||||||
|
./test_progs-no_alu32 ${DENYLIST:+-d$DENYLIST} ${ALLOWLIST:+-a$ALLOWLIST} && true
|
||||||
|
echo "test_progs-no_alu32:$?" >> "${STATUS_FILE}"
|
||||||
|
foldable end test_progs-no_alu32
|
||||||
|
}
|
||||||
|
|
||||||
|
test_maps() {
|
||||||
|
if [[ "${KERNEL}" == 'latest' ]]; then
|
||||||
|
foldable start test_maps "Testing test_maps"
|
||||||
|
./test_maps && true
|
||||||
|
echo "test_maps:$?" >> "${STATUS_FILE}"
|
||||||
|
foldable end test_maps
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_verifier() {
|
||||||
|
if [[ "${KERNEL}" == 'latest' ]]; then
|
||||||
|
foldable start test_verifier "Testing test_verifier"
|
||||||
|
./test_verifier && true
|
||||||
|
echo "test_verifier:$?" >> "${STATUS_FILE}"
|
||||||
|
foldable end test_verifier
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
foldable end vm_init
|
||||||
|
|
||||||
|
configs_path=${PROJECT_NAME}/vmtest/configs
|
||||||
|
DENYLIST=$(read_lists "$configs_path/DENYLIST-${KERNEL}" "$configs_path/DENYLIST-${KERNEL}.${ARCH}")
|
||||||
|
ALLOWLIST=$(read_lists "$configs_path/ALLOWLIST-${KERNEL}" "$configs_path/ALLOWLIST-${KERNEL}.${ARCH}")
|
||||||
|
|
||||||
|
echo "DENYLIST: ${DENYLIST}"
|
||||||
|
echo "ALLOWLIST: ${ALLOWLIST}"
|
||||||
|
|
||||||
|
cd ${PROJECT_NAME}/selftests/bpf
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
test_progs
|
||||||
|
test_progs_noalu
|
||||||
|
test_maps
|
||||||
|
test_verifier
|
||||||
|
else
|
||||||
|
for test_name in "$@"; do
|
||||||
|
"${test_name}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
2
docs/.gitignore
vendored
Normal file
2
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
sphinx/build
|
||||||
|
sphinx/doxygen/build
|
||||||
93
docs/api.rst
Normal file
93
docs/api.rst
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
|
.. _api:
|
||||||
|
|
||||||
|
.. toctree:: Table of Contents
|
||||||
|
|
||||||
|
|
||||||
|
LIBBPF API
|
||||||
|
==========
|
||||||
|
|
||||||
|
Error Handling
|
||||||
|
--------------
|
||||||
|
|
||||||
|
When libbpf is used in "libbpf 1.0 mode", API functions can return errors in one of two ways.
|
||||||
|
|
||||||
|
You can set "libbpf 1.0" mode with the following line:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
libbpf_set_strict_mode(LIBBPF_STRICT_DIRECT_ERRS | LIBBPF_STRICT_CLEAN_PTRS);
|
||||||
|
|
||||||
|
If the function returns an error code directly, it uses 0 to indicate success
|
||||||
|
and a negative error code to indicate what caused the error. In this case the
|
||||||
|
error code should be checked directly from the return, you do not need to check
|
||||||
|
errno.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
err = some_libbpf_api_with_error_return(...);
|
||||||
|
if (err < 0) {
|
||||||
|
/* Handle error accordingly */
|
||||||
|
}
|
||||||
|
|
||||||
|
If the function returns a pointer, it will return NULL to indicate there was
|
||||||
|
an error. In this case errno should be checked for the error code.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
ptr = some_libbpf_api_returning_ptr();
|
||||||
|
if (!ptr) {
|
||||||
|
/* note no minus sign for EINVAL and E2BIG below */
|
||||||
|
if (errno == EINVAL) {
|
||||||
|
/* handle EINVAL error */
|
||||||
|
} else if (errno == E2BIG) {
|
||||||
|
/* handle E2BIG error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libbpf.h
|
||||||
|
--------
|
||||||
|
.. doxygenfile:: libbpf.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
bpf.h
|
||||||
|
-----
|
||||||
|
.. doxygenfile:: bpf.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
btf.h
|
||||||
|
-----
|
||||||
|
.. doxygenfile:: btf.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
xsk.h
|
||||||
|
-----
|
||||||
|
.. doxygenfile:: xsk.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
bpf_tracing.h
|
||||||
|
-------------
|
||||||
|
.. doxygenfile:: bpf_tracing.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
bpf_core_read.h
|
||||||
|
---------------
|
||||||
|
.. doxygenfile:: bpf_core_read.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
|
|
||||||
|
bpf_endian.h
|
||||||
|
------------
|
||||||
|
.. doxygenfile:: bpf_endian.h
|
||||||
|
:project: libbpf
|
||||||
|
:sections: func define public-type enum
|
||||||
40
docs/conf.py
Normal file
40
docs/conf.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# This file only contains a selection of the most common options. For a full
|
||||||
|
# list see the documentation:
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
project = "libbpf"
|
||||||
|
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.doctest',
|
||||||
|
'sphinx.ext.mathjax',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
|
'sphinx.ext.imgmath',
|
||||||
|
'sphinx.ext.todo',
|
||||||
|
'breathe',
|
||||||
|
]
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
|
exclude_patterns = []
|
||||||
|
|
||||||
|
read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
|
||||||
|
|
||||||
|
if read_the_docs_build:
|
||||||
|
subprocess.call('cd sphinx ; make clean', shell=True)
|
||||||
|
subprocess.call('cd sphinx/doxygen ; doxygen', shell=True)
|
||||||
|
|
||||||
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
|
||||||
|
breathe_projects = { "libbpf": "./sphinx/doxygen/build/xml/" }
|
||||||
|
breathe_default_project = "libbpf"
|
||||||
|
breathe_show_define_initializer = True
|
||||||
|
breathe_show_enumvalue_initializer = True
|
||||||
21
docs/index.rst
Normal file
21
docs/index.rst
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
|
libbpf
|
||||||
|
======
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
API Documentation <https://libbpf.readthedocs.io/en/latest/api.html>
|
||||||
|
libbpf_naming_convention
|
||||||
|
libbpf_build
|
||||||
|
|
||||||
|
This is documentation for libbpf, a userspace library for loading and
|
||||||
|
interacting with bpf programs.
|
||||||
|
|
||||||
|
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||||
|
their application, should be sent to bpf@vger.kernel.org mailing list.
|
||||||
|
You can `subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the
|
||||||
|
mailing list search its `archive <https://lore.kernel.org/bpf/>`_.
|
||||||
|
Please search the archive before asking new questions. It very well might
|
||||||
|
be that this was already addressed or answered before.
|
||||||
37
docs/libbpf_build.rst
Normal file
37
docs/libbpf_build.rst
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
|
Building libbpf
|
||||||
|
===============
|
||||||
|
|
||||||
|
libelf and zlib are internal dependencies of libbpf and thus are required to link
|
||||||
|
against and must be installed on the system for applications to work.
|
||||||
|
pkg-config is used by default to find libelf, and the program called
|
||||||
|
can be overridden with PKG_CONFIG.
|
||||||
|
|
||||||
|
If using pkg-config at build time is not desired, it can be disabled by
|
||||||
|
setting NO_PKG_CONFIG=1 when calling make.
|
||||||
|
|
||||||
|
To build both static libbpf.a and shared libbpf.so:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ cd src
|
||||||
|
$ make
|
||||||
|
|
||||||
|
To build only static libbpf.a library in directory build/ and install them
|
||||||
|
together with libbpf headers in a staging directory root/:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ cd src
|
||||||
|
$ mkdir build root
|
||||||
|
$ BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=root make install
|
||||||
|
|
||||||
|
To build both static libbpf.a and shared libbpf.so against a custom libelf
|
||||||
|
dependency installed in /build/root/ and install them together with libbpf
|
||||||
|
headers in a build directory /build/root/:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ cd src
|
||||||
|
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
libbpf API naming convention
|
API naming convention
|
||||||
============================
|
=====================
|
||||||
|
|
||||||
libbpf API provides access to a few logically separated groups of
|
libbpf API provides access to a few logically separated groups of
|
||||||
functions and types. Every group has its own naming convention
|
functions and types. Every group has its own naming convention
|
||||||
@@ -9,15 +9,15 @@ described here. It's recommended to follow these conventions whenever a
|
|||||||
new function or type is added to keep libbpf API clean and consistent.
|
new function or type is added to keep libbpf API clean and consistent.
|
||||||
|
|
||||||
All types and functions provided by libbpf API should have one of the
|
All types and functions provided by libbpf API should have one of the
|
||||||
following prefixes: ``bpf_``, ``btf_``, ``libbpf_``, ``xsk_``,
|
following prefixes: ``bpf_``, ``btf_``, ``libbpf_``, ``btf_dump_``,
|
||||||
``perf_buffer_``.
|
``ring_buffer_``, ``perf_buffer_``.
|
||||||
|
|
||||||
System call wrappers
|
System call wrappers
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
System call wrappers are simple wrappers for commands supported by
|
System call wrappers are simple wrappers for commands supported by
|
||||||
sys_bpf system call. These wrappers should go to ``bpf.h`` header file
|
sys_bpf system call. These wrappers should go to ``bpf.h`` header file
|
||||||
and map one-on-one to corresponding commands.
|
and map one to one to corresponding commands.
|
||||||
|
|
||||||
For example ``bpf_map_lookup_elem`` wraps ``BPF_MAP_LOOKUP_ELEM``
|
For example ``bpf_map_lookup_elem`` wraps ``BPF_MAP_LOOKUP_ELEM``
|
||||||
command of sys_bpf, ``bpf_prog_attach`` wraps ``BPF_PROG_ATTACH``, etc.
|
command of sys_bpf, ``bpf_prog_attach`` wraps ``BPF_PROG_ATTACH``, etc.
|
||||||
@@ -49,10 +49,6 @@ object, ``bpf_object``, double underscore and ``open`` that defines the
|
|||||||
purpose of the function to open ELF file and create ``bpf_object`` from
|
purpose of the function to open ELF file and create ``bpf_object`` from
|
||||||
it.
|
it.
|
||||||
|
|
||||||
Another example: ``bpf_program__load`` is named for corresponding
|
|
||||||
object, ``bpf_program``, that is separated from other part of the name
|
|
||||||
by double underscore.
|
|
||||||
|
|
||||||
All objects and corresponding functions other than BTF related should go
|
All objects and corresponding functions other than BTF related should go
|
||||||
to ``libbpf.h``. BTF types and functions should go to ``btf.h``.
|
to ``libbpf.h``. BTF types and functions should go to ``btf.h``.
|
||||||
|
|
||||||
@@ -63,21 +59,8 @@ Auxiliary functions and types that don't fit well in any of categories
|
|||||||
described above should have ``libbpf_`` prefix, e.g.
|
described above should have ``libbpf_`` prefix, e.g.
|
||||||
``libbpf_get_error`` or ``libbpf_prog_type_by_name``.
|
``libbpf_get_error`` or ``libbpf_prog_type_by_name``.
|
||||||
|
|
||||||
AF_XDP functions
|
ABI
|
||||||
-------------------
|
---
|
||||||
|
|
||||||
AF_XDP functions should have an ``xsk_`` prefix, e.g.
|
|
||||||
``xsk_umem__get_data`` or ``xsk_umem__create``. The interface consists
|
|
||||||
of both low-level ring access functions and high-level configuration
|
|
||||||
functions. These can be mixed and matched. Note that these functions
|
|
||||||
are not reentrant for performance reasons.
|
|
||||||
|
|
||||||
Please take a look at Documentation/networking/af_xdp.rst in the Linux
|
|
||||||
kernel source tree on how to use XDP sockets and for some common
|
|
||||||
mistakes in case you do not get any traffic up to user space.
|
|
||||||
|
|
||||||
libbpf ABI
|
|
||||||
==========
|
|
||||||
|
|
||||||
libbpf can be both linked statically or used as DSO. To avoid possible
|
libbpf can be both linked statically or used as DSO. To avoid possible
|
||||||
conflicts with other libraries an application is linked with, all
|
conflicts with other libraries an application is linked with, all
|
||||||
@@ -116,7 +99,8 @@ This bump in ABI version is at most once per kernel development cycle.
|
|||||||
|
|
||||||
For example, if current state of ``libbpf.map`` is:
|
For example, if current state of ``libbpf.map`` is:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block:: none
|
||||||
|
|
||||||
LIBBPF_0.0.1 {
|
LIBBPF_0.0.1 {
|
||||||
global:
|
global:
|
||||||
bpf_func_a;
|
bpf_func_a;
|
||||||
@@ -128,7 +112,8 @@ For example, if current state of ``libbpf.map`` is:
|
|||||||
, and a new symbol ``bpf_func_c`` is being introduced, then
|
, and a new symbol ``bpf_func_c`` is being introduced, then
|
||||||
``libbpf.map`` should be changed like this:
|
``libbpf.map`` should be changed like this:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block:: none
|
||||||
|
|
||||||
LIBBPF_0.0.1 {
|
LIBBPF_0.0.1 {
|
||||||
global:
|
global:
|
||||||
bpf_func_a;
|
bpf_func_a;
|
||||||
@@ -148,7 +133,7 @@ Format of version script and ways to handle ABI changes, including
|
|||||||
incompatible ones, described in details in [1].
|
incompatible ones, described in details in [1].
|
||||||
|
|
||||||
Stand-alone build
|
Stand-alone build
|
||||||
=================
|
-------------------
|
||||||
|
|
||||||
Under https://github.com/libbpf/libbpf there is a (semi-)automated
|
Under https://github.com/libbpf/libbpf there is a (semi-)automated
|
||||||
mirror of the mainline's version of libbpf for a stand-alone build.
|
mirror of the mainline's version of libbpf for a stand-alone build.
|
||||||
@@ -156,13 +141,53 @@ mirror of the mainline's version of libbpf for a stand-alone build.
|
|||||||
However, all changes to libbpf's code base must be upstreamed through
|
However, all changes to libbpf's code base must be upstreamed through
|
||||||
the mainline kernel tree.
|
the mainline kernel tree.
|
||||||
|
|
||||||
|
|
||||||
|
API documentation convention
|
||||||
|
============================
|
||||||
|
|
||||||
|
The libbpf API is documented via comments above definitions in
|
||||||
|
header files. These comments can be rendered by doxygen and sphinx
|
||||||
|
for well organized html output. This section describes the
|
||||||
|
convention in which these comments should be formated.
|
||||||
|
|
||||||
|
Here is an example from btf.h:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **btf__new()** creates a new instance of a BTF object from the raw
|
||||||
|
* bytes of an ELF's BTF section
|
||||||
|
* @param data raw bytes
|
||||||
|
* @param size number of bytes passed in `data`
|
||||||
|
* @return new BTF object instance which has to be eventually freed with
|
||||||
|
* **btf__free()**
|
||||||
|
*
|
||||||
|
* On error, error-code-encoded-as-pointer is returned, not a NULL. To extract
|
||||||
|
* error code from such a pointer `libbpf_get_error()` should be used. If
|
||||||
|
* `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is
|
||||||
|
* returned on error instead. In both cases thread-local `errno` variable is
|
||||||
|
* always set to error code as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
The comment must start with a block comment of the form '/\*\*'.
|
||||||
|
|
||||||
|
The documentation always starts with a @brief directive. This line is a short
|
||||||
|
description about this API. It starts with the name of the API, denoted in bold
|
||||||
|
like so: **api_name**. Please include an open and close parenthesis if this is a
|
||||||
|
function. Follow with the short description of the API. A longer form description
|
||||||
|
can be added below the last directive, at the bottom of the comment.
|
||||||
|
|
||||||
|
Parameters are denoted with the @param directive, there should be one for each
|
||||||
|
parameter. If this is a function with a non-void return, use the @return directive
|
||||||
|
to document it.
|
||||||
|
|
||||||
License
|
License
|
||||||
=======
|
-------------------
|
||||||
|
|
||||||
libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause.
|
libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause.
|
||||||
|
|
||||||
Links
|
Links
|
||||||
=====
|
-------------------
|
||||||
|
|
||||||
[1] https://www.akkadia.org/drepper/dsohowto.pdf
|
[1] https://www.akkadia.org/drepper/dsohowto.pdf
|
||||||
(Chapter 3. Maintaining APIs and ABIs).
|
(Chapter 3. Maintaining APIs and ABIs).
|
||||||
9
docs/sphinx/Makefile
Normal file
9
docs/sphinx/Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
SPHINXBUILD ?= sphinx-build
|
||||||
|
SOURCEDIR = ../src
|
||||||
|
BUILDDIR = build
|
||||||
|
|
||||||
|
help:
|
||||||
|
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)"
|
||||||
|
|
||||||
|
%:
|
||||||
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)"
|
||||||
277
docs/sphinx/doxygen/Doxyfile
Normal file
277
docs/sphinx/doxygen/Doxyfile
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
PROJECT_NAME = "libbpf"
|
||||||
|
PROJECT_NUMBER =
|
||||||
|
PROJECT_BRIEF =
|
||||||
|
PROJECT_LOGO =
|
||||||
|
OUTPUT_DIRECTORY = ./build
|
||||||
|
CREATE_SUBDIRS = NO
|
||||||
|
ALLOW_UNICODE_NAMES = NO
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
OUTPUT_TEXT_DIRECTION = None
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
FULL_PATH_NAMES = YES
|
||||||
|
STRIP_FROM_PATH =
|
||||||
|
STRIP_FROM_INC_PATH =
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
JAVADOC_AUTOBRIEF = NO
|
||||||
|
JAVADOC_BANNER = NO
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
PYTHON_DOCSTRING = NO
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
|
TAB_SIZE = 4
|
||||||
|
ALIASES =
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
OPTIMIZE_OUTPUT_SLICE = NO
|
||||||
|
EXTENSION_MAPPING =
|
||||||
|
MARKDOWN_SUPPORT = YES
|
||||||
|
TOC_INCLUDE_HEADINGS = 5
|
||||||
|
AUTOLINK_SUPPORT = YES
|
||||||
|
BUILTIN_STL_SUPPORT = NO
|
||||||
|
CPP_CLI_SUPPORT = NO
|
||||||
|
SIP_SUPPORT = NO
|
||||||
|
IDL_PROPERTY_SUPPORT = YES
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
GROUP_NESTED_COMPOUNDS = NO
|
||||||
|
SUBGROUPING = YES
|
||||||
|
INLINE_GROUPED_CLASSES = NO
|
||||||
|
INLINE_SIMPLE_STRUCTS = NO
|
||||||
|
TYPEDEF_HIDES_STRUCT = NO
|
||||||
|
LOOKUP_CACHE_SIZE = 0
|
||||||
|
NUM_PROC_THREADS = 1
|
||||||
|
EXTRACT_ALL = NO
|
||||||
|
EXTRACT_PRIVATE = NO
|
||||||
|
EXTRACT_PRIV_VIRTUAL = NO
|
||||||
|
EXTRACT_PACKAGE = NO
|
||||||
|
EXTRACT_STATIC = NO
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
EXTRACT_LOCAL_METHODS = NO
|
||||||
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
RESOLVE_UNNAMED_PARAMS = YES
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
|
HIDE_IN_BODY_DOCS = NO
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
CASE_SENSE_NAMES = YES
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
HIDE_COMPOUND_REFERENCE= NO
|
||||||
|
SHOW_INCLUDE_FILES = YES
|
||||||
|
SHOW_GROUPED_MEMB_INC = NO
|
||||||
|
FORCE_LOCAL_INCLUDES = NO
|
||||||
|
INLINE_INFO = YES
|
||||||
|
SORT_MEMBER_DOCS = YES
|
||||||
|
SORT_BRIEF_DOCS = NO
|
||||||
|
SORT_MEMBERS_CTORS_1ST = NO
|
||||||
|
SORT_GROUP_NAMES = NO
|
||||||
|
SORT_BY_SCOPE_NAME = NO
|
||||||
|
STRICT_PROTO_MATCHING = NO
|
||||||
|
GENERATE_TODOLIST = YES
|
||||||
|
GENERATE_TESTLIST = YES
|
||||||
|
GENERATE_BUGLIST = YES
|
||||||
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
SHOW_USED_FILES = YES
|
||||||
|
SHOW_FILES = YES
|
||||||
|
SHOW_NAMESPACES = YES
|
||||||
|
FILE_VERSION_FILTER =
|
||||||
|
LAYOUT_FILE =
|
||||||
|
CITE_BIB_FILES =
|
||||||
|
QUIET = NO
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
WARN_NO_PARAMDOC = NO
|
||||||
|
WARN_AS_ERROR = NO
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE =
|
||||||
|
INPUT = ../../../src
|
||||||
|
INPUT_ENCODING = UTF-8
|
||||||
|
FILE_PATTERNS = *.c \
|
||||||
|
*.h
|
||||||
|
RECURSIVE = NO
|
||||||
|
EXCLUDE =
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
EXCLUDE_SYMBOLS = ___*
|
||||||
|
EXAMPLE_PATH =
|
||||||
|
EXAMPLE_PATTERNS = *
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
IMAGE_PATH =
|
||||||
|
INPUT_FILTER =
|
||||||
|
FILTER_PATTERNS =
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
FILTER_SOURCE_PATTERNS =
|
||||||
|
USE_MDFILE_AS_MAINPAGE = YES
|
||||||
|
SOURCE_BROWSER = NO
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
REFERENCED_BY_RELATION = NO
|
||||||
|
REFERENCES_RELATION = NO
|
||||||
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
SOURCE_TOOLTIPS = YES
|
||||||
|
USE_HTAGS = NO
|
||||||
|
VERBATIM_HEADERS = YES
|
||||||
|
ALPHABETICAL_INDEX = YES
|
||||||
|
IGNORE_PREFIX =
|
||||||
|
GENERATE_HTML = NO
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_HEADER =
|
||||||
|
HTML_FOOTER =
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
HTML_EXTRA_STYLESHEET =
|
||||||
|
HTML_EXTRA_FILES =
|
||||||
|
HTML_COLORSTYLE_HUE = 220
|
||||||
|
HTML_COLORSTYLE_SAT = 100
|
||||||
|
HTML_COLORSTYLE_GAMMA = 80
|
||||||
|
HTML_TIMESTAMP = NO
|
||||||
|
HTML_DYNAMIC_MENUS = YES
|
||||||
|
HTML_DYNAMIC_SECTIONS = NO
|
||||||
|
HTML_INDEX_NUM_ENTRIES = 100
|
||||||
|
GENERATE_DOCSET = NO
|
||||||
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||||
|
DOCSET_PUBLISHER_NAME = Publisher
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
CHM_FILE =
|
||||||
|
HHC_LOCATION =
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
CHM_INDEX_ENCODING =
|
||||||
|
BINARY_TOC = NO
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
GENERATE_QHP = NO
|
||||||
|
QCH_FILE =
|
||||||
|
QHP_NAMESPACE = org.doxygen.Project
|
||||||
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
QHP_CUST_FILTER_NAME =
|
||||||
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
QHG_LOCATION =
|
||||||
|
GENERATE_ECLIPSEHELP = NO
|
||||||
|
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
GENERATE_TREEVIEW = NO
|
||||||
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
TREEVIEW_WIDTH = 250
|
||||||
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
HTML_FORMULA_FORMAT = png
|
||||||
|
FORMULA_FONTSIZE = 10
|
||||||
|
FORMULA_TRANSPARENT = YES
|
||||||
|
FORMULA_MACROFILE =
|
||||||
|
USE_MATHJAX = NO
|
||||||
|
MATHJAX_FORMAT = HTML-CSS
|
||||||
|
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
|
||||||
|
MATHJAX_EXTENSIONS =
|
||||||
|
MATHJAX_CODEFILE =
|
||||||
|
SEARCHENGINE = YES
|
||||||
|
SERVER_BASED_SEARCH = NO
|
||||||
|
EXTERNAL_SEARCH = NO
|
||||||
|
SEARCHENGINE_URL =
|
||||||
|
SEARCHDATA_FILE = searchdata.xml
|
||||||
|
EXTERNAL_SEARCH_ID =
|
||||||
|
EXTRA_SEARCH_MAPPINGS =
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
LATEX_CMD_NAME =
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
LATEX_MAKEINDEX_CMD = makeindex
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
PAPER_TYPE = a4
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
LATEX_HEADER =
|
||||||
|
LATEX_FOOTER =
|
||||||
|
LATEX_EXTRA_STYLESHEET =
|
||||||
|
LATEX_EXTRA_FILES =
|
||||||
|
PDF_HYPERLINKS = YES
|
||||||
|
USE_PDFLATEX = YES
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
LATEX_HIDE_INDICES = NO
|
||||||
|
LATEX_SOURCE_CODE = NO
|
||||||
|
LATEX_BIB_STYLE = plain
|
||||||
|
LATEX_TIMESTAMP = NO
|
||||||
|
LATEX_EMOJI_DIRECTORY =
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
RTF_SOURCE_CODE = NO
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_SUBDIR =
|
||||||
|
MAN_LINKS = NO
|
||||||
|
GENERATE_XML = YES
|
||||||
|
XML_OUTPUT = xml
|
||||||
|
XML_PROGRAMLISTING = YES
|
||||||
|
XML_NS_MEMB_FILE_SCOPE = NO
|
||||||
|
GENERATE_DOCBOOK = NO
|
||||||
|
DOCBOOK_OUTPUT = docbook
|
||||||
|
DOCBOOK_PROGRAMLISTING = NO
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
GENERATE_PERLMOD = NO
|
||||||
|
PERLMOD_LATEX = NO
|
||||||
|
PERLMOD_PRETTY = YES
|
||||||
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = NO
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH =
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
PREDEFINED =
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
SKIP_FUNCTION_MACROS = NO
|
||||||
|
TAGFILES =
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
EXTERNAL_PAGES = YES
|
||||||
|
CLASS_DIAGRAMS = YES
|
||||||
|
DIA_PATH =
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
HAVE_DOT = NO
|
||||||
|
DOT_NUM_THREADS = 0
|
||||||
|
DOT_FONTNAME = Helvetica
|
||||||
|
DOT_FONTSIZE = 10
|
||||||
|
DOT_FONTPATH =
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
COLLABORATION_GRAPH = YES
|
||||||
|
GROUP_GRAPHS = YES
|
||||||
|
UML_LOOK = NO
|
||||||
|
UML_LIMIT_NUM_FIELDS = 10
|
||||||
|
DOT_UML_DETAILS = NO
|
||||||
|
DOT_WRAP_THRESHOLD = 17
|
||||||
|
TEMPLATE_RELATIONS = NO
|
||||||
|
INCLUDE_GRAPH = YES
|
||||||
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
CALL_GRAPH = NO
|
||||||
|
CALLER_GRAPH = NO
|
||||||
|
GRAPHICAL_HIERARCHY = YES
|
||||||
|
DIRECTORY_GRAPH = YES
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
INTERACTIVE_SVG = NO
|
||||||
|
DOT_PATH =
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
MSCFILE_DIRS =
|
||||||
|
DIAFILE_DIRS =
|
||||||
|
PLANTUML_JAR_PATH =
|
||||||
|
PLANTUML_CFG_FILE =
|
||||||
|
PLANTUML_INCLUDE_PATH =
|
||||||
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
DOT_TRANSPARENT = NO
|
||||||
|
DOT_MULTI_TARGETS = NO
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
DOT_CLEANUP = YES
|
||||||
1
docs/sphinx/requirements.txt
Normal file
1
docs/sphinx/requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
breathe
|
||||||
23
fuzz/bpf-object-fuzzer.c
Normal file
23
fuzz/bpf-object-fuzzer.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include "libbpf.h"
|
||||||
|
|
||||||
|
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
struct bpf_object *obj = NULL;
|
||||||
|
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
libbpf_set_print(libbpf_print_fn);
|
||||||
|
|
||||||
|
opts.object_name = "fuzz-object";
|
||||||
|
obj = bpf_object__open_mem(data, size, &opts);
|
||||||
|
err = libbpf_get_error(obj);
|
||||||
|
if (err)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bpf_object__close(obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
fuzz/bpf-object-fuzzer_seed_corpus.zip
Normal file
BIN
fuzz/bpf-object-fuzzer_seed_corpus.zip
Normal file
Binary file not shown.
@@ -5,6 +5,22 @@
|
|||||||
|
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
|
|
||||||
|
#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
|
||||||
|
((struct bpf_insn) { \
|
||||||
|
.code = CODE, \
|
||||||
|
.dst_reg = DST, \
|
||||||
|
.src_reg = SRC, \
|
||||||
|
.off = OFF, \
|
||||||
|
.imm = IMM })
|
||||||
|
|
||||||
|
#define BPF_ALU32_IMM(OP, DST, IMM) \
|
||||||
|
((struct bpf_insn) { \
|
||||||
|
.code = BPF_ALU | BPF_OP(OP) | BPF_K, \
|
||||||
|
.dst_reg = DST, \
|
||||||
|
.src_reg = 0, \
|
||||||
|
.off = 0, \
|
||||||
|
.imm = IMM })
|
||||||
|
|
||||||
#define BPF_ALU64_IMM(OP, DST, IMM) \
|
#define BPF_ALU64_IMM(OP, DST, IMM) \
|
||||||
((struct bpf_insn) { \
|
((struct bpf_insn) { \
|
||||||
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
|
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
|
||||||
@@ -107,5 +123,12 @@
|
|||||||
.off = OFF, \
|
.off = OFF, \
|
||||||
.imm = IMM })
|
.imm = IMM })
|
||||||
|
|
||||||
|
#define BPF_JMP32_IMM(OP, DST, IMM, OFF) \
|
||||||
|
((struct bpf_insn) { \
|
||||||
|
.code = BPF_JMP32 | BPF_OP(OP) | BPF_K, \
|
||||||
|
.dst_reg = DST, \
|
||||||
|
.src_reg = 0, \
|
||||||
|
.off = OFF, \
|
||||||
|
.imm = IMM })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -72,11 +72,20 @@ static inline void list_del(struct list_head *entry)
|
|||||||
entry->prev = LIST_POISON2;
|
entry->prev = LIST_POISON2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int list_empty(const struct list_head *head)
|
||||||
|
{
|
||||||
|
return head->next == head;
|
||||||
|
}
|
||||||
|
|
||||||
#define list_entry(ptr, type, member) \
|
#define list_entry(ptr, type, member) \
|
||||||
container_of(ptr, type, member)
|
container_of(ptr, type, member)
|
||||||
#define list_first_entry(ptr, type, member) \
|
#define list_first_entry(ptr, type, member) \
|
||||||
list_entry((ptr)->next, type, member)
|
list_entry((ptr)->next, type, member)
|
||||||
#define list_next_entry(pos, member) \
|
#define list_next_entry(pos, member) \
|
||||||
list_entry((pos)->member.next, typeof(*(pos)), member)
|
list_entry((pos)->member.next, typeof(*(pos)), member)
|
||||||
|
#define list_for_each_entry(pos, head, member) \
|
||||||
|
for (pos = list_first_entry(head, typeof(*pos), member); \
|
||||||
|
&pos->member != (head); \
|
||||||
|
pos = list_next_entry(pos, member))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <linux/stddef.h>
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/posix_types.h>
|
#include <asm/posix_types.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
// SPDX-License-Identifier: (LGPL-2.0+ OR BSD-2-Clause)
|
|
||||||
/* Copyright (C) 2018 Netronome Systems, Inc. */
|
|
||||||
|
|
||||||
#ifndef __TOOLS_LIBC_COMPAT_H
|
|
||||||
#define __TOOLS_LIBC_COMPAT_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <linux/overflow.h>
|
|
||||||
|
|
||||||
#ifdef COMPAT_NEED_REALLOCARRAY
|
|
||||||
static inline void *reallocarray(void *ptr, size_t nmemb, size_t size)
|
|
||||||
{
|
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
if (unlikely(check_mul_overflow(nmemb, size, &bytes)))
|
|
||||||
return NULL;
|
|
||||||
return realloc(ptr, bytes);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -22,9 +22,9 @@ struct btf_header {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Max # of type identifier */
|
/* Max # of type identifier */
|
||||||
#define BTF_MAX_TYPE 0x0000ffff
|
#define BTF_MAX_TYPE 0x000fffff
|
||||||
/* Max offset into the string section */
|
/* Max offset into the string section */
|
||||||
#define BTF_MAX_NAME_OFFSET 0x0000ffff
|
#define BTF_MAX_NAME_OFFSET 0x00ffffff
|
||||||
/* Max # of struct/union/enum members or func args */
|
/* Max # of struct/union/enum members or func args */
|
||||||
#define BTF_MAX_VLEN 0xffff
|
#define BTF_MAX_VLEN 0xffff
|
||||||
|
|
||||||
@@ -33,17 +33,17 @@ struct btf_type {
|
|||||||
/* "info" bits arrangement
|
/* "info" bits arrangement
|
||||||
* bits 0-15: vlen (e.g. # of struct's members)
|
* bits 0-15: vlen (e.g. # of struct's members)
|
||||||
* bits 16-23: unused
|
* bits 16-23: unused
|
||||||
* bits 24-27: kind (e.g. int, ptr, array...etc)
|
* bits 24-28: kind (e.g. int, ptr, array...etc)
|
||||||
* bits 28-30: unused
|
* bits 29-30: unused
|
||||||
* bit 31: kind_flag, currently used by
|
* bit 31: kind_flag, currently used by
|
||||||
* struct, union and fwd
|
* struct, union, enum, fwd and enum64
|
||||||
*/
|
*/
|
||||||
__u32 info;
|
__u32 info;
|
||||||
/* "size" is used by INT, ENUM, STRUCT, UNION and DATASEC.
|
/* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64.
|
||||||
* "size" tells the size of the type it is describing.
|
* "size" tells the size of the type it is describing.
|
||||||
*
|
*
|
||||||
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
|
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
|
||||||
* FUNC, FUNC_PROTO and VAR.
|
* FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG.
|
||||||
* "type" is a type_id referring to another type.
|
* "type" is a type_id referring to another type.
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
@@ -52,28 +52,35 @@ struct btf_type {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
|
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
|
||||||
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
|
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
|
||||||
#define BTF_INFO_KFLAG(info) ((info) >> 31)
|
#define BTF_INFO_KFLAG(info) ((info) >> 31)
|
||||||
|
|
||||||
#define BTF_KIND_UNKN 0 /* Unknown */
|
enum {
|
||||||
#define BTF_KIND_INT 1 /* Integer */
|
BTF_KIND_UNKN = 0, /* Unknown */
|
||||||
#define BTF_KIND_PTR 2 /* Pointer */
|
BTF_KIND_INT = 1, /* Integer */
|
||||||
#define BTF_KIND_ARRAY 3 /* Array */
|
BTF_KIND_PTR = 2, /* Pointer */
|
||||||
#define BTF_KIND_STRUCT 4 /* Struct */
|
BTF_KIND_ARRAY = 3, /* Array */
|
||||||
#define BTF_KIND_UNION 5 /* Union */
|
BTF_KIND_STRUCT = 4, /* Struct */
|
||||||
#define BTF_KIND_ENUM 6 /* Enumeration */
|
BTF_KIND_UNION = 5, /* Union */
|
||||||
#define BTF_KIND_FWD 7 /* Forward */
|
BTF_KIND_ENUM = 6, /* Enumeration up to 32-bit values */
|
||||||
#define BTF_KIND_TYPEDEF 8 /* Typedef */
|
BTF_KIND_FWD = 7, /* Forward */
|
||||||
#define BTF_KIND_VOLATILE 9 /* Volatile */
|
BTF_KIND_TYPEDEF = 8, /* Typedef */
|
||||||
#define BTF_KIND_CONST 10 /* Const */
|
BTF_KIND_VOLATILE = 9, /* Volatile */
|
||||||
#define BTF_KIND_RESTRICT 11 /* Restrict */
|
BTF_KIND_CONST = 10, /* Const */
|
||||||
#define BTF_KIND_FUNC 12 /* Function */
|
BTF_KIND_RESTRICT = 11, /* Restrict */
|
||||||
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
|
BTF_KIND_FUNC = 12, /* Function */
|
||||||
#define BTF_KIND_VAR 14 /* Variable */
|
BTF_KIND_FUNC_PROTO = 13, /* Function Proto */
|
||||||
#define BTF_KIND_DATASEC 15 /* Section */
|
BTF_KIND_VAR = 14, /* Variable */
|
||||||
#define BTF_KIND_MAX BTF_KIND_DATASEC
|
BTF_KIND_DATASEC = 15, /* Section */
|
||||||
#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
|
BTF_KIND_FLOAT = 16, /* Floating point */
|
||||||
|
BTF_KIND_DECL_TAG = 17, /* Decl Tag */
|
||||||
|
BTF_KIND_TYPE_TAG = 18, /* Type Tag */
|
||||||
|
BTF_KIND_ENUM64 = 19, /* Enumeration up to 64-bit values */
|
||||||
|
|
||||||
|
NR_BTF_KINDS,
|
||||||
|
BTF_KIND_MAX = NR_BTF_KINDS - 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* For some specific BTF_KIND, "struct btf_type" is immediately
|
/* For some specific BTF_KIND, "struct btf_type" is immediately
|
||||||
* followed by extra data.
|
* followed by extra data.
|
||||||
@@ -142,7 +149,14 @@ struct btf_param {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
BTF_VAR_STATIC = 0,
|
BTF_VAR_STATIC = 0,
|
||||||
BTF_VAR_GLOBAL_ALLOCATED,
|
BTF_VAR_GLOBAL_ALLOCATED = 1,
|
||||||
|
BTF_VAR_GLOBAL_EXTERN = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum btf_func_linkage {
|
||||||
|
BTF_FUNC_STATIC = 0,
|
||||||
|
BTF_FUNC_GLOBAL = 1,
|
||||||
|
BTF_FUNC_EXTERN = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
|
/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
|
||||||
@@ -162,4 +176,25 @@ struct btf_var_secinfo {
|
|||||||
__u32 size;
|
__u32 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* BTF_KIND_DECL_TAG is followed by a single "struct btf_decl_tag" to describe
|
||||||
|
* additional information related to the tag applied location.
|
||||||
|
* If component_idx == -1, the tag is applied to a struct, union,
|
||||||
|
* variable or function. Otherwise, it is applied to a struct/union
|
||||||
|
* member or a func argument, and component_idx indicates which member
|
||||||
|
* or argument (0 ... vlen-1).
|
||||||
|
*/
|
||||||
|
struct btf_decl_tag {
|
||||||
|
__s32 component_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* BTF_KIND_ENUM64 is followed by multiple "struct btf_enum64".
|
||||||
|
* The exact number of btf_enum64 is stored in the vlen (of the
|
||||||
|
* info in "struct btf_type").
|
||||||
|
*/
|
||||||
|
struct btf_enum64 {
|
||||||
|
__u32 name_off;
|
||||||
|
__u32 val_lo32;
|
||||||
|
__u32 val_hi32;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _UAPI__LINUX_BTF_H__ */
|
#endif /* _UAPI__LINUX_BTF_H__ */
|
||||||
|
|||||||
@@ -7,24 +7,23 @@
|
|||||||
|
|
||||||
/* This struct should be in sync with struct rtnl_link_stats64 */
|
/* This struct should be in sync with struct rtnl_link_stats64 */
|
||||||
struct rtnl_link_stats {
|
struct rtnl_link_stats {
|
||||||
__u32 rx_packets; /* total packets received */
|
__u32 rx_packets;
|
||||||
__u32 tx_packets; /* total packets transmitted */
|
__u32 tx_packets;
|
||||||
__u32 rx_bytes; /* total bytes received */
|
__u32 rx_bytes;
|
||||||
__u32 tx_bytes; /* total bytes transmitted */
|
__u32 tx_bytes;
|
||||||
__u32 rx_errors; /* bad packets received */
|
__u32 rx_errors;
|
||||||
__u32 tx_errors; /* packet transmit problems */
|
__u32 tx_errors;
|
||||||
__u32 rx_dropped; /* no space in linux buffers */
|
__u32 rx_dropped;
|
||||||
__u32 tx_dropped; /* no space available in linux */
|
__u32 tx_dropped;
|
||||||
__u32 multicast; /* multicast packets received */
|
__u32 multicast;
|
||||||
__u32 collisions;
|
__u32 collisions;
|
||||||
|
|
||||||
/* detailed rx_errors: */
|
/* detailed rx_errors: */
|
||||||
__u32 rx_length_errors;
|
__u32 rx_length_errors;
|
||||||
__u32 rx_over_errors; /* receiver ring buff overflow */
|
__u32 rx_over_errors;
|
||||||
__u32 rx_crc_errors; /* recved pkt with crc error */
|
__u32 rx_crc_errors;
|
||||||
__u32 rx_frame_errors; /* recv'd frame alignment error */
|
__u32 rx_frame_errors;
|
||||||
__u32 rx_fifo_errors; /* recv'r fifo overrun */
|
__u32 rx_fifo_errors;
|
||||||
__u32 rx_missed_errors; /* receiver missed packet */
|
__u32 rx_missed_errors;
|
||||||
|
|
||||||
/* detailed tx_errors */
|
/* detailed tx_errors */
|
||||||
__u32 tx_aborted_errors;
|
__u32 tx_aborted_errors;
|
||||||
@@ -37,29 +36,201 @@ struct rtnl_link_stats {
|
|||||||
__u32 rx_compressed;
|
__u32 rx_compressed;
|
||||||
__u32 tx_compressed;
|
__u32 tx_compressed;
|
||||||
|
|
||||||
__u32 rx_nohandler; /* dropped, no handler found */
|
__u32 rx_nohandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The main device statistics structure */
|
/**
|
||||||
|
* struct rtnl_link_stats64 - The main device statistics structure.
|
||||||
|
*
|
||||||
|
* @rx_packets: Number of good packets received by the interface.
|
||||||
|
* For hardware interfaces counts all good packets received from the device
|
||||||
|
* by the host, including packets which host had to drop at various stages
|
||||||
|
* of processing (even in the driver).
|
||||||
|
*
|
||||||
|
* @tx_packets: Number of packets successfully transmitted.
|
||||||
|
* For hardware interfaces counts packets which host was able to successfully
|
||||||
|
* hand over to the device, which does not necessarily mean that packets
|
||||||
|
* had been successfully transmitted out of the device, only that device
|
||||||
|
* acknowledged it copied them out of host memory.
|
||||||
|
*
|
||||||
|
* @rx_bytes: Number of good received bytes, corresponding to @rx_packets.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices should count the length of Ethernet Frames
|
||||||
|
* excluding the FCS.
|
||||||
|
*
|
||||||
|
* @tx_bytes: Number of good transmitted bytes, corresponding to @tx_packets.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices should count the length of Ethernet Frames
|
||||||
|
* excluding the FCS.
|
||||||
|
*
|
||||||
|
* @rx_errors: Total number of bad packets received on this network device.
|
||||||
|
* This counter must include events counted by @rx_length_errors,
|
||||||
|
* @rx_crc_errors, @rx_frame_errors and other errors not otherwise
|
||||||
|
* counted.
|
||||||
|
*
|
||||||
|
* @tx_errors: Total number of transmit problems.
|
||||||
|
* This counter must include events counter by @tx_aborted_errors,
|
||||||
|
* @tx_carrier_errors, @tx_fifo_errors, @tx_heartbeat_errors,
|
||||||
|
* @tx_window_errors and other errors not otherwise counted.
|
||||||
|
*
|
||||||
|
* @rx_dropped: Number of packets received but not processed,
|
||||||
|
* e.g. due to lack of resources or unsupported protocol.
|
||||||
|
* For hardware interfaces this counter may include packets discarded
|
||||||
|
* due to L2 address filtering but should not include packets dropped
|
||||||
|
* by the device due to buffer exhaustion which are counted separately in
|
||||||
|
* @rx_missed_errors (since procfs folds those two counters together).
|
||||||
|
*
|
||||||
|
* @tx_dropped: Number of packets dropped on their way to transmission,
|
||||||
|
* e.g. due to lack of resources.
|
||||||
|
*
|
||||||
|
* @multicast: Multicast packets received.
|
||||||
|
* For hardware interfaces this statistic is commonly calculated
|
||||||
|
* at the device level (unlike @rx_packets) and therefore may include
|
||||||
|
* packets which did not reach the host.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter may be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.21 aMulticastFramesReceivedOK
|
||||||
|
*
|
||||||
|
* @collisions: Number of collisions during packet transmissions.
|
||||||
|
*
|
||||||
|
* @rx_length_errors: Number of packets dropped due to invalid length.
|
||||||
|
* Part of aggregate "frame" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter should be equivalent to a sum
|
||||||
|
* of the following attributes:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.23 aInRangeLengthErrors
|
||||||
|
* - 30.3.1.1.24 aOutOfRangeLengthField
|
||||||
|
* - 30.3.1.1.25 aFrameTooLongErrors
|
||||||
|
*
|
||||||
|
* @rx_over_errors: Receiver FIFO overflow event counter.
|
||||||
|
*
|
||||||
|
* Historically the count of overflow events. Such events may be
|
||||||
|
* reported in the receive descriptors or via interrupts, and may
|
||||||
|
* not correspond one-to-one with dropped packets.
|
||||||
|
*
|
||||||
|
* The recommended interpretation for high speed interfaces is -
|
||||||
|
* number of packets dropped because they did not fit into buffers
|
||||||
|
* provided by the host, e.g. packets larger than MTU or next buffer
|
||||||
|
* in the ring was not available for a scatter transfer.
|
||||||
|
*
|
||||||
|
* Part of aggregate "frame" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* This statistics was historically used interchangeably with
|
||||||
|
* @rx_fifo_errors.
|
||||||
|
*
|
||||||
|
* This statistic corresponds to hardware events and is not commonly used
|
||||||
|
* on software devices.
|
||||||
|
*
|
||||||
|
* @rx_crc_errors: Number of packets received with a CRC error.
|
||||||
|
* Part of aggregate "frame" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter must be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.6 aFrameCheckSequenceErrors
|
||||||
|
*
|
||||||
|
* @rx_frame_errors: Receiver frame alignment errors.
|
||||||
|
* Part of aggregate "frame" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter should be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.7 aAlignmentErrors
|
||||||
|
*
|
||||||
|
* @rx_fifo_errors: Receiver FIFO error counter.
|
||||||
|
*
|
||||||
|
* Historically the count of overflow events. Those events may be
|
||||||
|
* reported in the receive descriptors or via interrupts, and may
|
||||||
|
* not correspond one-to-one with dropped packets.
|
||||||
|
*
|
||||||
|
* This statistics was used interchangeably with @rx_over_errors.
|
||||||
|
* Not recommended for use in drivers for high speed interfaces.
|
||||||
|
*
|
||||||
|
* This statistic is used on software devices, e.g. to count software
|
||||||
|
* packet queue overflow (can) or sequencing errors (GRE).
|
||||||
|
*
|
||||||
|
* @rx_missed_errors: Count of packets missed by the host.
|
||||||
|
* Folded into the "drop" counter in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* Counts number of packets dropped by the device due to lack
|
||||||
|
* of buffer space. This usually indicates that the host interface
|
||||||
|
* is slower than the network interface, or host is not keeping up
|
||||||
|
* with the receive packet rate.
|
||||||
|
*
|
||||||
|
* This statistic corresponds to hardware events and is not used
|
||||||
|
* on software devices.
|
||||||
|
*
|
||||||
|
* @tx_aborted_errors:
|
||||||
|
* Part of aggregate "carrier" errors in `/proc/net/dev`.
|
||||||
|
* For IEEE 802.3 devices capable of half-duplex operation this counter
|
||||||
|
* must be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.11 aFramesAbortedDueToXSColls
|
||||||
|
*
|
||||||
|
* High speed interfaces may use this counter as a general device
|
||||||
|
* discard counter.
|
||||||
|
*
|
||||||
|
* @tx_carrier_errors: Number of frame transmission errors due to loss
|
||||||
|
* of carrier during transmission.
|
||||||
|
* Part of aggregate "carrier" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter must be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.13 aCarrierSenseErrors
|
||||||
|
*
|
||||||
|
* @tx_fifo_errors: Number of frame transmission errors due to device
|
||||||
|
* FIFO underrun / underflow. This condition occurs when the device
|
||||||
|
* begins transmission of a frame but is unable to deliver the
|
||||||
|
* entire frame to the transmitter in time for transmission.
|
||||||
|
* Part of aggregate "carrier" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* @tx_heartbeat_errors: Number of Heartbeat / SQE Test errors for
|
||||||
|
* old half-duplex Ethernet.
|
||||||
|
* Part of aggregate "carrier" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices possibly equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.2.1.4 aSQETestErrors
|
||||||
|
*
|
||||||
|
* @tx_window_errors: Number of frame transmission errors due
|
||||||
|
* to late collisions (for Ethernet - after the first 64B of transmission).
|
||||||
|
* Part of aggregate "carrier" errors in `/proc/net/dev`.
|
||||||
|
*
|
||||||
|
* For IEEE 802.3 devices this counter must be equivalent to:
|
||||||
|
*
|
||||||
|
* - 30.3.1.1.10 aLateCollisions
|
||||||
|
*
|
||||||
|
* @rx_compressed: Number of correctly received compressed packets.
|
||||||
|
* This counters is only meaningful for interfaces which support
|
||||||
|
* packet compression (e.g. CSLIP, PPP).
|
||||||
|
*
|
||||||
|
* @tx_compressed: Number of transmitted compressed packets.
|
||||||
|
* This counters is only meaningful for interfaces which support
|
||||||
|
* packet compression (e.g. CSLIP, PPP).
|
||||||
|
*
|
||||||
|
* @rx_nohandler: Number of packets received on the interface
|
||||||
|
* but dropped by the networking stack because the device is
|
||||||
|
* not designated to receive packets (e.g. backup link in a bond).
|
||||||
|
*/
|
||||||
struct rtnl_link_stats64 {
|
struct rtnl_link_stats64 {
|
||||||
__u64 rx_packets; /* total packets received */
|
__u64 rx_packets;
|
||||||
__u64 tx_packets; /* total packets transmitted */
|
__u64 tx_packets;
|
||||||
__u64 rx_bytes; /* total bytes received */
|
__u64 rx_bytes;
|
||||||
__u64 tx_bytes; /* total bytes transmitted */
|
__u64 tx_bytes;
|
||||||
__u64 rx_errors; /* bad packets received */
|
__u64 rx_errors;
|
||||||
__u64 tx_errors; /* packet transmit problems */
|
__u64 tx_errors;
|
||||||
__u64 rx_dropped; /* no space in linux buffers */
|
__u64 rx_dropped;
|
||||||
__u64 tx_dropped; /* no space available in linux */
|
__u64 tx_dropped;
|
||||||
__u64 multicast; /* multicast packets received */
|
__u64 multicast;
|
||||||
__u64 collisions;
|
__u64 collisions;
|
||||||
|
|
||||||
/* detailed rx_errors: */
|
/* detailed rx_errors: */
|
||||||
__u64 rx_length_errors;
|
__u64 rx_length_errors;
|
||||||
__u64 rx_over_errors; /* receiver ring buff overflow */
|
__u64 rx_over_errors;
|
||||||
__u64 rx_crc_errors; /* recved pkt with crc error */
|
__u64 rx_crc_errors;
|
||||||
__u64 rx_frame_errors; /* recv'd frame alignment error */
|
__u64 rx_frame_errors;
|
||||||
__u64 rx_fifo_errors; /* recv'r fifo overrun */
|
__u64 rx_fifo_errors;
|
||||||
__u64 rx_missed_errors; /* receiver missed packet */
|
__u64 rx_missed_errors;
|
||||||
|
|
||||||
/* detailed tx_errors */
|
/* detailed tx_errors */
|
||||||
__u64 tx_aborted_errors;
|
__u64 tx_aborted_errors;
|
||||||
@@ -71,8 +242,7 @@ struct rtnl_link_stats64 {
|
|||||||
/* for cslip etc */
|
/* for cslip etc */
|
||||||
__u64 rx_compressed;
|
__u64 rx_compressed;
|
||||||
__u64 tx_compressed;
|
__u64 tx_compressed;
|
||||||
|
__u64 rx_nohandler;
|
||||||
__u64 rx_nohandler; /* dropped, no handler found */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The struct should be in sync with struct ifmap */
|
/* The struct should be in sync with struct ifmap */
|
||||||
@@ -167,12 +337,35 @@ enum {
|
|||||||
IFLA_NEW_IFINDEX,
|
IFLA_NEW_IFINDEX,
|
||||||
IFLA_MIN_MTU,
|
IFLA_MIN_MTU,
|
||||||
IFLA_MAX_MTU,
|
IFLA_MAX_MTU,
|
||||||
|
IFLA_PROP_LIST,
|
||||||
|
IFLA_ALT_IFNAME, /* Alternative ifname */
|
||||||
|
IFLA_PERM_ADDRESS,
|
||||||
|
IFLA_PROTO_DOWN_REASON,
|
||||||
|
|
||||||
|
/* device (sysfs) name as parent, used instead
|
||||||
|
* of IFLA_LINK where there's no parent netdev
|
||||||
|
*/
|
||||||
|
IFLA_PARENT_DEV_NAME,
|
||||||
|
IFLA_PARENT_DEV_BUS_NAME,
|
||||||
|
IFLA_GRO_MAX_SIZE,
|
||||||
|
IFLA_TSO_MAX_SIZE,
|
||||||
|
IFLA_TSO_MAX_SEGS,
|
||||||
|
|
||||||
__IFLA_MAX
|
__IFLA_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define IFLA_MAX (__IFLA_MAX - 1)
|
#define IFLA_MAX (__IFLA_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IFLA_PROTO_DOWN_REASON_UNSPEC,
|
||||||
|
IFLA_PROTO_DOWN_REASON_MASK, /* u32, mask for reason bits */
|
||||||
|
IFLA_PROTO_DOWN_REASON_VALUE, /* u32, reason bit value */
|
||||||
|
|
||||||
|
__IFLA_PROTO_DOWN_REASON_CNT,
|
||||||
|
IFLA_PROTO_DOWN_REASON_MAX = __IFLA_PROTO_DOWN_REASON_CNT - 1
|
||||||
|
};
|
||||||
|
|
||||||
/* backwards compatibility for userspace */
|
/* backwards compatibility for userspace */
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
|
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
|
||||||
@@ -227,6 +420,7 @@ enum {
|
|||||||
IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
|
IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
|
||||||
IFLA_INET6_TOKEN, /* device token */
|
IFLA_INET6_TOKEN, /* device token */
|
||||||
IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
|
IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
|
||||||
|
IFLA_INET6_RA_MTU, /* mtu carried in the RA message */
|
||||||
__IFLA_INET6_MAX
|
__IFLA_INET6_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -289,6 +483,7 @@ enum {
|
|||||||
IFLA_BR_MCAST_MLD_VERSION,
|
IFLA_BR_MCAST_MLD_VERSION,
|
||||||
IFLA_BR_VLAN_STATS_PER_PORT,
|
IFLA_BR_VLAN_STATS_PER_PORT,
|
||||||
IFLA_BR_MULTI_BOOLOPT,
|
IFLA_BR_MULTI_BOOLOPT,
|
||||||
|
IFLA_BR_MCAST_QUERIER_STATE,
|
||||||
__IFLA_BR_MAX,
|
__IFLA_BR_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,6 +535,10 @@ enum {
|
|||||||
IFLA_BRPORT_NEIGH_SUPPRESS,
|
IFLA_BRPORT_NEIGH_SUPPRESS,
|
||||||
IFLA_BRPORT_ISOLATED,
|
IFLA_BRPORT_ISOLATED,
|
||||||
IFLA_BRPORT_BACKUP_PORT,
|
IFLA_BRPORT_BACKUP_PORT,
|
||||||
|
IFLA_BRPORT_MRP_RING_OPEN,
|
||||||
|
IFLA_BRPORT_MRP_IN_OPEN,
|
||||||
|
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
|
||||||
|
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
|
||||||
__IFLA_BRPORT_MAX
|
__IFLA_BRPORT_MAX
|
||||||
};
|
};
|
||||||
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
|
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
|
||||||
@@ -404,6 +603,8 @@ enum {
|
|||||||
IFLA_MACVLAN_MACADDR,
|
IFLA_MACVLAN_MACADDR,
|
||||||
IFLA_MACVLAN_MACADDR_DATA,
|
IFLA_MACVLAN_MACADDR_DATA,
|
||||||
IFLA_MACVLAN_MACADDR_COUNT,
|
IFLA_MACVLAN_MACADDR_COUNT,
|
||||||
|
IFLA_MACVLAN_BC_QUEUE_LEN,
|
||||||
|
IFLA_MACVLAN_BC_QUEUE_LEN_USED,
|
||||||
__IFLA_MACVLAN_MAX,
|
__IFLA_MACVLAN_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -425,6 +626,7 @@ enum macvlan_macaddr_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MACVLAN_FLAG_NOPROMISC 1
|
#define MACVLAN_FLAG_NOPROMISC 1
|
||||||
|
#define MACVLAN_FLAG_NODST 2 /* skip dst macvlan if matching src macvlan */
|
||||||
|
|
||||||
/* VRF section */
|
/* VRF section */
|
||||||
enum {
|
enum {
|
||||||
@@ -460,6 +662,7 @@ enum {
|
|||||||
IFLA_MACSEC_REPLAY_PROTECT,
|
IFLA_MACSEC_REPLAY_PROTECT,
|
||||||
IFLA_MACSEC_VALIDATION,
|
IFLA_MACSEC_VALIDATION,
|
||||||
IFLA_MACSEC_PAD,
|
IFLA_MACSEC_PAD,
|
||||||
|
IFLA_MACSEC_OFFLOAD,
|
||||||
__IFLA_MACSEC_MAX,
|
__IFLA_MACSEC_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -483,6 +686,14 @@ enum macsec_validation_type {
|
|||||||
MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
|
MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum macsec_offload {
|
||||||
|
MACSEC_OFFLOAD_OFF = 0,
|
||||||
|
MACSEC_OFFLOAD_PHY = 1,
|
||||||
|
MACSEC_OFFLOAD_MAC = 2,
|
||||||
|
__MACSEC_OFFLOAD_END,
|
||||||
|
MACSEC_OFFLOAD_MAX = __MACSEC_OFFLOAD_END - 1,
|
||||||
|
};
|
||||||
|
|
||||||
/* IPVLAN section */
|
/* IPVLAN section */
|
||||||
enum {
|
enum {
|
||||||
IFLA_IPVLAN_UNSPEC,
|
IFLA_IPVLAN_UNSPEC,
|
||||||
@@ -580,6 +791,18 @@ enum ifla_geneve_df {
|
|||||||
GENEVE_DF_MAX = __GENEVE_DF_END - 1,
|
GENEVE_DF_MAX = __GENEVE_DF_END - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Bareudp section */
|
||||||
|
enum {
|
||||||
|
IFLA_BAREUDP_UNSPEC,
|
||||||
|
IFLA_BAREUDP_PORT,
|
||||||
|
IFLA_BAREUDP_ETHERTYPE,
|
||||||
|
IFLA_BAREUDP_SRCPORT_MIN,
|
||||||
|
IFLA_BAREUDP_MULTIPROTO_MODE,
|
||||||
|
__IFLA_BAREUDP_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IFLA_BAREUDP_MAX (__IFLA_BAREUDP_MAX - 1)
|
||||||
|
|
||||||
/* PPP section */
|
/* PPP section */
|
||||||
enum {
|
enum {
|
||||||
IFLA_PPP_UNSPEC,
|
IFLA_PPP_UNSPEC,
|
||||||
@@ -637,6 +860,9 @@ enum {
|
|||||||
IFLA_BOND_AD_ACTOR_SYSTEM,
|
IFLA_BOND_AD_ACTOR_SYSTEM,
|
||||||
IFLA_BOND_TLB_DYNAMIC_LB,
|
IFLA_BOND_TLB_DYNAMIC_LB,
|
||||||
IFLA_BOND_PEER_NOTIF_DELAY,
|
IFLA_BOND_PEER_NOTIF_DELAY,
|
||||||
|
IFLA_BOND_AD_LACP_ACTIVE,
|
||||||
|
IFLA_BOND_MISSED_MAX,
|
||||||
|
IFLA_BOND_NS_IP6_TARGET,
|
||||||
__IFLA_BOND_MAX,
|
__IFLA_BOND_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -664,6 +890,7 @@ enum {
|
|||||||
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
|
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
|
||||||
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
|
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
|
||||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
|
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
|
||||||
|
IFLA_BOND_SLAVE_PRIO,
|
||||||
__IFLA_BOND_SLAVE_MAX,
|
__IFLA_BOND_SLAVE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -881,7 +1108,14 @@ enum {
|
|||||||
#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
|
#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
|
||||||
|
|
||||||
|
|
||||||
/* HSR section */
|
/* HSR/PRP section, both uses same interface */
|
||||||
|
|
||||||
|
/* Different redundancy protocols for hsr device */
|
||||||
|
enum {
|
||||||
|
HSR_PROTOCOL_HSR,
|
||||||
|
HSR_PROTOCOL_PRP,
|
||||||
|
HSR_PROTOCOL_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IFLA_HSR_UNSPEC,
|
IFLA_HSR_UNSPEC,
|
||||||
@@ -891,6 +1125,9 @@ enum {
|
|||||||
IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
|
IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
|
||||||
IFLA_HSR_SEQ_NR,
|
IFLA_HSR_SEQ_NR,
|
||||||
IFLA_HSR_VERSION, /* HSR version */
|
IFLA_HSR_VERSION, /* HSR version */
|
||||||
|
IFLA_HSR_PROTOCOL, /* Indicate different protocol than
|
||||||
|
* HSR. For example PRP.
|
||||||
|
*/
|
||||||
__IFLA_HSR_MAX,
|
__IFLA_HSR_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -950,11 +1187,12 @@ enum {
|
|||||||
#define XDP_FLAGS_SKB_MODE (1U << 1)
|
#define XDP_FLAGS_SKB_MODE (1U << 1)
|
||||||
#define XDP_FLAGS_DRV_MODE (1U << 2)
|
#define XDP_FLAGS_DRV_MODE (1U << 2)
|
||||||
#define XDP_FLAGS_HW_MODE (1U << 3)
|
#define XDP_FLAGS_HW_MODE (1U << 3)
|
||||||
|
#define XDP_FLAGS_REPLACE (1U << 4)
|
||||||
#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
|
#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
|
||||||
XDP_FLAGS_DRV_MODE | \
|
XDP_FLAGS_DRV_MODE | \
|
||||||
XDP_FLAGS_HW_MODE)
|
XDP_FLAGS_HW_MODE)
|
||||||
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
|
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
|
||||||
XDP_FLAGS_MODES)
|
XDP_FLAGS_MODES | XDP_FLAGS_REPLACE)
|
||||||
|
|
||||||
/* These are stored into IFLA_XDP_ATTACHED on dump. */
|
/* These are stored into IFLA_XDP_ATTACHED on dump. */
|
||||||
enum {
|
enum {
|
||||||
@@ -974,6 +1212,7 @@ enum {
|
|||||||
IFLA_XDP_DRV_PROG_ID,
|
IFLA_XDP_DRV_PROG_ID,
|
||||||
IFLA_XDP_SKB_PROG_ID,
|
IFLA_XDP_SKB_PROG_ID,
|
||||||
IFLA_XDP_HW_PROG_ID,
|
IFLA_XDP_HW_PROG_ID,
|
||||||
|
IFLA_XDP_EXPECTED_FD,
|
||||||
__IFLA_XDP_MAX,
|
__IFLA_XDP_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1013,6 +1252,8 @@ enum {
|
|||||||
#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
|
#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
|
||||||
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
|
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
|
||||||
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
|
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
|
||||||
|
#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4)
|
||||||
|
#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5 (1U << 5)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IFLA_RMNET_UNSPEC,
|
IFLA_RMNET_UNSPEC,
|
||||||
@@ -1028,4 +1269,14 @@ struct ifla_rmnet_flags {
|
|||||||
__u32 mask;
|
__u32 mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* MCTP section */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IFLA_MCTP_UNSPEC,
|
||||||
|
IFLA_MCTP_NET,
|
||||||
|
__IFLA_MCTP_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
|
||||||
|
|
||||||
#endif /* _UAPI_LINUX_IF_LINK_H */
|
#endif /* _UAPI_LINUX_IF_LINK_H */
|
||||||
|
|||||||
@@ -73,9 +73,12 @@ struct xdp_umem_reg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct xdp_statistics {
|
struct xdp_statistics {
|
||||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
__u64 rx_dropped; /* Dropped for other reasons */
|
||||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||||
|
__u64 rx_ring_full; /* Dropped due to rx ring being full */
|
||||||
|
__u64 rx_fill_ring_empty_descs; /* Failed to retrieve item from fill ring */
|
||||||
|
__u64 tx_ring_empty_descs; /* Failed to retrieve item from tx ring */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xdp_options {
|
struct xdp_options {
|
||||||
|
|||||||
1398
include/uapi/linux/perf_event.h
Normal file
1398
include/uapi/linux/perf_event.h
Normal file
File diff suppressed because it is too large
Load Diff
612
include/uapi/linux/pkt_cls.h
Normal file
612
include/uapi/linux/pkt_cls.h
Normal file
@@ -0,0 +1,612 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
|
#ifndef __LINUX_PKT_CLS_H
|
||||||
|
#define __LINUX_PKT_CLS_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/pkt_sched.h>
|
||||||
|
|
||||||
|
#define TC_COOKIE_MAX_SIZE 16
|
||||||
|
|
||||||
|
/* Action attributes */
|
||||||
|
enum {
|
||||||
|
TCA_ACT_UNSPEC,
|
||||||
|
TCA_ACT_KIND,
|
||||||
|
TCA_ACT_OPTIONS,
|
||||||
|
TCA_ACT_INDEX,
|
||||||
|
TCA_ACT_STATS,
|
||||||
|
TCA_ACT_PAD,
|
||||||
|
TCA_ACT_COOKIE,
|
||||||
|
__TCA_ACT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_ACT_MAX __TCA_ACT_MAX
|
||||||
|
#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
|
||||||
|
#define TCA_ACT_MAX_PRIO 32
|
||||||
|
#define TCA_ACT_BIND 1
|
||||||
|
#define TCA_ACT_NOBIND 0
|
||||||
|
#define TCA_ACT_UNBIND 1
|
||||||
|
#define TCA_ACT_NOUNBIND 0
|
||||||
|
#define TCA_ACT_REPLACE 1
|
||||||
|
#define TCA_ACT_NOREPLACE 0
|
||||||
|
|
||||||
|
#define TC_ACT_UNSPEC (-1)
|
||||||
|
#define TC_ACT_OK 0
|
||||||
|
#define TC_ACT_RECLASSIFY 1
|
||||||
|
#define TC_ACT_SHOT 2
|
||||||
|
#define TC_ACT_PIPE 3
|
||||||
|
#define TC_ACT_STOLEN 4
|
||||||
|
#define TC_ACT_QUEUED 5
|
||||||
|
#define TC_ACT_REPEAT 6
|
||||||
|
#define TC_ACT_REDIRECT 7
|
||||||
|
#define TC_ACT_TRAP 8 /* For hw path, this means "trap to cpu"
|
||||||
|
* and don't further process the frame
|
||||||
|
* in hardware. For sw path, this is
|
||||||
|
* equivalent of TC_ACT_STOLEN - drop
|
||||||
|
* the skb and act like everything
|
||||||
|
* is alright.
|
||||||
|
*/
|
||||||
|
#define TC_ACT_VALUE_MAX TC_ACT_TRAP
|
||||||
|
|
||||||
|
/* There is a special kind of actions called "extended actions",
|
||||||
|
* which need a value parameter. These have a local opcode located in
|
||||||
|
* the highest nibble, starting from 1. The rest of the bits
|
||||||
|
* are used to carry the value. These two parts together make
|
||||||
|
* a combined opcode.
|
||||||
|
*/
|
||||||
|
#define __TC_ACT_EXT_SHIFT 28
|
||||||
|
#define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
|
||||||
|
#define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
|
||||||
|
#define TC_ACT_EXT_OPCODE(combined) ((combined) & (~TC_ACT_EXT_VAL_MASK))
|
||||||
|
#define TC_ACT_EXT_CMP(combined, opcode) (TC_ACT_EXT_OPCODE(combined) == opcode)
|
||||||
|
|
||||||
|
#define TC_ACT_JUMP __TC_ACT_EXT(1)
|
||||||
|
#define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2)
|
||||||
|
#define TC_ACT_EXT_OPCODE_MAX TC_ACT_GOTO_CHAIN
|
||||||
|
|
||||||
|
/* Action type identifiers*/
|
||||||
|
enum {
|
||||||
|
TCA_ID_UNSPEC=0,
|
||||||
|
TCA_ID_POLICE=1,
|
||||||
|
/* other actions go here */
|
||||||
|
__TCA_ID_MAX=255
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_ID_MAX __TCA_ID_MAX
|
||||||
|
|
||||||
|
struct tc_police {
|
||||||
|
__u32 index;
|
||||||
|
int action;
|
||||||
|
#define TC_POLICE_UNSPEC TC_ACT_UNSPEC
|
||||||
|
#define TC_POLICE_OK TC_ACT_OK
|
||||||
|
#define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY
|
||||||
|
#define TC_POLICE_SHOT TC_ACT_SHOT
|
||||||
|
#define TC_POLICE_PIPE TC_ACT_PIPE
|
||||||
|
|
||||||
|
__u32 limit;
|
||||||
|
__u32 burst;
|
||||||
|
__u32 mtu;
|
||||||
|
struct tc_ratespec rate;
|
||||||
|
struct tc_ratespec peakrate;
|
||||||
|
int refcnt;
|
||||||
|
int bindcnt;
|
||||||
|
__u32 capab;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tcf_t {
|
||||||
|
__u64 install;
|
||||||
|
__u64 lastuse;
|
||||||
|
__u64 expires;
|
||||||
|
__u64 firstuse;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tc_cnt {
|
||||||
|
int refcnt;
|
||||||
|
int bindcnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define tc_gen \
|
||||||
|
__u32 index; \
|
||||||
|
__u32 capab; \
|
||||||
|
int action; \
|
||||||
|
int refcnt; \
|
||||||
|
int bindcnt
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_POLICE_UNSPEC,
|
||||||
|
TCA_POLICE_TBF,
|
||||||
|
TCA_POLICE_RATE,
|
||||||
|
TCA_POLICE_PEAKRATE,
|
||||||
|
TCA_POLICE_AVRATE,
|
||||||
|
TCA_POLICE_RESULT,
|
||||||
|
TCA_POLICE_TM,
|
||||||
|
TCA_POLICE_PAD,
|
||||||
|
__TCA_POLICE_MAX
|
||||||
|
#define TCA_POLICE_RESULT TCA_POLICE_RESULT
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
|
||||||
|
|
||||||
|
/* tca flags definitions */
|
||||||
|
#define TCA_CLS_FLAGS_SKIP_HW (1 << 0) /* don't offload filter to HW */
|
||||||
|
#define TCA_CLS_FLAGS_SKIP_SW (1 << 1) /* don't use filter in SW */
|
||||||
|
#define TCA_CLS_FLAGS_IN_HW (1 << 2) /* filter is offloaded to HW */
|
||||||
|
#define TCA_CLS_FLAGS_NOT_IN_HW (1 << 3) /* filter isn't offloaded to HW */
|
||||||
|
#define TCA_CLS_FLAGS_VERBOSE (1 << 4) /* verbose logging */
|
||||||
|
|
||||||
|
/* U32 filters */
|
||||||
|
|
||||||
|
#define TC_U32_HTID(h) ((h)&0xFFF00000)
|
||||||
|
#define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20)
|
||||||
|
#define TC_U32_HASH(h) (((h)>>12)&0xFF)
|
||||||
|
#define TC_U32_NODE(h) ((h)&0xFFF)
|
||||||
|
#define TC_U32_KEY(h) ((h)&0xFFFFF)
|
||||||
|
#define TC_U32_UNSPEC 0
|
||||||
|
#define TC_U32_ROOT (0xFFF00000)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_U32_UNSPEC,
|
||||||
|
TCA_U32_CLASSID,
|
||||||
|
TCA_U32_HASH,
|
||||||
|
TCA_U32_LINK,
|
||||||
|
TCA_U32_DIVISOR,
|
||||||
|
TCA_U32_SEL,
|
||||||
|
TCA_U32_POLICE,
|
||||||
|
TCA_U32_ACT,
|
||||||
|
TCA_U32_INDEV,
|
||||||
|
TCA_U32_PCNT,
|
||||||
|
TCA_U32_MARK,
|
||||||
|
TCA_U32_FLAGS,
|
||||||
|
TCA_U32_PAD,
|
||||||
|
__TCA_U32_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_U32_MAX (__TCA_U32_MAX - 1)
|
||||||
|
|
||||||
|
struct tc_u32_key {
|
||||||
|
__be32 mask;
|
||||||
|
__be32 val;
|
||||||
|
int off;
|
||||||
|
int offmask;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tc_u32_sel {
|
||||||
|
unsigned char flags;
|
||||||
|
unsigned char offshift;
|
||||||
|
unsigned char nkeys;
|
||||||
|
|
||||||
|
__be16 offmask;
|
||||||
|
__u16 off;
|
||||||
|
short offoff;
|
||||||
|
|
||||||
|
short hoff;
|
||||||
|
__be32 hmask;
|
||||||
|
struct tc_u32_key keys[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tc_u32_mark {
|
||||||
|
__u32 val;
|
||||||
|
__u32 mask;
|
||||||
|
__u32 success;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tc_u32_pcnt {
|
||||||
|
__u64 rcnt;
|
||||||
|
__u64 rhit;
|
||||||
|
__u64 kcnts[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
|
||||||
|
#define TC_U32_TERMINAL 1
|
||||||
|
#define TC_U32_OFFSET 2
|
||||||
|
#define TC_U32_VAROFFSET 4
|
||||||
|
#define TC_U32_EAT 8
|
||||||
|
|
||||||
|
#define TC_U32_MAXDEPTH 8
|
||||||
|
|
||||||
|
|
||||||
|
/* RSVP filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_RSVP_UNSPEC,
|
||||||
|
TCA_RSVP_CLASSID,
|
||||||
|
TCA_RSVP_DST,
|
||||||
|
TCA_RSVP_SRC,
|
||||||
|
TCA_RSVP_PINFO,
|
||||||
|
TCA_RSVP_POLICE,
|
||||||
|
TCA_RSVP_ACT,
|
||||||
|
__TCA_RSVP_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 )
|
||||||
|
|
||||||
|
struct tc_rsvp_gpi {
|
||||||
|
__u32 key;
|
||||||
|
__u32 mask;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tc_rsvp_pinfo {
|
||||||
|
struct tc_rsvp_gpi dpi;
|
||||||
|
struct tc_rsvp_gpi spi;
|
||||||
|
__u8 protocol;
|
||||||
|
__u8 tunnelid;
|
||||||
|
__u8 tunnelhdr;
|
||||||
|
__u8 pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ROUTE filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_ROUTE4_UNSPEC,
|
||||||
|
TCA_ROUTE4_CLASSID,
|
||||||
|
TCA_ROUTE4_TO,
|
||||||
|
TCA_ROUTE4_FROM,
|
||||||
|
TCA_ROUTE4_IIF,
|
||||||
|
TCA_ROUTE4_POLICE,
|
||||||
|
TCA_ROUTE4_ACT,
|
||||||
|
__TCA_ROUTE4_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
|
||||||
|
|
||||||
|
|
||||||
|
/* FW filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FW_UNSPEC,
|
||||||
|
TCA_FW_CLASSID,
|
||||||
|
TCA_FW_POLICE,
|
||||||
|
TCA_FW_INDEV,
|
||||||
|
TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */
|
||||||
|
TCA_FW_MASK,
|
||||||
|
__TCA_FW_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_FW_MAX (__TCA_FW_MAX - 1)
|
||||||
|
|
||||||
|
/* TC index filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_TCINDEX_UNSPEC,
|
||||||
|
TCA_TCINDEX_HASH,
|
||||||
|
TCA_TCINDEX_MASK,
|
||||||
|
TCA_TCINDEX_SHIFT,
|
||||||
|
TCA_TCINDEX_FALL_THROUGH,
|
||||||
|
TCA_TCINDEX_CLASSID,
|
||||||
|
TCA_TCINDEX_POLICE,
|
||||||
|
TCA_TCINDEX_ACT,
|
||||||
|
__TCA_TCINDEX_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
|
||||||
|
|
||||||
|
/* Flow filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FLOW_KEY_SRC,
|
||||||
|
FLOW_KEY_DST,
|
||||||
|
FLOW_KEY_PROTO,
|
||||||
|
FLOW_KEY_PROTO_SRC,
|
||||||
|
FLOW_KEY_PROTO_DST,
|
||||||
|
FLOW_KEY_IIF,
|
||||||
|
FLOW_KEY_PRIORITY,
|
||||||
|
FLOW_KEY_MARK,
|
||||||
|
FLOW_KEY_NFCT,
|
||||||
|
FLOW_KEY_NFCT_SRC,
|
||||||
|
FLOW_KEY_NFCT_DST,
|
||||||
|
FLOW_KEY_NFCT_PROTO_SRC,
|
||||||
|
FLOW_KEY_NFCT_PROTO_DST,
|
||||||
|
FLOW_KEY_RTCLASSID,
|
||||||
|
FLOW_KEY_SKUID,
|
||||||
|
FLOW_KEY_SKGID,
|
||||||
|
FLOW_KEY_VLAN_TAG,
|
||||||
|
FLOW_KEY_RXHASH,
|
||||||
|
__FLOW_KEY_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FLOW_MODE_MAP,
|
||||||
|
FLOW_MODE_HASH,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FLOW_UNSPEC,
|
||||||
|
TCA_FLOW_KEYS,
|
||||||
|
TCA_FLOW_MODE,
|
||||||
|
TCA_FLOW_BASECLASS,
|
||||||
|
TCA_FLOW_RSHIFT,
|
||||||
|
TCA_FLOW_ADDEND,
|
||||||
|
TCA_FLOW_MASK,
|
||||||
|
TCA_FLOW_XOR,
|
||||||
|
TCA_FLOW_DIVISOR,
|
||||||
|
TCA_FLOW_ACT,
|
||||||
|
TCA_FLOW_POLICE,
|
||||||
|
TCA_FLOW_EMATCHES,
|
||||||
|
TCA_FLOW_PERTURB,
|
||||||
|
__TCA_FLOW_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_FLOW_MAX (__TCA_FLOW_MAX - 1)
|
||||||
|
|
||||||
|
/* Basic filter */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_BASIC_UNSPEC,
|
||||||
|
TCA_BASIC_CLASSID,
|
||||||
|
TCA_BASIC_EMATCHES,
|
||||||
|
TCA_BASIC_ACT,
|
||||||
|
TCA_BASIC_POLICE,
|
||||||
|
__TCA_BASIC_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
|
||||||
|
|
||||||
|
|
||||||
|
/* Cgroup classifier */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_CGROUP_UNSPEC,
|
||||||
|
TCA_CGROUP_ACT,
|
||||||
|
TCA_CGROUP_POLICE,
|
||||||
|
TCA_CGROUP_EMATCHES,
|
||||||
|
__TCA_CGROUP_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_CGROUP_MAX (__TCA_CGROUP_MAX - 1)
|
||||||
|
|
||||||
|
/* BPF classifier */
|
||||||
|
|
||||||
|
#define TCA_BPF_FLAG_ACT_DIRECT (1 << 0)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_BPF_UNSPEC,
|
||||||
|
TCA_BPF_ACT,
|
||||||
|
TCA_BPF_POLICE,
|
||||||
|
TCA_BPF_CLASSID,
|
||||||
|
TCA_BPF_OPS_LEN,
|
||||||
|
TCA_BPF_OPS,
|
||||||
|
TCA_BPF_FD,
|
||||||
|
TCA_BPF_NAME,
|
||||||
|
TCA_BPF_FLAGS,
|
||||||
|
TCA_BPF_FLAGS_GEN,
|
||||||
|
TCA_BPF_TAG,
|
||||||
|
TCA_BPF_ID,
|
||||||
|
__TCA_BPF_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
|
||||||
|
|
||||||
|
/* Flower classifier */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FLOWER_UNSPEC,
|
||||||
|
TCA_FLOWER_CLASSID,
|
||||||
|
TCA_FLOWER_INDEV,
|
||||||
|
TCA_FLOWER_ACT,
|
||||||
|
TCA_FLOWER_KEY_ETH_DST, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ETH_DST_MASK, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ETH_SRC, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ETH_SRC_MASK, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ETH_TYPE, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_IP_PROTO, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_IPV4_SRC, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_IPV4_SRC_MASK, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_IPV4_DST, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_IPV4_DST_MASK, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_IPV6_SRC, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_IPV6_SRC_MASK, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_IPV6_DST, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_IPV6_DST_MASK, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_TCP_SRC, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_TCP_DST, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_UDP_SRC, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_UDP_DST, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_FLAGS,
|
||||||
|
TCA_FLOWER_KEY_VLAN_ID, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_VLAN_PRIO, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_VLAN_ETH_TYPE, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ENC_KEY_ID, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV4_SRC, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK,/* be32 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV4_DST, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,/* be32 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV6_SRC, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK,/* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV6_DST, /* struct in6_addr */
|
||||||
|
TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,/* struct in6_addr */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_TCP_SRC_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_TCP_DST_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_UDP_SRC_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_UDP_DST_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_SCTP_SRC_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_SCTP_DST_MASK, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_SCTP_SRC, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_SCTP_DST, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_FLAGS, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_FLAGS_MASK, /* be32 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ICMPV4_CODE, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV4_CODE_MASK,/* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV4_TYPE, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,/* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV6_CODE, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV6_CODE_MASK,/* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV6_TYPE, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,/* u8 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ARP_SIP, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ARP_SIP_MASK, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ARP_TIP, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ARP_TIP_MASK, /* be32 */
|
||||||
|
TCA_FLOWER_KEY_ARP_OP, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ARP_OP_MASK, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ARP_SHA, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ARP_SHA_MASK, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ARP_THA, /* ETH_ALEN */
|
||||||
|
TCA_FLOWER_KEY_ARP_THA_MASK, /* ETH_ALEN */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_MPLS_TTL, /* u8 - 8 bits */
|
||||||
|
TCA_FLOWER_KEY_MPLS_BOS, /* u8 - 1 bit */
|
||||||
|
TCA_FLOWER_KEY_MPLS_TC, /* u8 - 3 bits */
|
||||||
|
TCA_FLOWER_KEY_MPLS_LABEL, /* be32 - 20 bits */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_TCP_FLAGS, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_TCP_FLAGS_MASK, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_IP_TOS, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_IP_TOS_MASK, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_IP_TTL, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_CVLAN_ID, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ENC_IP_TOS, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IP_TOS_MASK, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_ENC_OPTS,
|
||||||
|
TCA_FLOWER_KEY_ENC_OPTS_MASK,
|
||||||
|
|
||||||
|
TCA_FLOWER_IN_HW_COUNT,
|
||||||
|
|
||||||
|
__TCA_FLOWER_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
|
||||||
|
TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
|
||||||
|
* TCA_FLOWER_KEY_ENC_OPT_GENEVE_
|
||||||
|
* attributes
|
||||||
|
*/
|
||||||
|
__TCA_FLOWER_KEY_ENC_OPTS_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC,
|
||||||
|
TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, /* u16 */
|
||||||
|
TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */
|
||||||
|
TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */
|
||||||
|
|
||||||
|
__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
|
||||||
|
(__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
|
||||||
|
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Match-all classifier */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_MATCHALL_UNSPEC,
|
||||||
|
TCA_MATCHALL_CLASSID,
|
||||||
|
TCA_MATCHALL_ACT,
|
||||||
|
TCA_MATCHALL_FLAGS,
|
||||||
|
__TCA_MATCHALL_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1)
|
||||||
|
|
||||||
|
/* Extended Matches */
|
||||||
|
|
||||||
|
struct tcf_ematch_tree_hdr {
|
||||||
|
__u16 nmatches;
|
||||||
|
__u16 progid;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCA_EMATCH_TREE_UNSPEC,
|
||||||
|
TCA_EMATCH_TREE_HDR,
|
||||||
|
TCA_EMATCH_TREE_LIST,
|
||||||
|
__TCA_EMATCH_TREE_MAX
|
||||||
|
};
|
||||||
|
#define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1)
|
||||||
|
|
||||||
|
struct tcf_ematch_hdr {
|
||||||
|
__u16 matchid;
|
||||||
|
__u16 kind;
|
||||||
|
__u16 flags;
|
||||||
|
__u16 pad; /* currently unused */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 0 1
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
|
* +-----------------------+-+-+---+
|
||||||
|
* | Unused |S|I| R |
|
||||||
|
* +-----------------------+-+-+---+
|
||||||
|
*
|
||||||
|
* R(2) ::= relation to next ematch
|
||||||
|
* where: 0 0 END (last ematch)
|
||||||
|
* 0 1 AND
|
||||||
|
* 1 0 OR
|
||||||
|
* 1 1 Unused (invalid)
|
||||||
|
* I(1) ::= invert result
|
||||||
|
* S(1) ::= simple payload
|
||||||
|
*/
|
||||||
|
#define TCF_EM_REL_END 0
|
||||||
|
#define TCF_EM_REL_AND (1<<0)
|
||||||
|
#define TCF_EM_REL_OR (1<<1)
|
||||||
|
#define TCF_EM_INVERT (1<<2)
|
||||||
|
#define TCF_EM_SIMPLE (1<<3)
|
||||||
|
|
||||||
|
#define TCF_EM_REL_MASK 3
|
||||||
|
#define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCF_LAYER_LINK,
|
||||||
|
TCF_LAYER_NETWORK,
|
||||||
|
TCF_LAYER_TRANSPORT,
|
||||||
|
__TCF_LAYER_MAX
|
||||||
|
};
|
||||||
|
#define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1)
|
||||||
|
|
||||||
|
/* Ematch type assignments
|
||||||
|
* 1..32767 Reserved for ematches inside kernel tree
|
||||||
|
* 32768..65535 Free to use, not reliable
|
||||||
|
*/
|
||||||
|
#define TCF_EM_CONTAINER 0
|
||||||
|
#define TCF_EM_CMP 1
|
||||||
|
#define TCF_EM_NBYTE 2
|
||||||
|
#define TCF_EM_U32 3
|
||||||
|
#define TCF_EM_META 4
|
||||||
|
#define TCF_EM_TEXT 5
|
||||||
|
#define TCF_EM_VLAN 6
|
||||||
|
#define TCF_EM_CANID 7
|
||||||
|
#define TCF_EM_IPSET 8
|
||||||
|
#define TCF_EM_IPT 9
|
||||||
|
#define TCF_EM_MAX 9
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCF_EM_PROG_TC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCF_EM_OPND_EQ,
|
||||||
|
TCF_EM_OPND_GT,
|
||||||
|
TCF_EM_OPND_LT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
1164
include/uapi/linux/pkt_sched.h
Normal file
1164
include/uapi/linux/pkt_sched.h
Normal file
File diff suppressed because it is too large
Load Diff
81
scripts/build-fuzzers.sh
Executable file
81
scripts/build-fuzzers.sh
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
SANITIZER=${SANITIZER:-address}
|
||||||
|
flags="-O1 -fno-omit-frame-pointer -g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link"
|
||||||
|
|
||||||
|
export CC=${CC:-clang}
|
||||||
|
export CFLAGS=${CFLAGS:-$flags}
|
||||||
|
|
||||||
|
export CXX=${CXX:-clang++}
|
||||||
|
export CXXFLAGS=${CXXFLAGS:-$flags}
|
||||||
|
|
||||||
|
cd "$(dirname -- "$0")/.."
|
||||||
|
|
||||||
|
export OUT=${OUT:-"$(pwd)/out"}
|
||||||
|
mkdir -p "$OUT"
|
||||||
|
|
||||||
|
export LIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}
|
||||||
|
|
||||||
|
# libelf is compiled with _FORTIFY_SOURCE by default and it
|
||||||
|
# isn't compatible with MSan. It was borrowed
|
||||||
|
# from https://github.com/google/oss-fuzz/pull/7422
|
||||||
|
if [[ "$SANITIZER" == memory ]]; then
|
||||||
|
CFLAGS+=" -U_FORTIFY_SOURCE"
|
||||||
|
CXXFLAGS+=" -U_FORTIFY_SOURCE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The alignment check is turned off by default on OSS-Fuzz/CFLite so it should be
|
||||||
|
# turned on explicitly there. It was borrowed from
|
||||||
|
# https://github.com/google/oss-fuzz/pull/7092
|
||||||
|
if [[ "$SANITIZER" == undefined ]]; then
|
||||||
|
additional_ubsan_checks=alignment
|
||||||
|
UBSAN_FLAGS="-fsanitize=$additional_ubsan_checks -fno-sanitize-recover=$additional_ubsan_checks"
|
||||||
|
CFLAGS+=" $UBSAN_FLAGS"
|
||||||
|
CXXFLAGS+=" $UBSAN_FLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ideally libbelf should be built using release tarballs available
|
||||||
|
# at https://sourceware.org/elfutils/ftp/. Unfortunately sometimes they
|
||||||
|
# fail to compile (for example, elfutils-0.185 fails to compile with LDFLAGS enabled
|
||||||
|
# due to https://bugs.gentoo.org/794601) so let's just point the script to
|
||||||
|
# commits referring to versions of libelf that actually can be built
|
||||||
|
rm -rf elfutils
|
||||||
|
git clone git://sourceware.org/git/elfutils.git
|
||||||
|
(
|
||||||
|
cd elfutils
|
||||||
|
git checkout 83251d4091241acddbdcf16f814e3bc6ef3df49a
|
||||||
|
git log --oneline -1
|
||||||
|
|
||||||
|
# ASan isn't compatible with -Wl,--no-undefined: https://github.com/google/sanitizers/issues/380
|
||||||
|
find -name Makefile.am | xargs sed -i 's/,--no-undefined//'
|
||||||
|
|
||||||
|
# ASan isn't compatible with -Wl,-z,defs either:
|
||||||
|
# https://clang.llvm.org/docs/AddressSanitizer.html#usage
|
||||||
|
sed -i 's/^\(ZDEFS_LDFLAGS=\).*/\1/' configure.ac
|
||||||
|
|
||||||
|
if [[ "$SANITIZER" == undefined ]]; then
|
||||||
|
# That's basicaly what --enable-sanitize-undefined does to turn off unaligned access
|
||||||
|
# elfutils heavily relies on on i386/x86_64 but without changing compiler flags along the way
|
||||||
|
sed -i 's/\(check_undefined_val\)=[0-9]/\1=1/' configure.ac
|
||||||
|
fi
|
||||||
|
|
||||||
|
autoreconf -i -f
|
||||||
|
if ! ./configure --enable-maintainer-mode --disable-debuginfod --disable-libdebuginfod \
|
||||||
|
CC="$CC" CFLAGS="-Wno-error $CFLAGS" CXX="$CXX" CXXFLAGS="-Wno-error $CXXFLAGS" LDFLAGS="$CFLAGS"; then
|
||||||
|
cat config.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
make -C config -j$(nproc) V=1
|
||||||
|
make -C lib -j$(nproc) V=1
|
||||||
|
make -C libelf -j$(nproc) V=1
|
||||||
|
)
|
||||||
|
|
||||||
|
make -C src BUILD_STATIC_ONLY=y V=1 clean
|
||||||
|
make -C src -j$(nproc) CFLAGS="-I$(pwd)/elfutils/libelf $CFLAGS" BUILD_STATIC_ONLY=y V=1
|
||||||
|
|
||||||
|
$CC $CFLAGS -Isrc -Iinclude -Iinclude/uapi -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c fuzz/bpf-object-fuzzer.c -o bpf-object-fuzzer.o
|
||||||
|
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE bpf-object-fuzzer.o src/libbpf.a "$(pwd)/elfutils/libelf/libelf.a" -l:libz.a -o "$OUT/bpf-object-fuzzer"
|
||||||
|
|
||||||
|
cp fuzz/bpf-object-fuzzer_seed_corpus.zip "$OUT"
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
tfile=$(mktemp /tmp/test_reallocarray_XXXXXXXX.c)
|
|
||||||
ofile=${tfile%.c}.o
|
|
||||||
|
|
||||||
cat > $tfile <<EOL
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
return !!reallocarray(NULL, 1, 1);
|
|
||||||
}
|
|
||||||
EOL
|
|
||||||
|
|
||||||
gcc $tfile -o $ofile >/dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then echo "FAIL"; fi
|
|
||||||
/bin/rm -f $tfile $ofile
|
|
||||||
105
scripts/coverity.sh
Executable file
105
scripts/coverity.sh
Executable file
@@ -0,0 +1,105 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Taken from: https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh
|
||||||
|
# Local changes are annotated with "#[local]"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Environment check
|
||||||
|
echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m"
|
||||||
|
[ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1
|
||||||
|
[ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1
|
||||||
|
[ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1
|
||||||
|
[ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1
|
||||||
|
[ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1
|
||||||
|
|
||||||
|
PLATFORM=`uname`
|
||||||
|
#[local] Use /var/tmp for TOOL_ARCHIVE and TOOL_BASE, as on certain systems
|
||||||
|
# /tmp is tmpfs and is sometimes too small to handle all necessary tooling
|
||||||
|
TOOL_ARCHIVE=/var//tmp/cov-analysis-${PLATFORM}.tgz
|
||||||
|
TOOL_URL=https://scan.coverity.com/download/${PLATFORM}
|
||||||
|
TOOL_BASE=/var/tmp/coverity-scan-analysis
|
||||||
|
UPLOAD_URL="https://scan.coverity.com/builds"
|
||||||
|
SCAN_URL="https://scan.coverity.com"
|
||||||
|
|
||||||
|
# Do not run on pull requests
|
||||||
|
if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then
|
||||||
|
echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify this branch should run
|
||||||
|
IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"`
|
||||||
|
if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then
|
||||||
|
echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m"
|
||||||
|
else
|
||||||
|
echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify upload is permitted
|
||||||
|
AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted`
|
||||||
|
if [ "$AUTH_RES" = "Access denied" ]; then
|
||||||
|
echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"`
|
||||||
|
if [ "$AUTH" = "true" ]; then
|
||||||
|
echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m"
|
||||||
|
else
|
||||||
|
WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"`
|
||||||
|
echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d $TOOL_BASE ]; then
|
||||||
|
# Download Coverity Scan Analysis Tool
|
||||||
|
if [ ! -e $TOOL_ARCHIVE ]; then
|
||||||
|
echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m"
|
||||||
|
wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract Coverity Scan Analysis Tool
|
||||||
|
echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m"
|
||||||
|
mkdir -p $TOOL_BASE
|
||||||
|
pushd $TOOL_BASE
|
||||||
|
tar xzf $TOOL_ARCHIVE
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'`
|
||||||
|
export PATH=$TOOL_DIR/bin:$PATH
|
||||||
|
|
||||||
|
# Build
|
||||||
|
echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m"
|
||||||
|
COV_BUILD_OPTIONS=""
|
||||||
|
#COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85"
|
||||||
|
RESULTS_DIR="cov-int"
|
||||||
|
eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}"
|
||||||
|
COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND
|
||||||
|
cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt 2>&1
|
||||||
|
|
||||||
|
# Upload results
|
||||||
|
echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m"
|
||||||
|
RESULTS_ARCHIVE=analysis-results.tgz
|
||||||
|
tar czf $RESULTS_ARCHIVE $RESULTS_DIR
|
||||||
|
SHA=`git rev-parse --short HEAD`
|
||||||
|
|
||||||
|
echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m"
|
||||||
|
response=$(curl \
|
||||||
|
--silent --write-out "\n%{http_code}\n" \
|
||||||
|
--form project=$COVERITY_SCAN_PROJECT_NAME \
|
||||||
|
--form token=$COVERITY_SCAN_TOKEN \
|
||||||
|
--form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \
|
||||||
|
--form file=@$RESULTS_ARCHIVE \
|
||||||
|
--form version=$SHA \
|
||||||
|
--form description="Travis CI build" \
|
||||||
|
$UPLOAD_URL)
|
||||||
|
status_code=$(echo "$response" | sed -n '$p')
|
||||||
|
#[local] Coverity used to return 201 on success, but it's 200 now
|
||||||
|
# See https://github.com/systemd/systemd/blob/master/tools/coverity.sh#L145
|
||||||
|
if [ "$status_code" != "200" ]; then
|
||||||
|
TEXT=$(echo "$response" | sed '$d')
|
||||||
|
echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -6,7 +6,6 @@ usage () {
|
|||||||
echo "Set BPF_NEXT_BASELINE to override bpf-next tree commit, otherwise read from <libbpf-repo>/CHECKPOINT-COMMIT."
|
echo "Set BPF_NEXT_BASELINE to override bpf-next tree commit, otherwise read from <libbpf-repo>/CHECKPOINT-COMMIT."
|
||||||
echo "Set BPF_BASELINE to override bpf tree commit, otherwise read from <libbpf-repo>/BPF-CHECKPOINT-COMMIT."
|
echo "Set BPF_BASELINE to override bpf tree commit, otherwise read from <libbpf-repo>/BPF-CHECKPOINT-COMMIT."
|
||||||
echo "Set MANUAL_MODE to 1 to manually control every cherry-picked commits."
|
echo "Set MANUAL_MODE to 1 to manually control every cherry-picked commits."
|
||||||
echo "Set IGNORE_CONSISTENCY to 1 to ignore failed contents consistency check."
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ BPF_BRANCH=${3-""}
|
|||||||
BASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)}
|
BASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)}
|
||||||
BPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat ${LIBBPF_REPO}/BPF-CHECKPOINT-COMMIT)}
|
BPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat ${LIBBPF_REPO}/BPF-CHECKPOINT-COMMIT)}
|
||||||
|
|
||||||
if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ] || [ -z "${BPF_BRANCH}" ]; then
|
if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ]; then
|
||||||
echo "Error: libbpf or linux repos are not specified"
|
echo "Error: libbpf or linux repos are not specified"
|
||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
@@ -46,18 +45,22 @@ PATH_MAP=( \
|
|||||||
[tools/include/uapi/linux/if_link.h]=include/uapi/linux/if_link.h \
|
[tools/include/uapi/linux/if_link.h]=include/uapi/linux/if_link.h \
|
||||||
[tools/include/uapi/linux/if_xdp.h]=include/uapi/linux/if_xdp.h \
|
[tools/include/uapi/linux/if_xdp.h]=include/uapi/linux/if_xdp.h \
|
||||||
[tools/include/uapi/linux/netlink.h]=include/uapi/linux/netlink.h \
|
[tools/include/uapi/linux/netlink.h]=include/uapi/linux/netlink.h \
|
||||||
[tools/include/tools/libc_compat.h]=include/tools/libc_compat.h \
|
[tools/include/uapi/linux/pkt_cls.h]=include/uapi/linux/pkt_cls.h \
|
||||||
|
[tools/include/uapi/linux/pkt_sched.h]=include/uapi/linux/pkt_sched.h \
|
||||||
|
[include/uapi/linux/perf_event.h]=include/uapi/linux/perf_event.h \
|
||||||
|
[Documentation/bpf/libbpf]=docs \
|
||||||
)
|
)
|
||||||
|
|
||||||
LIBBPF_PATHS="${!PATH_MAP[@]}"
|
LIBBPF_PATHS="${!PATH_MAP[@]} :^tools/lib/bpf/Makefile :^tools/lib/bpf/Build :^tools/lib/bpf/.gitignore :^tools/include/tools/libc_compat.h"
|
||||||
LIBBPF_VIEW_PATHS="${PATH_MAP[@]}"
|
LIBBPF_VIEW_PATHS="${PATH_MAP[@]}"
|
||||||
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf.cpp|\.gitignore)$'
|
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf\.c|bpf_helper_defs\.h|\.gitignore)$|^docs/(\.gitignore|api\.rst|conf\.py)$|^docs/sphinx/.*'
|
||||||
|
LINUX_VIEW_EXCLUDE_REGEX='^include/tools/libc_compat.h$'
|
||||||
|
|
||||||
LIBBPF_TREE_FILTER="mkdir -p __libbpf/include/uapi/linux __libbpf/include/tools && "$'\\\n'
|
LIBBPF_TREE_FILTER="mkdir -p __libbpf/include/uapi/linux __libbpf/include/tools && "$'\\\n'
|
||||||
for p in "${!PATH_MAP[@]}"; do
|
for p in "${!PATH_MAP[@]}"; do
|
||||||
LIBBPF_TREE_FILTER+="git mv -kf ${p} __libbpf/${PATH_MAP[${p}]} && "$'\\\n'
|
LIBBPF_TREE_FILTER+="git mv -kf ${p} __libbpf/${PATH_MAP[${p}]} && "$'\\\n'
|
||||||
done
|
done
|
||||||
LIBBPF_TREE_FILTER+="git rm --ignore-unmatch -f __libbpf/src/{Makefile,Build,test_libbpf.cpp,.gitignore} >/dev/null"
|
LIBBPF_TREE_FILTER+="git rm --ignore-unmatch -f __libbpf/src/{Makefile,Build,test_libbpf.c,.gitignore} >/dev/null"
|
||||||
|
|
||||||
cd_to()
|
cd_to()
|
||||||
{
|
{
|
||||||
@@ -72,46 +75,17 @@ commit_desc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Create commit single-line signature, which consists of:
|
# Create commit single-line signature, which consists of:
|
||||||
# - full commit hash
|
# - full commit subject
|
||||||
# - author date in ISO8601 format
|
# - author date in ISO8601 format
|
||||||
# - full commit body with newlines replaced with vertical bars (|)
|
# - full commit body with newlines replaced with vertical bars (|)
|
||||||
# - shortstat appended at the end
|
# - shortstat appended at the end
|
||||||
# The idea is that this single-line signature is good enough to make final
|
# The idea is that this single-line signature is good enough to make final
|
||||||
# decision about whether two commits are the same, across different repos.
|
# decision about whether two commits are the same, across different repos.
|
||||||
# $1 - commit ref
|
# $1 - commit ref
|
||||||
|
# $2 - paths filter
|
||||||
commit_signature()
|
commit_signature()
|
||||||
{
|
{
|
||||||
git log -n1 --pretty='("%s")|%aI|%b' --shortstat $1 | tr '\n' '|'
|
git show --pretty='("%s")|%aI|%b' --shortstat $1 -- ${2-.} | tr '\n' '|'
|
||||||
}
|
|
||||||
|
|
||||||
# Validate there are no non-empty merges (we can't handle them)
|
|
||||||
# $1 - baseline tag
|
|
||||||
# $2 - tip tag
|
|
||||||
validate_merges()
|
|
||||||
{
|
|
||||||
local baseline_tag=$1
|
|
||||||
local tip_tag=$2
|
|
||||||
local new_merges
|
|
||||||
local merge_change_cnt
|
|
||||||
local ignore_merge_resolutions
|
|
||||||
local desc
|
|
||||||
|
|
||||||
new_merges=$(git rev-list --merges --topo-order --reverse ${baseline_tag}..${tip_tag} ${LIBBPF_PATHS[@]})
|
|
||||||
for new_merge in ${new_merges}; do
|
|
||||||
desc=$(commit_desc ${new_merge})
|
|
||||||
echo "MERGE: ${desc}"
|
|
||||||
merge_change_cnt=$(git show --format='' ${new_merge} | wc -l)
|
|
||||||
if ((${merge_change_cnt} > 0)); then
|
|
||||||
read -p "Merge '${desc}' is non-empty, which will cause conflicts! Do you want to proceed? [y/N]: " ignore_merge_resolutions
|
|
||||||
case "${ignore_merge_resolutions}" in
|
|
||||||
"y" | "Y")
|
|
||||||
echo "Skipping '${desc}'..."
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Cherry-pick commits touching libbpf-related files
|
# Cherry-pick commits touching libbpf-related files
|
||||||
@@ -133,7 +107,7 @@ cherry_pick_commits()
|
|||||||
new_commits=$(git rev-list --no-merges --topo-order --reverse ${baseline_tag}..${tip_tag} ${LIBBPF_PATHS[@]})
|
new_commits=$(git rev-list --no-merges --topo-order --reverse ${baseline_tag}..${tip_tag} ${LIBBPF_PATHS[@]})
|
||||||
for new_commit in ${new_commits}; do
|
for new_commit in ${new_commits}; do
|
||||||
desc="$(commit_desc ${new_commit})"
|
desc="$(commit_desc ${new_commit})"
|
||||||
signature="$(commit_signature ${new_commit})"
|
signature="$(commit_signature ${new_commit} "${LIBBPF_PATHS[@]}")"
|
||||||
synced_cnt=$(grep -F "${signature}" ${TMP_DIR}/libbpf_commits.txt | wc -l)
|
synced_cnt=$(grep -F "${signature}" ${TMP_DIR}/libbpf_commits.txt | wc -l)
|
||||||
manual_check=0
|
manual_check=0
|
||||||
if ((${synced_cnt} > 0)); then
|
if ((${synced_cnt} > 0)); then
|
||||||
@@ -166,6 +140,7 @@ cherry_pick_commits()
|
|||||||
echo "Warning! Cherry-picking '${desc} failed, checking if it's non-libbpf files causing problems..."
|
echo "Warning! Cherry-picking '${desc} failed, checking if it's non-libbpf files causing problems..."
|
||||||
libbpf_conflict_cnt=$(git diff --name-only --diff-filter=U -- ${LIBBPF_PATHS[@]} | wc -l)
|
libbpf_conflict_cnt=$(git diff --name-only --diff-filter=U -- ${LIBBPF_PATHS[@]} | wc -l)
|
||||||
conflict_cnt=$(git diff --name-only | wc -l)
|
conflict_cnt=$(git diff --name-only | wc -l)
|
||||||
|
prompt_resolution=1
|
||||||
|
|
||||||
if ((${libbpf_conflict_cnt} == 0)); then
|
if ((${libbpf_conflict_cnt} == 0)); then
|
||||||
echo "Looks like only non-libbpf files have conflicts, ignoring..."
|
echo "Looks like only non-libbpf files have conflicts, ignoring..."
|
||||||
@@ -181,16 +156,39 @@ cherry_pick_commits()
|
|||||||
echo "Error! That still failed! Please resolve manually."
|
echo "Error! That still failed! Please resolve manually."
|
||||||
else
|
else
|
||||||
echo "Success! All cherry-pick conflicts were resolved for '${desc}'!"
|
echo "Success! All cherry-pick conflicts were resolved for '${desc}'!"
|
||||||
continue
|
prompt_resolution=0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -p "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
|
if ((${prompt_resolution} == 1)); then
|
||||||
|
read -p "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
# Append signature of just cherry-picked commit to avoid
|
||||||
|
# potentially cherry-picking the same commit twice later when
|
||||||
|
# processing bpf tree commits. At this point we don't know yet
|
||||||
|
# the final commit sha in libbpf repo, so we record Linux SHA
|
||||||
|
# instead as LINUX_<sha>.
|
||||||
|
echo LINUX_$(git log --pretty='%h' -n1) "${signature}" >> ${TMP_DIR}/libbpf_commits.txt
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
echo "Cleaning up..."
|
||||||
|
rm -r ${TMP_DIR}
|
||||||
|
cd_to ${LINUX_REPO}
|
||||||
|
git checkout ${TIP_SYM_REF}
|
||||||
|
git branch -D ${BASELINE_TAG} ${TIP_TAG} ${BPF_BASELINE_TAG} ${BPF_TIP_TAG} \
|
||||||
|
${SQUASH_BASE_TAG} ${SQUASH_TIP_TAG} ${VIEW_TAG} || true
|
||||||
|
|
||||||
|
cd_to .
|
||||||
|
echo "DONE."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cd_to ${LIBBPF_REPO}
|
cd_to ${LIBBPF_REPO}
|
||||||
|
GITHUB_ABS_DIR=$(pwd)
|
||||||
echo "Dumping existing libbpf commit signatures..."
|
echo "Dumping existing libbpf commit signatures..."
|
||||||
for h in $(git log --pretty='%h' -n500); do
|
for h in $(git log --pretty='%h' -n500); do
|
||||||
echo $h "$(commit_signature $h)" >> ${TMP_DIR}/libbpf_commits.txt
|
echo $h "$(commit_signature $h)" >> ${TMP_DIR}/libbpf_commits.txt
|
||||||
@@ -198,6 +196,7 @@ done
|
|||||||
|
|
||||||
# Use current kernel repo HEAD as a source of patches
|
# Use current kernel repo HEAD as a source of patches
|
||||||
cd_to ${LINUX_REPO}
|
cd_to ${LINUX_REPO}
|
||||||
|
LINUX_ABS_DIR=$(pwd)
|
||||||
TIP_SYM_REF=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
|
TIP_SYM_REF=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
|
||||||
TIP_COMMIT=$(git rev-parse HEAD)
|
TIP_COMMIT=$(git rev-parse HEAD)
|
||||||
BPF_TIP_COMMIT=$(git rev-parse ${BPF_BRANCH})
|
BPF_TIP_COMMIT=$(git rev-parse ${BPF_BRANCH})
|
||||||
@@ -240,23 +239,20 @@ git branch ${BPF_TIP_TAG} ${BPF_TIP_COMMIT}
|
|||||||
git branch ${SQUASH_BASE_TAG} ${SQUASH_COMMIT}
|
git branch ${SQUASH_BASE_TAG} ${SQUASH_COMMIT}
|
||||||
git checkout -b ${SQUASH_TIP_TAG} ${SQUASH_COMMIT}
|
git checkout -b ${SQUASH_TIP_TAG} ${SQUASH_COMMIT}
|
||||||
|
|
||||||
# Validate there are no non-empty merges in bpf-next and bpf trees
|
|
||||||
validate_merges ${BASELINE_TAG} ${TIP_TAG}
|
|
||||||
validate_merges ${BPF_BASELINE_TAG} ${BPF_TIP_TAG}
|
|
||||||
|
|
||||||
# Cherry-pick new commits onto squashed baseline commit
|
# Cherry-pick new commits onto squashed baseline commit
|
||||||
cherry_pick_commits ${BASELINE_TAG} ${TIP_TAG}
|
cherry_pick_commits ${BASELINE_TAG} ${TIP_TAG}
|
||||||
cherry_pick_commits ${BPF_BASELINE_TAG} ${BPF_TIP_TAG}
|
cherry_pick_commits ${BPF_BASELINE_TAG} ${BPF_TIP_TAG}
|
||||||
|
|
||||||
# Move all libbpf files into __libbpf directory.
|
# Move all libbpf files into __libbpf directory.
|
||||||
git filter-branch --prune-empty -f --tree-filter "${LIBBPF_TREE_FILTER}" ${SQUASH_TIP_TAG} ${SQUASH_BASE_TAG}
|
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --prune-empty -f --tree-filter "${LIBBPF_TREE_FILTER}" ${SQUASH_TIP_TAG} ${SQUASH_BASE_TAG}
|
||||||
# Make __libbpf a new root directory
|
# Make __libbpf a new root directory
|
||||||
git filter-branch --prune-empty -f --subdirectory-filter __libbpf ${SQUASH_TIP_TAG} ${SQUASH_BASE_TAG}
|
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --prune-empty -f --subdirectory-filter __libbpf ${SQUASH_TIP_TAG} ${SQUASH_BASE_TAG}
|
||||||
|
|
||||||
# If there are no new commits with libbpf-related changes, bail out
|
# If there are no new commits with libbpf-related changes, bail out
|
||||||
COMMIT_CNT=$(git rev-list --count ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG})
|
COMMIT_CNT=$(git rev-list --count ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG})
|
||||||
if ((${COMMIT_CNT} <= 0)); then
|
if ((${COMMIT_CNT} <= 0)); then
|
||||||
echo "No new changes to apply, we are done!"
|
echo "No new changes to apply, we are done!"
|
||||||
|
cleanup
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -268,11 +264,32 @@ cd_to ${LIBBPF_REPO}
|
|||||||
git checkout -b ${LIBBPF_SYNC_TAG}
|
git checkout -b ${LIBBPF_SYNC_TAG}
|
||||||
|
|
||||||
for patch in $(ls -1 ${TMP_DIR}/patches | tail -n +2); do
|
for patch in $(ls -1 ${TMP_DIR}/patches | tail -n +2); do
|
||||||
if ! git am --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
|
if ! git am -3 --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
|
||||||
read -p "Applying ${TMP_DIR}/patches/${patch} failed, please resolve manually and press <return> to proceed..."
|
if ! patch -p1 --merge < "${TMP_DIR}/patches/${patch}"; then
|
||||||
|
read -p "Applying ${TMP_DIR}/patches/${patch} failed, please resolve manually and press <return> to proceed..."
|
||||||
|
fi
|
||||||
|
git am --continue
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Generate bpf_helper_defs.h and commit, if anything changed
|
||||||
|
# restore Linux tip to use bpf_doc.py
|
||||||
|
cd_to ${LINUX_REPO}
|
||||||
|
git checkout ${TIP_TAG}
|
||||||
|
# re-generate bpf_helper_defs.h
|
||||||
|
cd_to ${LIBBPF_REPO}
|
||||||
|
"${LINUX_ABS_DIR}/scripts/bpf_doc.py" --header \
|
||||||
|
--file include/uapi/linux/bpf.h > src/bpf_helper_defs.h
|
||||||
|
# if anything changed, commit it
|
||||||
|
helpers_changes=$(git status --porcelain src/bpf_helper_defs.h | wc -l)
|
||||||
|
if ((${helpers_changes} == 1)); then
|
||||||
|
git add src/bpf_helper_defs.h
|
||||||
|
git commit -m "sync: auto-generate latest BPF helpers
|
||||||
|
|
||||||
|
Latest changes to BPF helper definitions.
|
||||||
|
" -- src/bpf_helper_defs.h
|
||||||
|
fi
|
||||||
|
|
||||||
# Use generated cover-letter as a template for "sync commit" with
|
# Use generated cover-letter as a template for "sync commit" with
|
||||||
# baseline and checkpoint commits from kernel repo (and leave summary
|
# baseline and checkpoint commits from kernel repo (and leave summary
|
||||||
# from cover letter intact, of course)
|
# from cover letter intact, of course)
|
||||||
@@ -296,14 +313,12 @@ echo "SUCCESS! ${COMMIT_CNT} commits synced."
|
|||||||
echo "Verifying Linux's and Github's libbpf state"
|
echo "Verifying Linux's and Github's libbpf state"
|
||||||
|
|
||||||
cd_to ${LINUX_REPO}
|
cd_to ${LINUX_REPO}
|
||||||
LINUX_ABS_DIR=$(pwd)
|
|
||||||
git checkout -b ${VIEW_TAG} ${TIP_COMMIT}
|
git checkout -b ${VIEW_TAG} ${TIP_COMMIT}
|
||||||
git filter-branch -f --tree-filter "${LIBBPF_TREE_FILTER}" ${VIEW_TAG}^..${VIEW_TAG}
|
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --tree-filter "${LIBBPF_TREE_FILTER}" ${VIEW_TAG}^..${VIEW_TAG}
|
||||||
git filter-branch -f --subdirectory-filter __libbpf ${VIEW_TAG}^..${VIEW_TAG}
|
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --subdirectory-filter __libbpf ${VIEW_TAG}^..${VIEW_TAG}
|
||||||
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} > ${TMP_DIR}/linux-view.ls
|
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} | grep -v -E "${LINUX_VIEW_EXCLUDE_REGEX}" > ${TMP_DIR}/linux-view.ls
|
||||||
|
|
||||||
cd_to ${LIBBPF_REPO}
|
cd_to ${LIBBPF_REPO}
|
||||||
GITHUB_ABS_DIR=$(pwd)
|
|
||||||
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} | grep -v -E "${LIBBPF_VIEW_EXCLUDE_REGEX}" > ${TMP_DIR}/github-view.ls
|
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} | grep -v -E "${LIBBPF_VIEW_EXCLUDE_REGEX}" > ${TMP_DIR}/github-view.ls
|
||||||
|
|
||||||
echo "Comparing list of files..."
|
echo "Comparing list of files..."
|
||||||
@@ -319,19 +334,17 @@ done
|
|||||||
if ((${CONSISTENT} == 1)); then
|
if ((${CONSISTENT} == 1)); then
|
||||||
echo "Great! Content is identical!"
|
echo "Great! Content is identical!"
|
||||||
else
|
else
|
||||||
echo "Unfortunately, there are consistency problems!"
|
ignore_inconsistency=n
|
||||||
if ((${IGNORE_CONSISTENCY-0} != 1)); then
|
echo "Unfortunately, there are some inconsistencies, please double check."
|
||||||
exit 4
|
read -p "Does everything look good? [y/N]: " ignore_inconsistency
|
||||||
fi
|
case "${ignore_inconsistency}" in
|
||||||
|
"y" | "Y")
|
||||||
|
echo "Ok, proceeding..."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Oops, exiting with error..."
|
||||||
|
exit 4
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Cleaning up..."
|
cleanup
|
||||||
rm -r ${TMP_DIR}
|
|
||||||
cd_to ${LINUX_REPO}
|
|
||||||
git checkout ${TIP_SYM_REF}
|
|
||||||
git branch -D ${BASELINE_TAG} ${TIP_TAG} ${BPF_BASELINE_TAG} ${BPF_TIP_TAG} \
|
|
||||||
${SQUASH_BASE_TAG} ${SQUASH_TIP_TAG} ${VIEW_TAG}
|
|
||||||
|
|
||||||
cd_to .
|
|
||||||
echo "DONE."
|
|
||||||
|
|
||||||
|
|||||||
133
src/Makefile
133
src/Makefile
@@ -1,39 +1,58 @@
|
|||||||
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
LIBBPF_VERSION := $(shell \
|
ifeq ($(V),1)
|
||||||
grep -oE '^LIBBPF_([0-9.]+)' libbpf.map | \
|
Q =
|
||||||
sort -rV | head -n1 | cut -d'_' -f2)
|
msg =
|
||||||
LIBBPF_MAJOR_VERSION := $(firstword $(subst ., ,$(LIBBPF_VERSION)))
|
else
|
||||||
|
Q = @
|
||||||
|
msg = @printf ' %-8s %s%s\n' "$(1)" "$(2)" "$(if $(3), $(3))";
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIBBPF_MAJOR_VERSION := 1
|
||||||
|
LIBBPF_MINOR_VERSION := 0
|
||||||
|
LIBBPF_PATCH_VERSION := 0
|
||||||
|
LIBBPF_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).$(LIBBPF_PATCH_VERSION)
|
||||||
|
LIBBPF_MAJMIN_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).0
|
||||||
|
LIBBPF_MAP_VERSION := $(shell grep -oE '^LIBBPF_([0-9.]+)' libbpf.map | sort -rV | head -n1 | cut -d'_' -f2)
|
||||||
|
ifneq ($(LIBBPF_MAJMIN_VERSION), $(LIBBPF_MAP_VERSION))
|
||||||
|
$(error Libbpf release ($(LIBBPF_VERSION)) and map ($(LIBBPF_MAP_VERSION)) versions are out of sync!)
|
||||||
|
endif
|
||||||
|
|
||||||
|
define allow-override
|
||||||
|
$(if $(or $(findstring environment,$(origin $(1))),\
|
||||||
|
$(findstring command line,$(origin $(1)))),,\
|
||||||
|
$(eval $(1) = $(2)))
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(call allow-override,CC,$(CROSS_COMPILE)cc)
|
||||||
|
$(call allow-override,LD,$(CROSS_COMPILE)ld)
|
||||||
|
|
||||||
TOPDIR = ..
|
TOPDIR = ..
|
||||||
|
|
||||||
INCLUDES := -I. -I$(TOPDIR)/include -I$(TOPDIR)/include/uapi
|
INCLUDES := -I. -I$(TOPDIR)/include -I$(TOPDIR)/include/uapi
|
||||||
ALL_CFLAGS := $(INCLUDES)
|
ALL_CFLAGS := $(INCLUDES)
|
||||||
|
|
||||||
FEATURE_REALLOCARRAY := $(shell $(TOPDIR)/scripts/check-reallocarray.sh)
|
|
||||||
ifneq ($(FEATURE_REALLOCARRAY),)
|
|
||||||
ALL_CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
|
|
||||||
endif
|
|
||||||
|
|
||||||
SHARED_CFLAGS += -fPIC -fvisibility=hidden -DSHARED
|
SHARED_CFLAGS += -fPIC -fvisibility=hidden -DSHARED
|
||||||
|
|
||||||
CFLAGS ?= -g -O2 -Werror -Wall
|
CFLAGS ?= -g -O2 -Werror -Wall -std=gnu89
|
||||||
ALL_CFLAGS += $(CFLAGS)
|
ALL_CFLAGS += $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 $(EXTRA_CFLAGS)
|
||||||
ALL_LDFLAGS += $(LDFLAGS)
|
ALL_LDFLAGS += $(LDFLAGS) $(EXTRA_LDFLAGS)
|
||||||
|
|
||||||
ifdef NO_PKG_CONFIG
|
ifdef NO_PKG_CONFIG
|
||||||
ALL_LDFLAGS += -lelf
|
ALL_LDFLAGS += -lelf -lz
|
||||||
else
|
else
|
||||||
PKG_CONFIG ?= pkg-config
|
PKG_CONFIG ?= pkg-config
|
||||||
ALL_CFLAGS += $(shell $(PKG_CONFIG) --cflags libelf)
|
ALL_CFLAGS += $(shell $(PKG_CONFIG) --cflags libelf zlib)
|
||||||
ALL_LDFLAGS += $(shell $(PKG_CONFIG) --libs libelf)
|
ALL_LDFLAGS += $(shell $(PKG_CONFIG) --libs libelf zlib)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJDIR ?= .
|
OBJDIR ?= .
|
||||||
SHARED_OBJDIR := $(OBJDIR)/sharedobjs
|
SHARED_OBJDIR := $(OBJDIR)/sharedobjs
|
||||||
STATIC_OBJDIR := $(OBJDIR)/staticobjs
|
STATIC_OBJDIR := $(OBJDIR)/staticobjs
|
||||||
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
||||||
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o xsk.o \
|
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o \
|
||||||
btf_dump.o hashmap.o
|
btf_dump.o hashmap.o ringbuf.o strset.o linker.o gen_loader.o \
|
||||||
|
relo_core.o usdt.o
|
||||||
SHARED_OBJS := $(addprefix $(SHARED_OBJDIR)/,$(OBJS))
|
SHARED_OBJS := $(addprefix $(SHARED_OBJDIR)/,$(OBJS))
|
||||||
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
||||||
|
|
||||||
@@ -45,7 +64,10 @@ ifndef BUILD_STATIC_ONLY
|
|||||||
VERSION_SCRIPT := libbpf.map
|
VERSION_SCRIPT := libbpf.map
|
||||||
endif
|
endif
|
||||||
|
|
||||||
HEADERS := bpf.h libbpf.h btf.h xsk.h libbpf_util.h
|
HEADERS := bpf.h libbpf.h btf.h libbpf_common.h libbpf_legacy.h \
|
||||||
|
bpf_helpers.h bpf_helper_defs.h bpf_tracing.h \
|
||||||
|
bpf_endian.h bpf_core_read.h skel_internal.h libbpf_version.h \
|
||||||
|
usdt.bpf.h
|
||||||
UAPI_HEADERS := $(addprefix $(TOPDIR)/include/uapi/linux/,\
|
UAPI_HEADERS := $(addprefix $(TOPDIR)/include/uapi/linux/,\
|
||||||
bpf.h bpf_common.h btf.h)
|
bpf.h bpf_common.h btf.h)
|
||||||
|
|
||||||
@@ -55,64 +77,77 @@ INSTALL = install
|
|||||||
|
|
||||||
DESTDIR ?=
|
DESTDIR ?=
|
||||||
|
|
||||||
ifeq ($(shell uname -m),x86_64)
|
ifeq ($(filter-out %64 %64be %64eb %64le %64el s390x, $(shell uname -m)),)
|
||||||
LIBSUBDIR := lib64
|
LIBSUBDIR := lib64
|
||||||
else
|
else
|
||||||
LIBSUBDIR := lib
|
LIBSUBDIR := lib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# By default let the pc file itself use ${prefix} in includedir/libdir so that
|
||||||
|
# the prefix can be overridden at runtime (eg: --define-prefix)
|
||||||
|
ifndef LIBDIR
|
||||||
|
LIBDIR_PC := $$\{prefix\}/$(LIBSUBDIR)
|
||||||
|
else
|
||||||
|
LIBDIR_PC := $(LIBDIR)
|
||||||
|
endif
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
LIBDIR ?= $(PREFIX)/$(LIBSUBDIR)
|
LIBDIR ?= $(PREFIX)/$(LIBSUBDIR)
|
||||||
INCLUDEDIR ?= $(PREFIX)/include
|
INCLUDEDIR ?= $(PREFIX)/include
|
||||||
UAPIDIR ?= $(PREFIX)/include
|
UAPIDIR ?= $(PREFIX)/include
|
||||||
|
|
||||||
|
TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
|
||||||
|
|
||||||
all: $(STATIC_LIBS) $(SHARED_LIBS) $(PC_FILE)
|
all: $(STATIC_LIBS) $(SHARED_LIBS) $(PC_FILE)
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.a: $(STATIC_OBJS)
|
$(OBJDIR)/libbpf.a: $(STATIC_OBJS)
|
||||||
$(AR) rcs $@ $^
|
$(call msg,AR,$@)
|
||||||
|
$(Q)$(AR) rcs $@ $^
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so: $(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION)
|
$(OBJDIR)/libbpf.so: $(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION)
|
||||||
ln -sf $(^F) $@
|
$(Q)ln -sf $(^F) $@
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION): $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
$(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION): $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
||||||
ln -sf $(^F) $@
|
$(Q)ln -sf $(^F) $@
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(SHARED_OBJS)
|
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(SHARED_OBJS)
|
||||||
$(CC) -shared -Wl,--version-script=$(VERSION_SCRIPT) \
|
$(call msg,CC,$@)
|
||||||
-Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
$(Q)$(CC) -shared -Wl,--version-script=$(VERSION_SCRIPT) \
|
||||||
$^ $(ALL_LDFLAGS) -o $@
|
-Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
||||||
|
$^ $(ALL_LDFLAGS) -o $@
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.pc:
|
$(OBJDIR)/libbpf.pc: force
|
||||||
sed -e "s|@PREFIX@|$(PREFIX)|" \
|
$(Q)sed -e "s|@PREFIX@|$(PREFIX)|" \
|
||||||
-e "s|@LIBDIR@|$(LIBDIR)|" \
|
-e "s|@LIBDIR@|$(LIBDIR_PC)|" \
|
||||||
-e "s|@VERSION@|$(LIBBPF_VERSION)|" \
|
-e "s|@VERSION@|$(LIBBPF_VERSION)|" \
|
||||||
< libbpf.pc.template > $@
|
< libbpf.pc.template > $@
|
||||||
|
|
||||||
$(STATIC_OBJDIR):
|
$(STATIC_OBJDIR) $(SHARED_OBJDIR):
|
||||||
mkdir -p $(STATIC_OBJDIR)
|
$(call msg,MKDIR,$@)
|
||||||
|
$(Q)mkdir -p $@
|
||||||
$(SHARED_OBJDIR):
|
|
||||||
mkdir -p $(SHARED_OBJDIR)
|
|
||||||
|
|
||||||
$(STATIC_OBJDIR)/%.o: %.c | $(STATIC_OBJDIR)
|
$(STATIC_OBJDIR)/%.o: %.c | $(STATIC_OBJDIR)
|
||||||
$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
$(call msg,CC,$@)
|
||||||
|
$(Q)$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(SHARED_OBJDIR)/%.o: %.c | $(SHARED_OBJDIR)
|
$(SHARED_OBJDIR)/%.o: %.c | $(SHARED_OBJDIR)
|
||||||
$(CC) $(ALL_CFLAGS) $(SHARED_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
$(call msg,CC,$@)
|
||||||
|
$(Q)$(CC) $(ALL_CFLAGS) $(SHARED_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
define do_install
|
define do_install
|
||||||
if [ ! -d '$(DESTDIR)$2' ]; then \
|
$(call msg,INSTALL,$1)
|
||||||
|
$(Q)if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||||
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
||||||
fi; \
|
fi;
|
||||||
$(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR)$2'
|
$(Q)$(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR)$2'
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# Preserve symlinks at installation.
|
# Preserve symlinks at installation.
|
||||||
define do_s_install
|
define do_s_install
|
||||||
if [ ! -d '$(DESTDIR)$2' ]; then \
|
$(call msg,INSTALL,$1)
|
||||||
|
$(Q)if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||||
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
||||||
fi; \
|
fi;
|
||||||
cp -fpR $1 '$(DESTDIR)$2'
|
$(Q)cp -fR $1 '$(DESTDIR)$2'
|
||||||
endef
|
endef
|
||||||
|
|
||||||
install: all install_headers install_pkgconfig
|
install: all install_headers install_pkgconfig
|
||||||
@@ -130,4 +165,18 @@ install_pkgconfig: $(PC_FILE)
|
|||||||
$(call do_install,$(PC_FILE),$(LIBDIR)/pkgconfig,644)
|
$(call do_install,$(PC_FILE),$(LIBDIR)/pkgconfig,644)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o *.a *.so *.so.* *.pc $(SHARED_OBJDIR) $(STATIC_OBJDIR)
|
$(call msg,CLEAN)
|
||||||
|
$(Q)rm -rf *.o *.a *.so *.so.* *.pc $(SHARED_OBJDIR) $(STATIC_OBJDIR)
|
||||||
|
|
||||||
|
.PHONY: cscope tags force
|
||||||
|
cscope:
|
||||||
|
$(call msg,CSCOPE)
|
||||||
|
$(Q)ls *.c *.h > cscope.files
|
||||||
|
$(Q)cscope -b -q -f cscope.out
|
||||||
|
|
||||||
|
tags:
|
||||||
|
$(call msg,CTAGS)
|
||||||
|
$(Q)rm -f TAGS tags
|
||||||
|
$(Q)ls *.c *.h | xargs $(TAGS_PROG) -a
|
||||||
|
|
||||||
|
force:
|
||||||
|
|||||||
394
src/bpf.h
394
src/bpf.h
@@ -28,86 +28,100 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "libbpf_common.h"
|
||||||
|
#include "libbpf_legacy.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LIBBPF_API
|
int libbpf_set_memlock_rlim(size_t memlock_bytes);
|
||||||
#define LIBBPF_API __attribute__((visibility("default")))
|
|
||||||
#endif
|
struct bpf_map_create_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
|
||||||
struct bpf_create_map_attr {
|
|
||||||
const char *name;
|
|
||||||
enum bpf_map_type map_type;
|
|
||||||
__u32 map_flags;
|
|
||||||
__u32 key_size;
|
|
||||||
__u32 value_size;
|
|
||||||
__u32 max_entries;
|
|
||||||
__u32 numa_node;
|
|
||||||
__u32 btf_fd;
|
__u32 btf_fd;
|
||||||
__u32 btf_key_type_id;
|
__u32 btf_key_type_id;
|
||||||
__u32 btf_value_type_id;
|
__u32 btf_value_type_id;
|
||||||
__u32 map_ifindex;
|
__u32 btf_vmlinux_value_type_id;
|
||||||
|
|
||||||
__u32 inner_map_fd;
|
__u32 inner_map_fd;
|
||||||
|
__u32 map_flags;
|
||||||
|
__u64 map_extra;
|
||||||
|
|
||||||
|
__u32 numa_node;
|
||||||
|
__u32 map_ifindex;
|
||||||
};
|
};
|
||||||
|
#define bpf_map_create_opts__last_field map_ifindex
|
||||||
|
|
||||||
LIBBPF_API int
|
LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
|
||||||
bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr);
|
const char *map_name,
|
||||||
LIBBPF_API int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
|
__u32 key_size,
|
||||||
int key_size, int value_size,
|
__u32 value_size,
|
||||||
int max_entries, __u32 map_flags, int node);
|
__u32 max_entries,
|
||||||
LIBBPF_API int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
|
const struct bpf_map_create_opts *opts);
|
||||||
int key_size, int value_size,
|
|
||||||
int max_entries, __u32 map_flags);
|
struct bpf_prog_load_opts {
|
||||||
LIBBPF_API int bpf_create_map(enum bpf_map_type map_type, int key_size,
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
int value_size, int max_entries, __u32 map_flags);
|
|
||||||
LIBBPF_API int bpf_create_map_in_map_node(enum bpf_map_type map_type,
|
/* libbpf can retry BPF_PROG_LOAD command if bpf() syscall returns
|
||||||
const char *name, int key_size,
|
* -EAGAIN. This field determines how many attempts libbpf has to
|
||||||
int inner_map_fd, int max_entries,
|
* make. If not specified, libbpf will use default value of 5.
|
||||||
__u32 map_flags, int node);
|
*/
|
||||||
LIBBPF_API int bpf_create_map_in_map(enum bpf_map_type map_type,
|
int attempts;
|
||||||
const char *name, int key_size,
|
|
||||||
int inner_map_fd, int max_entries,
|
|
||||||
__u32 map_flags);
|
|
||||||
|
|
||||||
struct bpf_load_program_attr {
|
|
||||||
enum bpf_prog_type prog_type;
|
|
||||||
enum bpf_attach_type expected_attach_type;
|
enum bpf_attach_type expected_attach_type;
|
||||||
const char *name;
|
|
||||||
const struct bpf_insn *insns;
|
|
||||||
size_t insns_cnt;
|
|
||||||
const char *license;
|
|
||||||
__u32 kern_version;
|
|
||||||
__u32 prog_ifindex;
|
|
||||||
__u32 prog_btf_fd;
|
__u32 prog_btf_fd;
|
||||||
__u32 func_info_rec_size;
|
__u32 prog_flags;
|
||||||
|
__u32 prog_ifindex;
|
||||||
|
__u32 kern_version;
|
||||||
|
|
||||||
|
__u32 attach_btf_id;
|
||||||
|
__u32 attach_prog_fd;
|
||||||
|
__u32 attach_btf_obj_fd;
|
||||||
|
|
||||||
|
const int *fd_array;
|
||||||
|
|
||||||
|
/* .BTF.ext func info data */
|
||||||
const void *func_info;
|
const void *func_info;
|
||||||
__u32 func_info_cnt;
|
__u32 func_info_cnt;
|
||||||
__u32 line_info_rec_size;
|
__u32 func_info_rec_size;
|
||||||
|
|
||||||
|
/* .BTF.ext line info data */
|
||||||
const void *line_info;
|
const void *line_info;
|
||||||
__u32 line_info_cnt;
|
__u32 line_info_cnt;
|
||||||
|
__u32 line_info_rec_size;
|
||||||
|
|
||||||
|
/* verifier log options */
|
||||||
__u32 log_level;
|
__u32 log_level;
|
||||||
__u32 prog_flags;
|
__u32 log_size;
|
||||||
|
char *log_buf;
|
||||||
};
|
};
|
||||||
|
#define bpf_prog_load_opts__last_field log_buf
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_prog_load(enum bpf_prog_type prog_type,
|
||||||
|
const char *prog_name, const char *license,
|
||||||
|
const struct bpf_insn *insns, size_t insn_cnt,
|
||||||
|
const struct bpf_prog_load_opts *opts);
|
||||||
|
|
||||||
/* Flags to direct loading requirements */
|
/* Flags to direct loading requirements */
|
||||||
#define MAPS_RELAX_COMPAT 0x01
|
#define MAPS_RELAX_COMPAT 0x01
|
||||||
|
|
||||||
/* Recommend log buffer size */
|
/* Recommended log buffer size */
|
||||||
#define BPF_LOG_BUF_SIZE (UINT32_MAX >> 8) /* verifier maximum in kernels <= 5.1 */
|
#define BPF_LOG_BUF_SIZE (UINT32_MAX >> 8) /* verifier maximum in kernels <= 5.1 */
|
||||||
LIBBPF_API int
|
|
||||||
bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
|
struct bpf_btf_load_opts {
|
||||||
char *log_buf, size_t log_buf_sz);
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
LIBBPF_API int bpf_load_program(enum bpf_prog_type type,
|
|
||||||
const struct bpf_insn *insns, size_t insns_cnt,
|
/* kernel log options */
|
||||||
const char *license, __u32 kern_version,
|
char *log_buf;
|
||||||
char *log_buf, size_t log_buf_sz);
|
__u32 log_level;
|
||||||
LIBBPF_API int bpf_verify_program(enum bpf_prog_type type,
|
__u32 log_size;
|
||||||
const struct bpf_insn *insns,
|
};
|
||||||
size_t insns_cnt, __u32 prog_flags,
|
#define bpf_btf_load_opts__last_field log_size
|
||||||
const char *license, __u32 kern_version,
|
|
||||||
char *log_buf, size_t log_buf_sz,
|
LIBBPF_API int bpf_btf_load(const void *btf_data, size_t btf_size,
|
||||||
int log_level);
|
const struct bpf_btf_load_opts *opts);
|
||||||
|
|
||||||
LIBBPF_API int bpf_map_update_elem(int fd, const void *key, const void *value,
|
LIBBPF_API int bpf_map_update_elem(int fd, const void *key, const void *value,
|
||||||
__u64 flags);
|
__u64 flags);
|
||||||
@@ -117,17 +131,219 @@ LIBBPF_API int bpf_map_lookup_elem_flags(int fd, const void *key, void *value,
|
|||||||
__u64 flags);
|
__u64 flags);
|
||||||
LIBBPF_API int bpf_map_lookup_and_delete_elem(int fd, const void *key,
|
LIBBPF_API int bpf_map_lookup_and_delete_elem(int fd, const void *key,
|
||||||
void *value);
|
void *value);
|
||||||
|
LIBBPF_API int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key,
|
||||||
|
void *value, __u64 flags);
|
||||||
LIBBPF_API int bpf_map_delete_elem(int fd, const void *key);
|
LIBBPF_API int bpf_map_delete_elem(int fd, const void *key);
|
||||||
|
LIBBPF_API int bpf_map_delete_elem_flags(int fd, const void *key, __u64 flags);
|
||||||
LIBBPF_API int bpf_map_get_next_key(int fd, const void *key, void *next_key);
|
LIBBPF_API int bpf_map_get_next_key(int fd, const void *key, void *next_key);
|
||||||
LIBBPF_API int bpf_map_freeze(int fd);
|
LIBBPF_API int bpf_map_freeze(int fd);
|
||||||
|
|
||||||
|
struct bpf_map_batch_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
__u64 elem_flags;
|
||||||
|
__u64 flags;
|
||||||
|
};
|
||||||
|
#define bpf_map_batch_opts__last_field flags
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map_delete_batch()** allows for batch deletion of multiple
|
||||||
|
* elements in a BPF map.
|
||||||
|
*
|
||||||
|
* @param fd BPF map file descriptor
|
||||||
|
* @param keys pointer to an array of *count* keys
|
||||||
|
* @param count input and output parameter; on input **count** represents the
|
||||||
|
* number of elements in the map to delete in batch;
|
||||||
|
* on output if a non-EFAULT error is returned, **count** represents the number of deleted
|
||||||
|
* elements if the output **count** value is not equal to the input **count** value
|
||||||
|
* If EFAULT is returned, **count** should not be trusted to be correct.
|
||||||
|
* @param opts options for configuring the way the batch deletion works
|
||||||
|
* @return 0, on success; negative error code, otherwise (errno is also set to
|
||||||
|
* the error code)
|
||||||
|
*/
|
||||||
|
LIBBPF_API int bpf_map_delete_batch(int fd, const void *keys,
|
||||||
|
__u32 *count,
|
||||||
|
const struct bpf_map_batch_opts *opts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map_lookup_batch()** allows for batch lookup of BPF map elements.
|
||||||
|
*
|
||||||
|
* The parameter *in_batch* is the address of the first element in the batch to read.
|
||||||
|
* *out_batch* is an output parameter that should be passed as *in_batch* to subsequent
|
||||||
|
* calls to **bpf_map_lookup_batch()**. NULL can be passed for *in_batch* to indicate
|
||||||
|
* that the batched lookup starts from the beginning of the map.
|
||||||
|
*
|
||||||
|
* The *keys* and *values* are output parameters which must point to memory large enough to
|
||||||
|
* hold *count* items based on the key and value size of the map *map_fd*. The *keys*
|
||||||
|
* buffer must be of *key_size* * *count*. The *values* buffer must be of
|
||||||
|
* *value_size* * *count*.
|
||||||
|
*
|
||||||
|
* @param fd BPF map file descriptor
|
||||||
|
* @param in_batch address of the first element in batch to read, can pass NULL to
|
||||||
|
* indicate that the batched lookup starts from the beginning of the map.
|
||||||
|
* @param out_batch output parameter that should be passed to next call as *in_batch*
|
||||||
|
* @param keys pointer to an array large enough for *count* keys
|
||||||
|
* @param values pointer to an array large enough for *count* values
|
||||||
|
* @param count input and output parameter; on input it's the number of elements
|
||||||
|
* in the map to read in batch; on output it's the number of elements that were
|
||||||
|
* successfully read.
|
||||||
|
* If a non-EFAULT error is returned, count will be set as the number of elements
|
||||||
|
* that were read before the error occurred.
|
||||||
|
* If EFAULT is returned, **count** should not be trusted to be correct.
|
||||||
|
* @param opts options for configuring the way the batch lookup works
|
||||||
|
* @return 0, on success; negative error code, otherwise (errno is also set to
|
||||||
|
* the error code)
|
||||||
|
*/
|
||||||
|
LIBBPF_API int bpf_map_lookup_batch(int fd, void *in_batch, void *out_batch,
|
||||||
|
void *keys, void *values, __u32 *count,
|
||||||
|
const struct bpf_map_batch_opts *opts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map_lookup_and_delete_batch()** allows for batch lookup and deletion
|
||||||
|
* of BPF map elements where each element is deleted after being retrieved.
|
||||||
|
*
|
||||||
|
* @param fd BPF map file descriptor
|
||||||
|
* @param in_batch address of the first element in batch to read, can pass NULL to
|
||||||
|
* get address of the first element in *out_batch*
|
||||||
|
* @param out_batch output parameter that should be passed to next call as *in_batch*
|
||||||
|
* @param keys pointer to an array of *count* keys
|
||||||
|
* @param values pointer to an array large enough for *count* values
|
||||||
|
* @param count input and output parameter; on input it's the number of elements
|
||||||
|
* in the map to read and delete in batch; on output it represents the number of
|
||||||
|
* elements that were successfully read and deleted
|
||||||
|
* If a non-**EFAULT** error code is returned and if the output **count** value
|
||||||
|
* is not equal to the input **count** value, up to **count** elements may
|
||||||
|
* have been deleted.
|
||||||
|
* if **EFAULT** is returned up to *count* elements may have been deleted without
|
||||||
|
* being returned via the *keys* and *values* output parameters.
|
||||||
|
* @param opts options for configuring the way the batch lookup and delete works
|
||||||
|
* @return 0, on success; negative error code, otherwise (errno is also set to
|
||||||
|
* the error code)
|
||||||
|
*/
|
||||||
|
LIBBPF_API int bpf_map_lookup_and_delete_batch(int fd, void *in_batch,
|
||||||
|
void *out_batch, void *keys,
|
||||||
|
void *values, __u32 *count,
|
||||||
|
const struct bpf_map_batch_opts *opts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **bpf_map_update_batch()** updates multiple elements in a map
|
||||||
|
* by specifying keys and their corresponding values.
|
||||||
|
*
|
||||||
|
* The *keys* and *values* parameters must point to memory large enough
|
||||||
|
* to hold *count* items based on the key and value size of the map.
|
||||||
|
*
|
||||||
|
* The *opts* parameter can be used to control how *bpf_map_update_batch()*
|
||||||
|
* should handle keys that either do or do not already exist in the map.
|
||||||
|
* In particular the *flags* parameter of *bpf_map_batch_opts* can be
|
||||||
|
* one of the following:
|
||||||
|
*
|
||||||
|
* Note that *count* is an input and output parameter, where on output it
|
||||||
|
* represents how many elements were successfully updated. Also note that if
|
||||||
|
* **EFAULT** then *count* should not be trusted to be correct.
|
||||||
|
*
|
||||||
|
* **BPF_ANY**
|
||||||
|
* Create new elements or update existing.
|
||||||
|
*
|
||||||
|
* **BPF_NOEXIST**
|
||||||
|
* Create new elements only if they do not exist.
|
||||||
|
*
|
||||||
|
* **BPF_EXIST**
|
||||||
|
* Update existing elements.
|
||||||
|
*
|
||||||
|
* **BPF_F_LOCK**
|
||||||
|
* Update spin_lock-ed map elements. This must be
|
||||||
|
* specified if the map value contains a spinlock.
|
||||||
|
*
|
||||||
|
* @param fd BPF map file descriptor
|
||||||
|
* @param keys pointer to an array of *count* keys
|
||||||
|
* @param values pointer to an array of *count* values
|
||||||
|
* @param count input and output parameter; on input it's the number of elements
|
||||||
|
* in the map to update in batch; on output if a non-EFAULT error is returned,
|
||||||
|
* **count** represents the number of updated elements if the output **count**
|
||||||
|
* value is not equal to the input **count** value.
|
||||||
|
* If EFAULT is returned, **count** should not be trusted to be correct.
|
||||||
|
* @param opts options for configuring the way the batch update works
|
||||||
|
* @return 0, on success; negative error code, otherwise (errno is also set to
|
||||||
|
* the error code)
|
||||||
|
*/
|
||||||
|
LIBBPF_API int bpf_map_update_batch(int fd, const void *keys, const void *values,
|
||||||
|
__u32 *count,
|
||||||
|
const struct bpf_map_batch_opts *opts);
|
||||||
|
|
||||||
|
struct bpf_obj_get_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
|
||||||
|
__u32 file_flags;
|
||||||
|
|
||||||
|
size_t :0;
|
||||||
|
};
|
||||||
|
#define bpf_obj_get_opts__last_field file_flags
|
||||||
|
|
||||||
LIBBPF_API int bpf_obj_pin(int fd, const char *pathname);
|
LIBBPF_API int bpf_obj_pin(int fd, const char *pathname);
|
||||||
LIBBPF_API int bpf_obj_get(const char *pathname);
|
LIBBPF_API int bpf_obj_get(const char *pathname);
|
||||||
|
LIBBPF_API int bpf_obj_get_opts(const char *pathname,
|
||||||
|
const struct bpf_obj_get_opts *opts);
|
||||||
|
|
||||||
|
struct bpf_prog_attach_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
unsigned int flags;
|
||||||
|
int replace_prog_fd;
|
||||||
|
};
|
||||||
|
#define bpf_prog_attach_opts__last_field replace_prog_fd
|
||||||
|
|
||||||
LIBBPF_API int bpf_prog_attach(int prog_fd, int attachable_fd,
|
LIBBPF_API int bpf_prog_attach(int prog_fd, int attachable_fd,
|
||||||
enum bpf_attach_type type, unsigned int flags);
|
enum bpf_attach_type type, unsigned int flags);
|
||||||
|
LIBBPF_API int bpf_prog_attach_opts(int prog_fd, int attachable_fd,
|
||||||
|
enum bpf_attach_type type,
|
||||||
|
const struct bpf_prog_attach_opts *opts);
|
||||||
LIBBPF_API int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);
|
LIBBPF_API int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);
|
||||||
LIBBPF_API int bpf_prog_detach2(int prog_fd, int attachable_fd,
|
LIBBPF_API int bpf_prog_detach2(int prog_fd, int attachable_fd,
|
||||||
enum bpf_attach_type type);
|
enum bpf_attach_type type);
|
||||||
|
|
||||||
|
union bpf_iter_link_info; /* defined in up-to-date linux/bpf.h */
|
||||||
|
struct bpf_link_create_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
__u32 flags;
|
||||||
|
union bpf_iter_link_info *iter_info;
|
||||||
|
__u32 iter_info_len;
|
||||||
|
__u32 target_btf_id;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
__u64 bpf_cookie;
|
||||||
|
} perf_event;
|
||||||
|
struct {
|
||||||
|
__u32 flags;
|
||||||
|
__u32 cnt;
|
||||||
|
const char **syms;
|
||||||
|
const unsigned long *addrs;
|
||||||
|
const __u64 *cookies;
|
||||||
|
} kprobe_multi;
|
||||||
|
struct {
|
||||||
|
__u64 cookie;
|
||||||
|
} tracing;
|
||||||
|
};
|
||||||
|
size_t :0;
|
||||||
|
};
|
||||||
|
#define bpf_link_create_opts__last_field kprobe_multi.cookies
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
|
||||||
|
enum bpf_attach_type attach_type,
|
||||||
|
const struct bpf_link_create_opts *opts);
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_link_detach(int link_fd);
|
||||||
|
|
||||||
|
struct bpf_link_update_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
__u32 flags; /* extra flags */
|
||||||
|
__u32 old_prog_fd; /* expected old program FD */
|
||||||
|
};
|
||||||
|
#define bpf_link_update_opts__last_field old_prog_fd
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_link_update(int link_fd, int new_prog_fd,
|
||||||
|
const struct bpf_link_update_opts *opts);
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_iter_create(int link_fd);
|
||||||
|
|
||||||
struct bpf_prog_test_run_attr {
|
struct bpf_prog_test_run_attr {
|
||||||
int prog_fd;
|
int prog_fd;
|
||||||
int repeat;
|
int repeat;
|
||||||
@@ -145,32 +361,76 @@ struct bpf_prog_test_run_attr {
|
|||||||
* out: length of cxt_out */
|
* out: length of cxt_out */
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBBPF_API int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* bpf_prog_test_run does not check that data_out is large enough. Consider
|
|
||||||
* using bpf_prog_test_run_xattr instead.
|
|
||||||
*/
|
|
||||||
LIBBPF_API int bpf_prog_test_run(int prog_fd, int repeat, void *data,
|
|
||||||
__u32 size, void *data_out, __u32 *size_out,
|
|
||||||
__u32 *retval, __u32 *duration);
|
|
||||||
LIBBPF_API int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id);
|
LIBBPF_API int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id);
|
||||||
LIBBPF_API int bpf_map_get_next_id(__u32 start_id, __u32 *next_id);
|
LIBBPF_API int bpf_map_get_next_id(__u32 start_id, __u32 *next_id);
|
||||||
LIBBPF_API int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id);
|
LIBBPF_API int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id);
|
||||||
|
LIBBPF_API int bpf_link_get_next_id(__u32 start_id, __u32 *next_id);
|
||||||
LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
|
LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
|
||||||
LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
|
LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
|
||||||
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
|
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
|
||||||
LIBBPF_API int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len);
|
LIBBPF_API int bpf_link_get_fd_by_id(__u32 id);
|
||||||
|
LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
|
||||||
|
|
||||||
|
struct bpf_prog_query_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
__u32 query_flags;
|
||||||
|
__u32 attach_flags; /* output argument */
|
||||||
|
__u32 *prog_ids;
|
||||||
|
__u32 prog_cnt; /* input+output argument */
|
||||||
|
__u32 *prog_attach_flags;
|
||||||
|
};
|
||||||
|
#define bpf_prog_query_opts__last_field prog_attach_flags
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_prog_query_opts(int target_fd,
|
||||||
|
enum bpf_attach_type type,
|
||||||
|
struct bpf_prog_query_opts *opts);
|
||||||
LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
|
LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
|
||||||
__u32 query_flags, __u32 *attach_flags,
|
__u32 query_flags, __u32 *attach_flags,
|
||||||
__u32 *prog_ids, __u32 *prog_cnt);
|
__u32 *prog_ids, __u32 *prog_cnt);
|
||||||
|
|
||||||
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
|
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
|
||||||
LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
|
|
||||||
__u32 log_buf_size, bool do_log);
|
|
||||||
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
||||||
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
|
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
|
||||||
__u64 *probe_offset, __u64 *probe_addr);
|
__u64 *probe_offset, __u64 *probe_addr);
|
||||||
|
|
||||||
|
enum bpf_stats_type; /* defined in up-to-date linux/bpf.h */
|
||||||
|
LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);
|
||||||
|
|
||||||
|
struct bpf_prog_bind_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
__u32 flags;
|
||||||
|
};
|
||||||
|
#define bpf_prog_bind_opts__last_field flags
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_prog_bind_map(int prog_fd, int map_fd,
|
||||||
|
const struct bpf_prog_bind_opts *opts);
|
||||||
|
|
||||||
|
struct bpf_test_run_opts {
|
||||||
|
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||||
|
const void *data_in; /* optional */
|
||||||
|
void *data_out; /* optional */
|
||||||
|
__u32 data_size_in;
|
||||||
|
__u32 data_size_out; /* in: max length of data_out
|
||||||
|
* out: length of data_out
|
||||||
|
*/
|
||||||
|
const void *ctx_in; /* optional */
|
||||||
|
void *ctx_out; /* optional */
|
||||||
|
__u32 ctx_size_in;
|
||||||
|
__u32 ctx_size_out; /* in: max length of ctx_out
|
||||||
|
* out: length of cxt_out
|
||||||
|
*/
|
||||||
|
__u32 retval; /* out: return code of the BPF program */
|
||||||
|
int repeat;
|
||||||
|
__u32 duration; /* out: average per repetition in ns */
|
||||||
|
__u32 flags;
|
||||||
|
__u32 cpu;
|
||||||
|
__u32 batch_size;
|
||||||
|
};
|
||||||
|
#define bpf_test_run_opts__last_field batch_size
|
||||||
|
|
||||||
|
LIBBPF_API int bpf_prog_test_run_opts(int prog_fd,
|
||||||
|
struct bpf_test_run_opts *opts);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
484
src/bpf_core_read.h
Normal file
484
src/bpf_core_read.h
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
#ifndef __BPF_CORE_READ_H__
|
||||||
|
#define __BPF_CORE_READ_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enum bpf_field_info_kind is passed as a second argument into
|
||||||
|
* __builtin_preserve_field_info() built-in to get a specific aspect of
|
||||||
|
* a field, captured as a first argument. __builtin_preserve_field_info(field,
|
||||||
|
* info_kind) returns __u32 integer and produces BTF field relocation, which
|
||||||
|
* is understood and processed by libbpf during BPF object loading. See
|
||||||
|
* selftests/bpf for examples.
|
||||||
|
*/
|
||||||
|
enum bpf_field_info_kind {
|
||||||
|
BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */
|
||||||
|
BPF_FIELD_BYTE_SIZE = 1,
|
||||||
|
BPF_FIELD_EXISTS = 2, /* field existence in target kernel */
|
||||||
|
BPF_FIELD_SIGNED = 3,
|
||||||
|
BPF_FIELD_LSHIFT_U64 = 4,
|
||||||
|
BPF_FIELD_RSHIFT_U64 = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* second argument to __builtin_btf_type_id() built-in */
|
||||||
|
enum bpf_type_id_kind {
|
||||||
|
BPF_TYPE_ID_LOCAL = 0, /* BTF type ID in local program */
|
||||||
|
BPF_TYPE_ID_TARGET = 1, /* BTF type ID in target kernel */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* second argument to __builtin_preserve_type_info() built-in */
|
||||||
|
enum bpf_type_info_kind {
|
||||||
|
BPF_TYPE_EXISTS = 0, /* type existence in target kernel */
|
||||||
|
BPF_TYPE_SIZE = 1, /* type size in target kernel */
|
||||||
|
BPF_TYPE_MATCHES = 2, /* type match in target kernel */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* second argument to __builtin_preserve_enum_value() built-in */
|
||||||
|
enum bpf_enum_value_kind {
|
||||||
|
BPF_ENUMVAL_EXISTS = 0, /* enum value existence in kernel */
|
||||||
|
BPF_ENUMVAL_VALUE = 1, /* enum value value relocation */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __CORE_RELO(src, field, info) \
|
||||||
|
__builtin_preserve_field_info((src)->field, BPF_FIELD_##info)
|
||||||
|
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
||||||
|
bpf_probe_read_kernel( \
|
||||||
|
(void *)dst, \
|
||||||
|
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||||
|
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||||
|
#else
|
||||||
|
/* semantics of LSHIFT_64 assumes loading values into low-ordered bytes, so
|
||||||
|
* for big-endian we need to adjust destination pointer accordingly, based on
|
||||||
|
* field byte size
|
||||||
|
*/
|
||||||
|
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
||||||
|
bpf_probe_read_kernel( \
|
||||||
|
(void *)dst + (8 - __CORE_RELO(src, fld, BYTE_SIZE)), \
|
||||||
|
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||||
|
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract bitfield, identified by s->field, and return its value as u64.
|
||||||
|
* All this is done in relocatable manner, so bitfield changes such as
|
||||||
|
* signedness, bit size, offset changes, this will be handled automatically.
|
||||||
|
* This version of macro is using bpf_probe_read_kernel() to read underlying
|
||||||
|
* integer storage. Macro functions as an expression and its return type is
|
||||||
|
* bpf_probe_read_kernel()'s return value: 0, on success, <0 on error.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_BITFIELD_PROBED(s, field) ({ \
|
||||||
|
unsigned long long val = 0; \
|
||||||
|
\
|
||||||
|
__CORE_BITFIELD_PROBE_READ(&val, s, field); \
|
||||||
|
val <<= __CORE_RELO(s, field, LSHIFT_U64); \
|
||||||
|
if (__CORE_RELO(s, field, SIGNED)) \
|
||||||
|
val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \
|
||||||
|
else \
|
||||||
|
val = val >> __CORE_RELO(s, field, RSHIFT_U64); \
|
||||||
|
val; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract bitfield, identified by s->field, and return its value as u64.
|
||||||
|
* This version of macro is using direct memory reads and should be used from
|
||||||
|
* BPF program types that support such functionality (e.g., typed raw
|
||||||
|
* tracepoints).
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_BITFIELD(s, field) ({ \
|
||||||
|
const void *p = (const void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \
|
||||||
|
unsigned long long val; \
|
||||||
|
\
|
||||||
|
/* This is a so-called barrier_var() operation that makes specified \
|
||||||
|
* variable "a black box" for optimizing compiler. \
|
||||||
|
* It forces compiler to perform BYTE_OFFSET relocation on p and use \
|
||||||
|
* its calculated value in the switch below, instead of applying \
|
||||||
|
* the same relocation 4 times for each individual memory load. \
|
||||||
|
*/ \
|
||||||
|
asm volatile("" : "=r"(p) : "0"(p)); \
|
||||||
|
\
|
||||||
|
switch (__CORE_RELO(s, field, BYTE_SIZE)) { \
|
||||||
|
case 1: val = *(const unsigned char *)p; break; \
|
||||||
|
case 2: val = *(const unsigned short *)p; break; \
|
||||||
|
case 4: val = *(const unsigned int *)p; break; \
|
||||||
|
case 8: val = *(const unsigned long long *)p; break; \
|
||||||
|
} \
|
||||||
|
val <<= __CORE_RELO(s, field, LSHIFT_U64); \
|
||||||
|
if (__CORE_RELO(s, field, SIGNED)) \
|
||||||
|
val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \
|
||||||
|
else \
|
||||||
|
val = val >> __CORE_RELO(s, field, RSHIFT_U64); \
|
||||||
|
val; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define ___bpf_field_ref1(field) (field)
|
||||||
|
#define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field)
|
||||||
|
#define ___bpf_field_ref(args...) \
|
||||||
|
___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to check that field actually exists in target kernel's.
|
||||||
|
* Returns:
|
||||||
|
* 1, if matching field is present in target kernel;
|
||||||
|
* 0, if no matching field found.
|
||||||
|
*
|
||||||
|
* Supports two forms:
|
||||||
|
* - field reference through variable access:
|
||||||
|
* bpf_core_field_exists(p->my_field);
|
||||||
|
* - field reference through type and field names:
|
||||||
|
* bpf_core_field_exists(struct my_type, my_field).
|
||||||
|
*/
|
||||||
|
#define bpf_core_field_exists(field...) \
|
||||||
|
__builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_EXISTS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get the byte size of a field. Works for integers,
|
||||||
|
* struct/unions, pointers, arrays, and enums.
|
||||||
|
*
|
||||||
|
* Supports two forms:
|
||||||
|
* - field reference through variable access:
|
||||||
|
* bpf_core_field_size(p->my_field);
|
||||||
|
* - field reference through type and field names:
|
||||||
|
* bpf_core_field_size(struct my_type, my_field).
|
||||||
|
*/
|
||||||
|
#define bpf_core_field_size(field...) \
|
||||||
|
__builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_SIZE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get field's byte offset.
|
||||||
|
*
|
||||||
|
* Supports two forms:
|
||||||
|
* - field reference through variable access:
|
||||||
|
* bpf_core_field_offset(p->my_field);
|
||||||
|
* - field reference through type and field names:
|
||||||
|
* bpf_core_field_offset(struct my_type, my_field).
|
||||||
|
*/
|
||||||
|
#define bpf_core_field_offset(field...) \
|
||||||
|
__builtin_preserve_field_info(___bpf_field_ref(field), BPF_FIELD_BYTE_OFFSET)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get BTF type ID of a specified type, using a local BTF
|
||||||
|
* information. Return 32-bit unsigned integer with type ID from program's own
|
||||||
|
* BTF. Always succeeds.
|
||||||
|
*/
|
||||||
|
#define bpf_core_type_id_local(type) \
|
||||||
|
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_LOCAL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get BTF type ID of a target kernel's type that matches
|
||||||
|
* specified local type.
|
||||||
|
* Returns:
|
||||||
|
* - valid 32-bit unsigned type ID in kernel BTF;
|
||||||
|
* - 0, if no matching type was found in a target kernel BTF.
|
||||||
|
*/
|
||||||
|
#define bpf_core_type_id_kernel(type) \
|
||||||
|
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_TARGET)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to check that provided named type
|
||||||
|
* (struct/union/enum/typedef) exists in a target kernel.
|
||||||
|
* Returns:
|
||||||
|
* 1, if such type is present in target kernel's BTF;
|
||||||
|
* 0, if no matching type is found.
|
||||||
|
*/
|
||||||
|
#define bpf_core_type_exists(type) \
|
||||||
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_EXISTS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to check that provided named type
|
||||||
|
* (struct/union/enum/typedef) "matches" that in a target kernel.
|
||||||
|
* Returns:
|
||||||
|
* 1, if the type matches in the target kernel's BTF;
|
||||||
|
* 0, if the type does not match any in the target kernel
|
||||||
|
*/
|
||||||
|
#define bpf_core_type_matches(type) \
|
||||||
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_MATCHES)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get the byte size of a provided named type
|
||||||
|
* (struct/union/enum/typedef) in a target kernel.
|
||||||
|
* Returns:
|
||||||
|
* >= 0 size (in bytes), if type is present in target kernel's BTF;
|
||||||
|
* 0, if no matching type is found.
|
||||||
|
*/
|
||||||
|
#define bpf_core_type_size(type) \
|
||||||
|
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_SIZE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to check that provided enumerator value is defined in
|
||||||
|
* a target kernel.
|
||||||
|
* Returns:
|
||||||
|
* 1, if specified enum type and its enumerator value are present in target
|
||||||
|
* kernel's BTF;
|
||||||
|
* 0, if no matching enum and/or enum value within that enum is found.
|
||||||
|
*/
|
||||||
|
#define bpf_core_enum_value_exists(enum_type, enum_value) \
|
||||||
|
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_EXISTS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience macro to get the integer value of an enumerator value in
|
||||||
|
* a target kernel.
|
||||||
|
* Returns:
|
||||||
|
* 64-bit value, if specified enum type and its enumerator value are
|
||||||
|
* present in target kernel's BTF;
|
||||||
|
* 0, if no matching enum and/or enum value within that enum is found.
|
||||||
|
*/
|
||||||
|
#define bpf_core_enum_value(enum_type, enum_value) \
|
||||||
|
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_VALUE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bpf_core_read() abstracts away bpf_probe_read_kernel() call and captures
|
||||||
|
* offset relocation for source address using __builtin_preserve_access_index()
|
||||||
|
* built-in, provided by Clang.
|
||||||
|
*
|
||||||
|
* __builtin_preserve_access_index() takes as an argument an expression of
|
||||||
|
* taking an address of a field within struct/union. It makes compiler emit
|
||||||
|
* a relocation, which records BTF type ID describing root struct/union and an
|
||||||
|
* accessor string which describes exact embedded field that was used to take
|
||||||
|
* an address. See detailed description of this relocation format and
|
||||||
|
* semantics in comments to struct bpf_field_reloc in libbpf_internal.h.
|
||||||
|
*
|
||||||
|
* This relocation allows libbpf to adjust BPF instruction to use correct
|
||||||
|
* actual field offset, based on target kernel BTF type that matches original
|
||||||
|
* (local) BTF, used to record relocation.
|
||||||
|
*/
|
||||||
|
#define bpf_core_read(dst, sz, src) \
|
||||||
|
bpf_probe_read_kernel(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||||
|
|
||||||
|
/* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use. */
|
||||||
|
#define bpf_core_read_user(dst, sz, src) \
|
||||||
|
bpf_probe_read_user(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||||
|
/*
|
||||||
|
* bpf_core_read_str() is a thin wrapper around bpf_probe_read_str()
|
||||||
|
* additionally emitting BPF CO-RE field relocation for specified source
|
||||||
|
* argument.
|
||||||
|
*/
|
||||||
|
#define bpf_core_read_str(dst, sz, src) \
|
||||||
|
bpf_probe_read_kernel_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||||
|
|
||||||
|
/* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use. */
|
||||||
|
#define bpf_core_read_user_str(dst, sz, src) \
|
||||||
|
bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||||
|
|
||||||
|
#define ___concat(a, b) a ## b
|
||||||
|
#define ___apply(fn, n) ___concat(fn, n)
|
||||||
|
#define ___nth(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __11, N, ...) N
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return number of provided arguments; used for switch-based variadic macro
|
||||||
|
* definitions (see ___last, ___arrow, etc below)
|
||||||
|
*/
|
||||||
|
#define ___narg(...) ___nth(_, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||||
|
/*
|
||||||
|
* return 0 if no arguments are passed, N - otherwise; used for
|
||||||
|
* recursively-defined macros to specify termination (0) case, and generic
|
||||||
|
* (N) case (e.g., ___read_ptrs, ___core_read)
|
||||||
|
*/
|
||||||
|
#define ___empty(...) ___nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0)
|
||||||
|
|
||||||
|
#define ___last1(x) x
|
||||||
|
#define ___last2(a, x) x
|
||||||
|
#define ___last3(a, b, x) x
|
||||||
|
#define ___last4(a, b, c, x) x
|
||||||
|
#define ___last5(a, b, c, d, x) x
|
||||||
|
#define ___last6(a, b, c, d, e, x) x
|
||||||
|
#define ___last7(a, b, c, d, e, f, x) x
|
||||||
|
#define ___last8(a, b, c, d, e, f, g, x) x
|
||||||
|
#define ___last9(a, b, c, d, e, f, g, h, x) x
|
||||||
|
#define ___last10(a, b, c, d, e, f, g, h, i, x) x
|
||||||
|
#define ___last(...) ___apply(___last, ___narg(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define ___nolast2(a, _) a
|
||||||
|
#define ___nolast3(a, b, _) a, b
|
||||||
|
#define ___nolast4(a, b, c, _) a, b, c
|
||||||
|
#define ___nolast5(a, b, c, d, _) a, b, c, d
|
||||||
|
#define ___nolast6(a, b, c, d, e, _) a, b, c, d, e
|
||||||
|
#define ___nolast7(a, b, c, d, e, f, _) a, b, c, d, e, f
|
||||||
|
#define ___nolast8(a, b, c, d, e, f, g, _) a, b, c, d, e, f, g
|
||||||
|
#define ___nolast9(a, b, c, d, e, f, g, h, _) a, b, c, d, e, f, g, h
|
||||||
|
#define ___nolast10(a, b, c, d, e, f, g, h, i, _) a, b, c, d, e, f, g, h, i
|
||||||
|
#define ___nolast(...) ___apply(___nolast, ___narg(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define ___arrow1(a) a
|
||||||
|
#define ___arrow2(a, b) a->b
|
||||||
|
#define ___arrow3(a, b, c) a->b->c
|
||||||
|
#define ___arrow4(a, b, c, d) a->b->c->d
|
||||||
|
#define ___arrow5(a, b, c, d, e) a->b->c->d->e
|
||||||
|
#define ___arrow6(a, b, c, d, e, f) a->b->c->d->e->f
|
||||||
|
#define ___arrow7(a, b, c, d, e, f, g) a->b->c->d->e->f->g
|
||||||
|
#define ___arrow8(a, b, c, d, e, f, g, h) a->b->c->d->e->f->g->h
|
||||||
|
#define ___arrow9(a, b, c, d, e, f, g, h, i) a->b->c->d->e->f->g->h->i
|
||||||
|
#define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j
|
||||||
|
#define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define ___type(...) typeof(___arrow(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define ___read(read_fn, dst, src_type, src, accessor) \
|
||||||
|
read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
|
||||||
|
|
||||||
|
/* "recursively" read a sequence of inner pointers using local __t var */
|
||||||
|
#define ___rd_first(fn, src, a) ___read(fn, &__t, ___type(src), src, a);
|
||||||
|
#define ___rd_last(fn, ...) \
|
||||||
|
___read(fn, &__t, ___type(___nolast(__VA_ARGS__)), __t, ___last(__VA_ARGS__));
|
||||||
|
#define ___rd_p1(fn, ...) const void *__t; ___rd_first(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p2(fn, ...) ___rd_p1(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p3(fn, ...) ___rd_p2(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p4(fn, ...) ___rd_p3(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p5(fn, ...) ___rd_p4(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p6(fn, ...) ___rd_p5(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p7(fn, ...) ___rd_p6(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p8(fn, ...) ___rd_p7(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___rd_p9(fn, ...) ___rd_p8(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||||
|
#define ___read_ptrs(fn, src, ...) \
|
||||||
|
___apply(___rd_p, ___narg(__VA_ARGS__))(fn, src, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define ___core_read0(fn, fn_ptr, dst, src, a) \
|
||||||
|
___read(fn, dst, ___type(src), src, a);
|
||||||
|
#define ___core_readN(fn, fn_ptr, dst, src, ...) \
|
||||||
|
___read_ptrs(fn_ptr, src, ___nolast(__VA_ARGS__)) \
|
||||||
|
___read(fn, dst, ___type(src, ___nolast(__VA_ARGS__)), __t, \
|
||||||
|
___last(__VA_ARGS__));
|
||||||
|
#define ___core_read(fn, fn_ptr, dst, src, a, ...) \
|
||||||
|
___apply(___core_read, ___empty(__VA_ARGS__))(fn, fn_ptr, dst, \
|
||||||
|
src, a, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_CORE_READ_INTO() is a more performance-conscious variant of
|
||||||
|
* BPF_CORE_READ(), in which final field is read into user-provided storage.
|
||||||
|
* See BPF_CORE_READ() below for more details on general usage.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_core_read, bpf_core_read, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variant of BPF_CORE_READ_INTO() for reading from user-space memory.
|
||||||
|
*
|
||||||
|
* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_USER_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_core_read_user, bpf_core_read_user, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Non-CO-RE variant of BPF_CORE_READ_INTO() */
|
||||||
|
#define BPF_PROBE_READ_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_probe_read, bpf_probe_read, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Non-CO-RE variant of BPF_CORE_READ_USER_INTO().
|
||||||
|
*
|
||||||
|
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||||
|
* not restricted to kernel types only.
|
||||||
|
*/
|
||||||
|
#define BPF_PROBE_READ_USER_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_probe_read_user, bpf_probe_read_user, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_CORE_READ_STR_INTO() does same "pointer chasing" as
|
||||||
|
* BPF_CORE_READ() for intermediate pointers, but then executes (and returns
|
||||||
|
* corresponding error code) bpf_core_read_str() for final string read.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_STR_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_core_read_str, bpf_core_read, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variant of BPF_CORE_READ_STR_INTO() for reading from user-space memory.
|
||||||
|
*
|
||||||
|
* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_USER_STR_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_core_read_user_str, bpf_core_read_user, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Non-CO-RE variant of BPF_CORE_READ_STR_INTO() */
|
||||||
|
#define BPF_PROBE_READ_STR_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_probe_read_str, bpf_probe_read, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-CO-RE variant of BPF_CORE_READ_USER_STR_INTO().
|
||||||
|
*
|
||||||
|
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||||
|
* not restricted to kernel types only.
|
||||||
|
*/
|
||||||
|
#define BPF_PROBE_READ_USER_STR_INTO(dst, src, a, ...) ({ \
|
||||||
|
___core_read(bpf_probe_read_user_str, bpf_probe_read_user, \
|
||||||
|
dst, (src), a, ##__VA_ARGS__) \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_CORE_READ() is used to simplify BPF CO-RE relocatable read, especially
|
||||||
|
* when there are few pointer chasing steps.
|
||||||
|
* E.g., what in non-BPF world (or in BPF w/ BCC) would be something like:
|
||||||
|
* int x = s->a.b.c->d.e->f->g;
|
||||||
|
* can be succinctly achieved using BPF_CORE_READ as:
|
||||||
|
* int x = BPF_CORE_READ(s, a.b.c, d.e, f, g);
|
||||||
|
*
|
||||||
|
* BPF_CORE_READ will decompose above statement into 4 bpf_core_read (BPF
|
||||||
|
* CO-RE relocatable bpf_probe_read_kernel() wrapper) calls, logically
|
||||||
|
* equivalent to:
|
||||||
|
* 1. const void *__t = s->a.b.c;
|
||||||
|
* 2. __t = __t->d.e;
|
||||||
|
* 3. __t = __t->f;
|
||||||
|
* 4. return __t->g;
|
||||||
|
*
|
||||||
|
* Equivalence is logical, because there is a heavy type casting/preservation
|
||||||
|
* involved, as well as all the reads are happening through
|
||||||
|
* bpf_probe_read_kernel() calls using __builtin_preserve_access_index() to
|
||||||
|
* emit CO-RE relocations.
|
||||||
|
*
|
||||||
|
* N.B. Only up to 9 "field accessors" are supported, which should be more
|
||||||
|
* than enough for any practical purpose.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ(src, a, ...) ({ \
|
||||||
|
___type((src), a, ##__VA_ARGS__) __r; \
|
||||||
|
BPF_CORE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||||
|
__r; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variant of BPF_CORE_READ() for reading from user-space memory.
|
||||||
|
*
|
||||||
|
* NOTE: all the source types involved are still *kernel types* and need to
|
||||||
|
* exist in kernel (or kernel module) BTF, otherwise CO-RE relocation will
|
||||||
|
* fail. Custom user types are not relocatable with CO-RE.
|
||||||
|
* The typical situation in which BPF_CORE_READ_USER() might be used is to
|
||||||
|
* read kernel UAPI types from the user-space memory passed in as a syscall
|
||||||
|
* input argument.
|
||||||
|
*/
|
||||||
|
#define BPF_CORE_READ_USER(src, a, ...) ({ \
|
||||||
|
___type((src), a, ##__VA_ARGS__) __r; \
|
||||||
|
BPF_CORE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||||
|
__r; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Non-CO-RE variant of BPF_CORE_READ() */
|
||||||
|
#define BPF_PROBE_READ(src, a, ...) ({ \
|
||||||
|
___type((src), a, ##__VA_ARGS__) __r; \
|
||||||
|
BPF_PROBE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||||
|
__r; \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-CO-RE variant of BPF_CORE_READ_USER().
|
||||||
|
*
|
||||||
|
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||||
|
* not restricted to kernel types only.
|
||||||
|
*/
|
||||||
|
#define BPF_PROBE_READ_USER(src, a, ...) ({ \
|
||||||
|
___type((src), a, ##__VA_ARGS__) __r; \
|
||||||
|
BPF_PROBE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||||
|
__r; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
99
src/bpf_endian.h
Normal file
99
src/bpf_endian.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
#ifndef __BPF_ENDIAN__
|
||||||
|
#define __BPF_ENDIAN__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Isolate byte #n and put it into byte #m, for __u##b type.
|
||||||
|
* E.g., moving byte #6 (nnnnnnnn) into byte #1 (mmmmmmmm) for __u64:
|
||||||
|
* 1) xxxxxxxx nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx
|
||||||
|
* 2) nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx 00000000
|
||||||
|
* 3) 00000000 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn
|
||||||
|
* 4) 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn 00000000
|
||||||
|
*/
|
||||||
|
#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8))
|
||||||
|
|
||||||
|
#define ___bpf_swab16(x) ((__u16)( \
|
||||||
|
___bpf_mvb(x, 16, 0, 1) | \
|
||||||
|
___bpf_mvb(x, 16, 1, 0)))
|
||||||
|
|
||||||
|
#define ___bpf_swab32(x) ((__u32)( \
|
||||||
|
___bpf_mvb(x, 32, 0, 3) | \
|
||||||
|
___bpf_mvb(x, 32, 1, 2) | \
|
||||||
|
___bpf_mvb(x, 32, 2, 1) | \
|
||||||
|
___bpf_mvb(x, 32, 3, 0)))
|
||||||
|
|
||||||
|
#define ___bpf_swab64(x) ((__u64)( \
|
||||||
|
___bpf_mvb(x, 64, 0, 7) | \
|
||||||
|
___bpf_mvb(x, 64, 1, 6) | \
|
||||||
|
___bpf_mvb(x, 64, 2, 5) | \
|
||||||
|
___bpf_mvb(x, 64, 3, 4) | \
|
||||||
|
___bpf_mvb(x, 64, 4, 3) | \
|
||||||
|
___bpf_mvb(x, 64, 5, 2) | \
|
||||||
|
___bpf_mvb(x, 64, 6, 1) | \
|
||||||
|
___bpf_mvb(x, 64, 7, 0)))
|
||||||
|
|
||||||
|
/* LLVM's BPF target selects the endianness of the CPU
|
||||||
|
* it compiles on, or the user specifies (bpfel/bpfeb),
|
||||||
|
* respectively. The used __BYTE_ORDER__ is defined by
|
||||||
|
* the compiler, we cannot rely on __BYTE_ORDER from
|
||||||
|
* libc headers, since it doesn't reflect the actual
|
||||||
|
* requested byte order.
|
||||||
|
*
|
||||||
|
* Note, LLVM's BPF target has different __builtin_bswapX()
|
||||||
|
* semantics. It does map to BPF_ALU | BPF_END | BPF_TO_BE
|
||||||
|
* in bpfel and bpfeb case, which means below, that we map
|
||||||
|
* to cpu_to_be16(). We could use it unconditionally in BPF
|
||||||
|
* case, but better not rely on it, so that this header here
|
||||||
|
* can be used from application and BPF program side, which
|
||||||
|
* use different targets.
|
||||||
|
*/
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
# define __bpf_ntohs(x) __builtin_bswap16(x)
|
||||||
|
# define __bpf_htons(x) __builtin_bswap16(x)
|
||||||
|
# define __bpf_constant_ntohs(x) ___bpf_swab16(x)
|
||||||
|
# define __bpf_constant_htons(x) ___bpf_swab16(x)
|
||||||
|
# define __bpf_ntohl(x) __builtin_bswap32(x)
|
||||||
|
# define __bpf_htonl(x) __builtin_bswap32(x)
|
||||||
|
# define __bpf_constant_ntohl(x) ___bpf_swab32(x)
|
||||||
|
# define __bpf_constant_htonl(x) ___bpf_swab32(x)
|
||||||
|
# define __bpf_be64_to_cpu(x) __builtin_bswap64(x)
|
||||||
|
# define __bpf_cpu_to_be64(x) __builtin_bswap64(x)
|
||||||
|
# define __bpf_constant_be64_to_cpu(x) ___bpf_swab64(x)
|
||||||
|
# define __bpf_constant_cpu_to_be64(x) ___bpf_swab64(x)
|
||||||
|
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
|
# define __bpf_ntohs(x) (x)
|
||||||
|
# define __bpf_htons(x) (x)
|
||||||
|
# define __bpf_constant_ntohs(x) (x)
|
||||||
|
# define __bpf_constant_htons(x) (x)
|
||||||
|
# define __bpf_ntohl(x) (x)
|
||||||
|
# define __bpf_htonl(x) (x)
|
||||||
|
# define __bpf_constant_ntohl(x) (x)
|
||||||
|
# define __bpf_constant_htonl(x) (x)
|
||||||
|
# define __bpf_be64_to_cpu(x) (x)
|
||||||
|
# define __bpf_cpu_to_be64(x) (x)
|
||||||
|
# define __bpf_constant_be64_to_cpu(x) (x)
|
||||||
|
# define __bpf_constant_cpu_to_be64(x) (x)
|
||||||
|
#else
|
||||||
|
# error "Fix your compiler's __BYTE_ORDER__?!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define bpf_htons(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_htons(x) : __bpf_htons(x))
|
||||||
|
#define bpf_ntohs(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_ntohs(x) : __bpf_ntohs(x))
|
||||||
|
#define bpf_htonl(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_htonl(x) : __bpf_htonl(x))
|
||||||
|
#define bpf_ntohl(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_ntohl(x) : __bpf_ntohl(x))
|
||||||
|
#define bpf_cpu_to_be64(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_cpu_to_be64(x) : __bpf_cpu_to_be64(x))
|
||||||
|
#define bpf_be64_to_cpu(x) \
|
||||||
|
(__builtin_constant_p(x) ? \
|
||||||
|
__bpf_constant_be64_to_cpu(x) : __bpf_be64_to_cpu(x))
|
||||||
|
|
||||||
|
#endif /* __BPF_ENDIAN__ */
|
||||||
72
src/bpf_gen_internal.h
Normal file
72
src/bpf_gen_internal.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
/* Copyright (c) 2021 Facebook */
|
||||||
|
#ifndef __BPF_GEN_INTERNAL_H
|
||||||
|
#define __BPF_GEN_INTERNAL_H
|
||||||
|
|
||||||
|
#include "bpf.h"
|
||||||
|
|
||||||
|
struct ksym_relo_desc {
|
||||||
|
const char *name;
|
||||||
|
int kind;
|
||||||
|
int insn_idx;
|
||||||
|
bool is_weak;
|
||||||
|
bool is_typeless;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ksym_desc {
|
||||||
|
const char *name;
|
||||||
|
int ref;
|
||||||
|
int kind;
|
||||||
|
union {
|
||||||
|
/* used for kfunc */
|
||||||
|
int off;
|
||||||
|
/* used for typeless ksym */
|
||||||
|
bool typeless;
|
||||||
|
};
|
||||||
|
int insn;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bpf_gen {
|
||||||
|
struct gen_loader_opts *opts;
|
||||||
|
void *data_start;
|
||||||
|
void *data_cur;
|
||||||
|
void *insn_start;
|
||||||
|
void *insn_cur;
|
||||||
|
ssize_t cleanup_label;
|
||||||
|
__u32 nr_progs;
|
||||||
|
__u32 nr_maps;
|
||||||
|
int log_level;
|
||||||
|
int error;
|
||||||
|
struct ksym_relo_desc *relos;
|
||||||
|
int relo_cnt;
|
||||||
|
struct bpf_core_relo *core_relos;
|
||||||
|
int core_relo_cnt;
|
||||||
|
char attach_target[128];
|
||||||
|
int attach_kind;
|
||||||
|
struct ksym_desc *ksyms;
|
||||||
|
__u32 nr_ksyms;
|
||||||
|
int fd_array;
|
||||||
|
int nr_fd_array;
|
||||||
|
};
|
||||||
|
|
||||||
|
void bpf_gen__init(struct bpf_gen *gen, int log_level, int nr_progs, int nr_maps);
|
||||||
|
int bpf_gen__finish(struct bpf_gen *gen, int nr_progs, int nr_maps);
|
||||||
|
void bpf_gen__free(struct bpf_gen *gen);
|
||||||
|
void bpf_gen__load_btf(struct bpf_gen *gen, const void *raw_data, __u32 raw_size);
|
||||||
|
void bpf_gen__map_create(struct bpf_gen *gen,
|
||||||
|
enum bpf_map_type map_type, const char *map_name,
|
||||||
|
__u32 key_size, __u32 value_size, __u32 max_entries,
|
||||||
|
struct bpf_map_create_opts *map_attr, int map_idx);
|
||||||
|
void bpf_gen__prog_load(struct bpf_gen *gen,
|
||||||
|
enum bpf_prog_type prog_type, const char *prog_name,
|
||||||
|
const char *license, struct bpf_insn *insns, size_t insn_cnt,
|
||||||
|
struct bpf_prog_load_opts *load_attr, int prog_idx);
|
||||||
|
void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *value, __u32 value_size);
|
||||||
|
void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx);
|
||||||
|
void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *name, enum bpf_attach_type type);
|
||||||
|
void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
|
||||||
|
bool is_typeless, int kind, int insn_idx);
|
||||||
|
void bpf_gen__record_relo_core(struct bpf_gen *gen, const struct bpf_core_relo *core_relo);
|
||||||
|
void bpf_gen__populate_outer_map(struct bpf_gen *gen, int outer_map_idx, int key, int inner_map_idx);
|
||||||
|
|
||||||
|
#endif
|
||||||
4609
src/bpf_helper_defs.h
Normal file
4609
src/bpf_helper_defs.h
Normal file
File diff suppressed because it is too large
Load Diff
301
src/bpf_helpers.h
Normal file
301
src/bpf_helpers.h
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
#ifndef __BPF_HELPERS__
|
||||||
|
#define __BPF_HELPERS__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that bpf programs need to include either
|
||||||
|
* vmlinux.h (auto-generated from BTF) or linux/types.h
|
||||||
|
* in advance since bpf_helper_defs.h uses such types
|
||||||
|
* as __u64.
|
||||||
|
*/
|
||||||
|
#include "bpf_helper_defs.h"
|
||||||
|
|
||||||
|
#define __uint(name, val) int (*name)[val]
|
||||||
|
#define __type(name, val) typeof(val) *name
|
||||||
|
#define __array(name, val) typeof(val) *name[]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper macro to place programs, maps, license in
|
||||||
|
* different sections in elf_bpf file. Section names
|
||||||
|
* are interpreted by libbpf depending on the context (BPF programs, BPF maps,
|
||||||
|
* extern variables, etc).
|
||||||
|
* To allow use of SEC() with externs (e.g., for extern .maps declarations),
|
||||||
|
* make sure __attribute__((unused)) doesn't trigger compilation warning.
|
||||||
|
*/
|
||||||
|
#if __GNUC__ && !__clang__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pragma macros are broken on GCC
|
||||||
|
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
|
||||||
|
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90400
|
||||||
|
*/
|
||||||
|
#define SEC(name) __attribute__((section(name), used))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SEC(name) \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wignored-attributes\"") \
|
||||||
|
__attribute__((section(name), used)) \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Avoid 'linux/stddef.h' definition of '__always_inline'. */
|
||||||
|
#undef __always_inline
|
||||||
|
#define __always_inline inline __attribute__((always_inline))
|
||||||
|
|
||||||
|
#ifndef __noinline
|
||||||
|
#define __noinline __attribute__((noinline))
|
||||||
|
#endif
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use __hidden attribute to mark a non-static BPF subprogram effectively
|
||||||
|
* static for BPF verifier's verification algorithm purposes, allowing more
|
||||||
|
* extensive and permissive BPF verification process, taking into account
|
||||||
|
* subprogram's caller context.
|
||||||
|
*/
|
||||||
|
#define __hidden __attribute__((visibility("hidden")))
|
||||||
|
|
||||||
|
/* When utilizing vmlinux.h with BPF CO-RE, user BPF programs can't include
|
||||||
|
* any system-level headers (such as stddef.h, linux/version.h, etc), and
|
||||||
|
* commonly-used macros like NULL and KERNEL_VERSION aren't available through
|
||||||
|
* vmlinux.h. This just adds unnecessary hurdles and forces users to re-define
|
||||||
|
* them on their own. So as a convenience, provide such definitions here.
|
||||||
|
*/
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KERNEL_VERSION
|
||||||
|
#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper macros to manipulate data structures
|
||||||
|
*/
|
||||||
|
#ifndef offsetof
|
||||||
|
#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
|
||||||
|
#endif
|
||||||
|
#ifndef container_of
|
||||||
|
#define container_of(ptr, type, member) \
|
||||||
|
({ \
|
||||||
|
void *__mptr = (void *)(ptr); \
|
||||||
|
((type *)(__mptr - offsetof(type, member))); \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compiler (optimization) barrier.
|
||||||
|
*/
|
||||||
|
#ifndef barrier
|
||||||
|
#define barrier() asm volatile("" ::: "memory")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Variable-specific compiler (optimization) barrier. It's a no-op which makes
|
||||||
|
* compiler believe that there is some black box modification of a given
|
||||||
|
* variable and thus prevents compiler from making extra assumption about its
|
||||||
|
* value and potential simplifications and optimizations on this variable.
|
||||||
|
*
|
||||||
|
* E.g., compiler might often delay or even omit 32-bit to 64-bit casting of
|
||||||
|
* a variable, making some code patterns unverifiable. Putting barrier_var()
|
||||||
|
* in place will ensure that cast is performed before the barrier_var()
|
||||||
|
* invocation, because compiler has to pessimistically assume that embedded
|
||||||
|
* asm section might perform some extra operations on that variable.
|
||||||
|
*
|
||||||
|
* This is a variable-specific variant of more global barrier().
|
||||||
|
*/
|
||||||
|
#ifndef barrier_var
|
||||||
|
#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper macro to throw a compilation error if __bpf_unreachable() gets
|
||||||
|
* built into the resulting code. This works given BPF back end does not
|
||||||
|
* implement __builtin_trap(). This is useful to assert that certain paths
|
||||||
|
* of the program code are never used and hence eliminated by the compiler.
|
||||||
|
*
|
||||||
|
* For example, consider a switch statement that covers known cases used by
|
||||||
|
* the program. __bpf_unreachable() can then reside in the default case. If
|
||||||
|
* the program gets extended such that a case is not covered in the switch
|
||||||
|
* statement, then it will throw a build error due to the default case not
|
||||||
|
* being compiled out.
|
||||||
|
*/
|
||||||
|
#ifndef __bpf_unreachable
|
||||||
|
# define __bpf_unreachable() __builtin_trap()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to perform a tail call with a constant/immediate map slot.
|
||||||
|
*/
|
||||||
|
#if __clang_major__ >= 8 && defined(__bpf__)
|
||||||
|
static __always_inline void
|
||||||
|
bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p(slot))
|
||||||
|
__bpf_unreachable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide a hard guarantee that LLVM won't optimize setting r2 (map
|
||||||
|
* pointer) and r3 (constant map index) from _different paths_ ending
|
||||||
|
* up at the _same_ call insn as otherwise we won't be able to use the
|
||||||
|
* jmpq/nopl retpoline-free patching by the x86-64 JIT in the kernel
|
||||||
|
* given they mismatch. See also d2e4c1e6c294 ("bpf: Constant map key
|
||||||
|
* tracking for prog array pokes") for details on verifier tracking.
|
||||||
|
*
|
||||||
|
* Note on clobber list: we need to stay in-line with BPF calling
|
||||||
|
* convention, so even if we don't end up using r0, r4, r5, we need
|
||||||
|
* to mark them as clobber so that LLVM doesn't end up using them
|
||||||
|
* before / after the call.
|
||||||
|
*/
|
||||||
|
asm volatile("r1 = %[ctx]\n\t"
|
||||||
|
"r2 = %[map]\n\t"
|
||||||
|
"r3 = %[slot]\n\t"
|
||||||
|
"call 12"
|
||||||
|
:: [ctx]"r"(ctx), [map]"r"(map), [slot]"i"(slot)
|
||||||
|
: "r0", "r1", "r2", "r3", "r4", "r5");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper structure used by eBPF C program
|
||||||
|
* to describe BPF map attributes to libbpf loader
|
||||||
|
*/
|
||||||
|
struct bpf_map_def {
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int key_size;
|
||||||
|
unsigned int value_size;
|
||||||
|
unsigned int max_entries;
|
||||||
|
unsigned int map_flags;
|
||||||
|
} __attribute__((deprecated("use BTF-defined maps in .maps section")));
|
||||||
|
|
||||||
|
enum libbpf_pin_type {
|
||||||
|
LIBBPF_PIN_NONE,
|
||||||
|
/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
|
||||||
|
LIBBPF_PIN_BY_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum libbpf_tristate {
|
||||||
|
TRI_NO = 0,
|
||||||
|
TRI_YES = 1,
|
||||||
|
TRI_MODULE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __kconfig __attribute__((section(".kconfig")))
|
||||||
|
#define __ksym __attribute__((section(".ksyms")))
|
||||||
|
#define __kptr __attribute__((btf_type_tag("kptr")))
|
||||||
|
#define __kptr_ref __attribute__((btf_type_tag("kptr_ref")))
|
||||||
|
|
||||||
|
#ifndef ___bpf_concat
|
||||||
|
#define ___bpf_concat(a, b) a ## b
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_apply
|
||||||
|
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_nth
|
||||||
|
#define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_narg
|
||||||
|
#define ___bpf_narg(...) \
|
||||||
|
___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ___bpf_fill0(arr, p, x) do {} while (0)
|
||||||
|
#define ___bpf_fill1(arr, p, x) arr[p] = x
|
||||||
|
#define ___bpf_fill2(arr, p, x, args...) arr[p] = x; ___bpf_fill1(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill3(arr, p, x, args...) arr[p] = x; ___bpf_fill2(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill4(arr, p, x, args...) arr[p] = x; ___bpf_fill3(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill5(arr, p, x, args...) arr[p] = x; ___bpf_fill4(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill6(arr, p, x, args...) arr[p] = x; ___bpf_fill5(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill7(arr, p, x, args...) arr[p] = x; ___bpf_fill6(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill8(arr, p, x, args...) arr[p] = x; ___bpf_fill7(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill9(arr, p, x, args...) arr[p] = x; ___bpf_fill8(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill10(arr, p, x, args...) arr[p] = x; ___bpf_fill9(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill11(arr, p, x, args...) arr[p] = x; ___bpf_fill10(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill12(arr, p, x, args...) arr[p] = x; ___bpf_fill11(arr, p + 1, args)
|
||||||
|
#define ___bpf_fill(arr, args...) \
|
||||||
|
___bpf_apply(___bpf_fill, ___bpf_narg(args))(arr, 0, args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_SEQ_PRINTF to wrap bpf_seq_printf to-be-printed values
|
||||||
|
* in a structure.
|
||||||
|
*/
|
||||||
|
#define BPF_SEQ_PRINTF(seq, fmt, args...) \
|
||||||
|
({ \
|
||||||
|
static const char ___fmt[] = fmt; \
|
||||||
|
unsigned long long ___param[___bpf_narg(args)]; \
|
||||||
|
\
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
___bpf_fill(___param, args); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
\
|
||||||
|
bpf_seq_printf(seq, ___fmt, sizeof(___fmt), \
|
||||||
|
___param, sizeof(___param)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_SNPRINTF wraps the bpf_snprintf helper with variadic arguments instead of
|
||||||
|
* an array of u64.
|
||||||
|
*/
|
||||||
|
#define BPF_SNPRINTF(out, out_size, fmt, args...) \
|
||||||
|
({ \
|
||||||
|
static const char ___fmt[] = fmt; \
|
||||||
|
unsigned long long ___param[___bpf_narg(args)]; \
|
||||||
|
\
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
___bpf_fill(___param, args); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
\
|
||||||
|
bpf_snprintf(out, out_size, ___fmt, \
|
||||||
|
___param, sizeof(___param)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#ifdef BPF_NO_GLOBAL_DATA
|
||||||
|
#define BPF_PRINTK_FMT_MOD
|
||||||
|
#else
|
||||||
|
#define BPF_PRINTK_FMT_MOD static const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __bpf_printk(fmt, ...) \
|
||||||
|
({ \
|
||||||
|
BPF_PRINTK_FMT_MOD char ____fmt[] = fmt; \
|
||||||
|
bpf_trace_printk(____fmt, sizeof(____fmt), \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __bpf_vprintk wraps the bpf_trace_vprintk helper with variadic arguments
|
||||||
|
* instead of an array of u64.
|
||||||
|
*/
|
||||||
|
#define __bpf_vprintk(fmt, args...) \
|
||||||
|
({ \
|
||||||
|
static const char ___fmt[] = fmt; \
|
||||||
|
unsigned long long ___param[___bpf_narg(args)]; \
|
||||||
|
\
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
___bpf_fill(___param, args); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
\
|
||||||
|
bpf_trace_vprintk(___fmt, sizeof(___fmt), \
|
||||||
|
___param, sizeof(___param)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Use __bpf_printk when bpf_printk call has 3 or fewer fmt args
|
||||||
|
* Otherwise use __bpf_vprintk
|
||||||
|
*/
|
||||||
|
#define ___bpf_pick_printk(...) \
|
||||||
|
___bpf_nth(_, ##__VA_ARGS__, __bpf_vprintk, __bpf_vprintk, __bpf_vprintk, \
|
||||||
|
__bpf_vprintk, __bpf_vprintk, __bpf_vprintk, __bpf_vprintk, \
|
||||||
|
__bpf_vprintk, __bpf_vprintk, __bpf_printk /*3*/, __bpf_printk /*2*/,\
|
||||||
|
__bpf_printk /*1*/, __bpf_printk /*0*/)
|
||||||
|
|
||||||
|
/* Helper macro to print out debug messages */
|
||||||
|
#define bpf_printk(fmt, args...) ___bpf_pick_printk(args)(fmt, ##args)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -101,11 +101,12 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
|
|||||||
{
|
{
|
||||||
struct bpf_prog_linfo *prog_linfo;
|
struct bpf_prog_linfo *prog_linfo;
|
||||||
__u32 nr_linfo, nr_jited_func;
|
__u32 nr_linfo, nr_jited_func;
|
||||||
|
__u64 data_sz;
|
||||||
|
|
||||||
nr_linfo = info->nr_line_info;
|
nr_linfo = info->nr_line_info;
|
||||||
|
|
||||||
if (!nr_linfo)
|
if (!nr_linfo)
|
||||||
return NULL;
|
return errno = EINVAL, NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The min size that bpf_prog_linfo has to access for
|
* The min size that bpf_prog_linfo has to access for
|
||||||
@@ -113,20 +114,20 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
|
|||||||
*/
|
*/
|
||||||
if (info->line_info_rec_size <
|
if (info->line_info_rec_size <
|
||||||
offsetof(struct bpf_line_info, file_name_off))
|
offsetof(struct bpf_line_info, file_name_off))
|
||||||
return NULL;
|
return errno = EINVAL, NULL;
|
||||||
|
|
||||||
prog_linfo = calloc(1, sizeof(*prog_linfo));
|
prog_linfo = calloc(1, sizeof(*prog_linfo));
|
||||||
if (!prog_linfo)
|
if (!prog_linfo)
|
||||||
return NULL;
|
return errno = ENOMEM, NULL;
|
||||||
|
|
||||||
/* Copy xlated line_info */
|
/* Copy xlated line_info */
|
||||||
prog_linfo->nr_linfo = nr_linfo;
|
prog_linfo->nr_linfo = nr_linfo;
|
||||||
prog_linfo->rec_size = info->line_info_rec_size;
|
prog_linfo->rec_size = info->line_info_rec_size;
|
||||||
prog_linfo->raw_linfo = malloc(nr_linfo * prog_linfo->rec_size);
|
data_sz = (__u64)nr_linfo * prog_linfo->rec_size;
|
||||||
|
prog_linfo->raw_linfo = malloc(data_sz);
|
||||||
if (!prog_linfo->raw_linfo)
|
if (!prog_linfo->raw_linfo)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
memcpy(prog_linfo->raw_linfo, (void *)(long)info->line_info,
|
memcpy(prog_linfo->raw_linfo, (void *)(long)info->line_info, data_sz);
|
||||||
nr_linfo * prog_linfo->rec_size);
|
|
||||||
|
|
||||||
nr_jited_func = info->nr_jited_ksyms;
|
nr_jited_func = info->nr_jited_ksyms;
|
||||||
if (!nr_jited_func ||
|
if (!nr_jited_func ||
|
||||||
@@ -142,13 +143,12 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
|
|||||||
/* Copy jited_line_info */
|
/* Copy jited_line_info */
|
||||||
prog_linfo->nr_jited_func = nr_jited_func;
|
prog_linfo->nr_jited_func = nr_jited_func;
|
||||||
prog_linfo->jited_rec_size = info->jited_line_info_rec_size;
|
prog_linfo->jited_rec_size = info->jited_line_info_rec_size;
|
||||||
prog_linfo->raw_jited_linfo = malloc(nr_linfo *
|
data_sz = (__u64)nr_linfo * prog_linfo->jited_rec_size;
|
||||||
prog_linfo->jited_rec_size);
|
prog_linfo->raw_jited_linfo = malloc(data_sz);
|
||||||
if (!prog_linfo->raw_jited_linfo)
|
if (!prog_linfo->raw_jited_linfo)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
memcpy(prog_linfo->raw_jited_linfo,
|
memcpy(prog_linfo->raw_jited_linfo,
|
||||||
(void *)(long)info->jited_line_info,
|
(void *)(long)info->jited_line_info, data_sz);
|
||||||
nr_linfo * prog_linfo->jited_rec_size);
|
|
||||||
|
|
||||||
/* Number of jited_line_info per jited func */
|
/* Number of jited_line_info per jited func */
|
||||||
prog_linfo->nr_jited_linfo_per_func = malloc(nr_jited_func *
|
prog_linfo->nr_jited_linfo_per_func = malloc(nr_jited_func *
|
||||||
@@ -174,7 +174,7 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
|
|||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
bpf_prog_linfo__free(prog_linfo);
|
bpf_prog_linfo__free(prog_linfo);
|
||||||
return NULL;
|
return errno = EINVAL, NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct bpf_line_info *
|
const struct bpf_line_info *
|
||||||
@@ -186,11 +186,11 @@ bpf_prog_linfo__lfind_addr_func(const struct bpf_prog_linfo *prog_linfo,
|
|||||||
const __u64 *jited_linfo;
|
const __u64 *jited_linfo;
|
||||||
|
|
||||||
if (func_idx >= prog_linfo->nr_jited_func)
|
if (func_idx >= prog_linfo->nr_jited_func)
|
||||||
return NULL;
|
return errno = ENOENT, NULL;
|
||||||
|
|
||||||
nr_linfo = prog_linfo->nr_jited_linfo_per_func[func_idx];
|
nr_linfo = prog_linfo->nr_jited_linfo_per_func[func_idx];
|
||||||
if (nr_skip >= nr_linfo)
|
if (nr_skip >= nr_linfo)
|
||||||
return NULL;
|
return errno = ENOENT, NULL;
|
||||||
|
|
||||||
start = prog_linfo->jited_linfo_func_idx[func_idx] + nr_skip;
|
start = prog_linfo->jited_linfo_func_idx[func_idx] + nr_skip;
|
||||||
jited_rec_size = prog_linfo->jited_rec_size;
|
jited_rec_size = prog_linfo->jited_rec_size;
|
||||||
@@ -198,7 +198,7 @@ bpf_prog_linfo__lfind_addr_func(const struct bpf_prog_linfo *prog_linfo,
|
|||||||
(start * jited_rec_size);
|
(start * jited_rec_size);
|
||||||
jited_linfo = raw_jited_linfo;
|
jited_linfo = raw_jited_linfo;
|
||||||
if (addr < *jited_linfo)
|
if (addr < *jited_linfo)
|
||||||
return NULL;
|
return errno = ENOENT, NULL;
|
||||||
|
|
||||||
nr_linfo -= nr_skip;
|
nr_linfo -= nr_skip;
|
||||||
rec_size = prog_linfo->rec_size;
|
rec_size = prog_linfo->rec_size;
|
||||||
@@ -225,13 +225,13 @@ bpf_prog_linfo__lfind(const struct bpf_prog_linfo *prog_linfo,
|
|||||||
|
|
||||||
nr_linfo = prog_linfo->nr_linfo;
|
nr_linfo = prog_linfo->nr_linfo;
|
||||||
if (nr_skip >= nr_linfo)
|
if (nr_skip >= nr_linfo)
|
||||||
return NULL;
|
return errno = ENOENT, NULL;
|
||||||
|
|
||||||
rec_size = prog_linfo->rec_size;
|
rec_size = prog_linfo->rec_size;
|
||||||
raw_linfo = prog_linfo->raw_linfo + (nr_skip * rec_size);
|
raw_linfo = prog_linfo->raw_linfo + (nr_skip * rec_size);
|
||||||
linfo = raw_linfo;
|
linfo = raw_linfo;
|
||||||
if (insn_off < linfo->insn_off)
|
if (insn_off < linfo->insn_off)
|
||||||
return NULL;
|
return errno = ENOENT, NULL;
|
||||||
|
|
||||||
nr_linfo -= nr_skip;
|
nr_linfo -= nr_skip;
|
||||||
for (i = 0; i < nr_linfo; i++) {
|
for (i = 0; i < nr_linfo; i++) {
|
||||||
|
|||||||
563
src/bpf_tracing.h
Normal file
563
src/bpf_tracing.h
Normal file
@@ -0,0 +1,563 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
#ifndef __BPF_TRACING_H__
|
||||||
|
#define __BPF_TRACING_H__
|
||||||
|
|
||||||
|
#include <bpf/bpf_helpers.h>
|
||||||
|
|
||||||
|
/* Scan the ARCH passed in from ARCH env variable (see Makefile) */
|
||||||
|
#if defined(__TARGET_ARCH_x86)
|
||||||
|
#define bpf_target_x86
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_s390)
|
||||||
|
#define bpf_target_s390
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_arm)
|
||||||
|
#define bpf_target_arm
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_arm64)
|
||||||
|
#define bpf_target_arm64
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_mips)
|
||||||
|
#define bpf_target_mips
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_powerpc)
|
||||||
|
#define bpf_target_powerpc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_sparc)
|
||||||
|
#define bpf_target_sparc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_riscv)
|
||||||
|
#define bpf_target_riscv
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__TARGET_ARCH_arc)
|
||||||
|
#define bpf_target_arc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Fall back to what the compiler says */
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#define bpf_target_x86
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__s390__)
|
||||||
|
#define bpf_target_s390
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#define bpf_target_arm
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#define bpf_target_arm64
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__mips__)
|
||||||
|
#define bpf_target_mips
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__powerpc__)
|
||||||
|
#define bpf_target_powerpc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
#define bpf_target_sparc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__riscv) && __riscv_xlen == 64
|
||||||
|
#define bpf_target_riscv
|
||||||
|
#define bpf_target_defined
|
||||||
|
#elif defined(__arc__)
|
||||||
|
#define bpf_target_arc
|
||||||
|
#define bpf_target_defined
|
||||||
|
#endif /* no compiler target */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __BPF_TARGET_MISSING
|
||||||
|
#define __BPF_TARGET_MISSING "GCC error \"Must specify a BPF target arch via __TARGET_ARCH_xxx\""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(bpf_target_x86)
|
||||||
|
|
||||||
|
#if defined(__KERNEL__) || defined(__VMLINUX_H__)
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG di
|
||||||
|
#define __PT_PARM2_REG si
|
||||||
|
#define __PT_PARM3_REG dx
|
||||||
|
#define __PT_PARM4_REG cx
|
||||||
|
#define __PT_PARM5_REG r8
|
||||||
|
#define __PT_RET_REG sp
|
||||||
|
#define __PT_FP_REG bp
|
||||||
|
#define __PT_RC_REG ax
|
||||||
|
#define __PT_SP_REG sp
|
||||||
|
#define __PT_IP_REG ip
|
||||||
|
/* syscall uses r10 for PARM4 */
|
||||||
|
#define PT_REGS_PARM4_SYSCALL(x) ((x)->r10)
|
||||||
|
#define PT_REGS_PARM4_CORE_SYSCALL(x) BPF_CORE_READ(x, r10)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG eax
|
||||||
|
#define __PT_PARM2_REG edx
|
||||||
|
#define __PT_PARM3_REG ecx
|
||||||
|
/* i386 kernel is built with -mregparm=3 */
|
||||||
|
#define __PT_PARM4_REG __unsupported__
|
||||||
|
#define __PT_PARM5_REG __unsupported__
|
||||||
|
#define __PT_RET_REG esp
|
||||||
|
#define __PT_FP_REG ebp
|
||||||
|
#define __PT_RC_REG eax
|
||||||
|
#define __PT_SP_REG esp
|
||||||
|
#define __PT_IP_REG eip
|
||||||
|
|
||||||
|
#else /* __i386__ */
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG rdi
|
||||||
|
#define __PT_PARM2_REG rsi
|
||||||
|
#define __PT_PARM3_REG rdx
|
||||||
|
#define __PT_PARM4_REG rcx
|
||||||
|
#define __PT_PARM5_REG r8
|
||||||
|
#define __PT_RET_REG rsp
|
||||||
|
#define __PT_FP_REG rbp
|
||||||
|
#define __PT_RC_REG rax
|
||||||
|
#define __PT_SP_REG rsp
|
||||||
|
#define __PT_IP_REG rip
|
||||||
|
/* syscall uses r10 for PARM4 */
|
||||||
|
#define PT_REGS_PARM4_SYSCALL(x) ((x)->r10)
|
||||||
|
#define PT_REGS_PARM4_CORE_SYSCALL(x) BPF_CORE_READ(x, r10)
|
||||||
|
|
||||||
|
#endif /* __i386__ */
|
||||||
|
|
||||||
|
#endif /* __KERNEL__ || __VMLINUX_H__ */
|
||||||
|
|
||||||
|
#elif defined(bpf_target_s390)
|
||||||
|
|
||||||
|
struct pt_regs___s390 {
|
||||||
|
unsigned long orig_gpr2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
|
||||||
|
#define __PT_REGS_CAST(x) ((const user_pt_regs *)(x))
|
||||||
|
#define __PT_PARM1_REG gprs[2]
|
||||||
|
#define __PT_PARM2_REG gprs[3]
|
||||||
|
#define __PT_PARM3_REG gprs[4]
|
||||||
|
#define __PT_PARM4_REG gprs[5]
|
||||||
|
#define __PT_PARM5_REG gprs[6]
|
||||||
|
#define __PT_RET_REG grps[14]
|
||||||
|
#define __PT_FP_REG gprs[11] /* Works only with CONFIG_FRAME_POINTER */
|
||||||
|
#define __PT_RC_REG gprs[2]
|
||||||
|
#define __PT_SP_REG gprs[15]
|
||||||
|
#define __PT_IP_REG psw.addr
|
||||||
|
#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x)
|
||||||
|
#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___s390 *)(x), orig_gpr2)
|
||||||
|
|
||||||
|
#elif defined(bpf_target_arm)
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG uregs[0]
|
||||||
|
#define __PT_PARM2_REG uregs[1]
|
||||||
|
#define __PT_PARM3_REG uregs[2]
|
||||||
|
#define __PT_PARM4_REG uregs[3]
|
||||||
|
#define __PT_PARM5_REG uregs[4]
|
||||||
|
#define __PT_RET_REG uregs[14]
|
||||||
|
#define __PT_FP_REG uregs[11] /* Works only with CONFIG_FRAME_POINTER */
|
||||||
|
#define __PT_RC_REG uregs[0]
|
||||||
|
#define __PT_SP_REG uregs[13]
|
||||||
|
#define __PT_IP_REG uregs[12]
|
||||||
|
|
||||||
|
#elif defined(bpf_target_arm64)
|
||||||
|
|
||||||
|
struct pt_regs___arm64 {
|
||||||
|
unsigned long orig_x0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
|
||||||
|
#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x))
|
||||||
|
#define __PT_PARM1_REG regs[0]
|
||||||
|
#define __PT_PARM2_REG regs[1]
|
||||||
|
#define __PT_PARM3_REG regs[2]
|
||||||
|
#define __PT_PARM4_REG regs[3]
|
||||||
|
#define __PT_PARM5_REG regs[4]
|
||||||
|
#define __PT_RET_REG regs[30]
|
||||||
|
#define __PT_FP_REG regs[29] /* Works only with CONFIG_FRAME_POINTER */
|
||||||
|
#define __PT_RC_REG regs[0]
|
||||||
|
#define __PT_SP_REG sp
|
||||||
|
#define __PT_IP_REG pc
|
||||||
|
#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x)
|
||||||
|
#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___arm64 *)(x), orig_x0)
|
||||||
|
|
||||||
|
#elif defined(bpf_target_mips)
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG regs[4]
|
||||||
|
#define __PT_PARM2_REG regs[5]
|
||||||
|
#define __PT_PARM3_REG regs[6]
|
||||||
|
#define __PT_PARM4_REG regs[7]
|
||||||
|
#define __PT_PARM5_REG regs[8]
|
||||||
|
#define __PT_RET_REG regs[31]
|
||||||
|
#define __PT_FP_REG regs[30] /* Works only with CONFIG_FRAME_POINTER */
|
||||||
|
#define __PT_RC_REG regs[2]
|
||||||
|
#define __PT_SP_REG regs[29]
|
||||||
|
#define __PT_IP_REG cp0_epc
|
||||||
|
|
||||||
|
#elif defined(bpf_target_powerpc)
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG gpr[3]
|
||||||
|
#define __PT_PARM2_REG gpr[4]
|
||||||
|
#define __PT_PARM3_REG gpr[5]
|
||||||
|
#define __PT_PARM4_REG gpr[6]
|
||||||
|
#define __PT_PARM5_REG gpr[7]
|
||||||
|
#define __PT_RET_REG regs[31]
|
||||||
|
#define __PT_FP_REG __unsupported__
|
||||||
|
#define __PT_RC_REG gpr[3]
|
||||||
|
#define __PT_SP_REG sp
|
||||||
|
#define __PT_IP_REG nip
|
||||||
|
/* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER. */
|
||||||
|
#define PT_REGS_SYSCALL_REGS(ctx) ctx
|
||||||
|
|
||||||
|
#elif defined(bpf_target_sparc)
|
||||||
|
|
||||||
|
#define __PT_PARM1_REG u_regs[UREG_I0]
|
||||||
|
#define __PT_PARM2_REG u_regs[UREG_I1]
|
||||||
|
#define __PT_PARM3_REG u_regs[UREG_I2]
|
||||||
|
#define __PT_PARM4_REG u_regs[UREG_I3]
|
||||||
|
#define __PT_PARM5_REG u_regs[UREG_I4]
|
||||||
|
#define __PT_RET_REG u_regs[UREG_I7]
|
||||||
|
#define __PT_FP_REG __unsupported__
|
||||||
|
#define __PT_RC_REG u_regs[UREG_I0]
|
||||||
|
#define __PT_SP_REG u_regs[UREG_FP]
|
||||||
|
/* Should this also be a bpf_target check for the sparc case? */
|
||||||
|
#if defined(__arch64__)
|
||||||
|
#define __PT_IP_REG tpc
|
||||||
|
#else
|
||||||
|
#define __PT_IP_REG pc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(bpf_target_riscv)
|
||||||
|
|
||||||
|
#define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x))
|
||||||
|
#define __PT_PARM1_REG a0
|
||||||
|
#define __PT_PARM2_REG a1
|
||||||
|
#define __PT_PARM3_REG a2
|
||||||
|
#define __PT_PARM4_REG a3
|
||||||
|
#define __PT_PARM5_REG a4
|
||||||
|
#define __PT_RET_REG ra
|
||||||
|
#define __PT_FP_REG s0
|
||||||
|
#define __PT_RC_REG a0
|
||||||
|
#define __PT_SP_REG sp
|
||||||
|
#define __PT_IP_REG pc
|
||||||
|
/* riscv does not select ARCH_HAS_SYSCALL_WRAPPER. */
|
||||||
|
#define PT_REGS_SYSCALL_REGS(ctx) ctx
|
||||||
|
|
||||||
|
#elif defined(bpf_target_arc)
|
||||||
|
|
||||||
|
/* arc provides struct user_pt_regs instead of struct pt_regs to userspace */
|
||||||
|
#define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x))
|
||||||
|
#define __PT_PARM1_REG scratch.r0
|
||||||
|
#define __PT_PARM2_REG scratch.r1
|
||||||
|
#define __PT_PARM3_REG scratch.r2
|
||||||
|
#define __PT_PARM4_REG scratch.r3
|
||||||
|
#define __PT_PARM5_REG scratch.r4
|
||||||
|
#define __PT_RET_REG scratch.blink
|
||||||
|
#define __PT_FP_REG __unsupported__
|
||||||
|
#define __PT_RC_REG scratch.r0
|
||||||
|
#define __PT_SP_REG scratch.sp
|
||||||
|
#define __PT_IP_REG scratch.ret
|
||||||
|
/* arc does not select ARCH_HAS_SYSCALL_WRAPPER. */
|
||||||
|
#define PT_REGS_SYSCALL_REGS(ctx) ctx
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(bpf_target_defined)
|
||||||
|
|
||||||
|
struct pt_regs;
|
||||||
|
|
||||||
|
/* allow some architecutres to override `struct pt_regs` */
|
||||||
|
#ifndef __PT_REGS_CAST
|
||||||
|
#define __PT_REGS_CAST(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG)
|
||||||
|
#define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG)
|
||||||
|
#define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG)
|
||||||
|
#define PT_REGS_PARM4(x) (__PT_REGS_CAST(x)->__PT_PARM4_REG)
|
||||||
|
#define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG)
|
||||||
|
#define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG)
|
||||||
|
#define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG)
|
||||||
|
#define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG)
|
||||||
|
#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG)
|
||||||
|
#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG)
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_REG)
|
||||||
|
#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM2_REG)
|
||||||
|
#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM3_REG)
|
||||||
|
#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM4_REG)
|
||||||
|
#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM5_REG)
|
||||||
|
#define PT_REGS_RET_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RET_REG)
|
||||||
|
#define PT_REGS_FP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_FP_REG)
|
||||||
|
#define PT_REGS_RC_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RC_REG)
|
||||||
|
#define PT_REGS_SP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_SP_REG)
|
||||||
|
#define PT_REGS_IP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_IP_REG)
|
||||||
|
|
||||||
|
#if defined(bpf_target_powerpc)
|
||||||
|
|
||||||
|
#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; })
|
||||||
|
#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
|
||||||
|
|
||||||
|
#elif defined(bpf_target_sparc)
|
||||||
|
|
||||||
|
#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); })
|
||||||
|
#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define BPF_KPROBE_READ_RET_IP(ip, ctx) \
|
||||||
|
({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
|
||||||
|
#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) \
|
||||||
|
({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PT_REGS_PARM1_SYSCALL
|
||||||
|
#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1(x)
|
||||||
|
#endif
|
||||||
|
#define PT_REGS_PARM2_SYSCALL(x) PT_REGS_PARM2(x)
|
||||||
|
#define PT_REGS_PARM3_SYSCALL(x) PT_REGS_PARM3(x)
|
||||||
|
#ifndef PT_REGS_PARM4_SYSCALL
|
||||||
|
#define PT_REGS_PARM4_SYSCALL(x) PT_REGS_PARM4(x)
|
||||||
|
#endif
|
||||||
|
#define PT_REGS_PARM5_SYSCALL(x) PT_REGS_PARM5(x)
|
||||||
|
|
||||||
|
#ifndef PT_REGS_PARM1_CORE_SYSCALL
|
||||||
|
#define PT_REGS_PARM1_CORE_SYSCALL(x) PT_REGS_PARM1_CORE(x)
|
||||||
|
#endif
|
||||||
|
#define PT_REGS_PARM2_CORE_SYSCALL(x) PT_REGS_PARM2_CORE(x)
|
||||||
|
#define PT_REGS_PARM3_CORE_SYSCALL(x) PT_REGS_PARM3_CORE(x)
|
||||||
|
#ifndef PT_REGS_PARM4_CORE_SYSCALL
|
||||||
|
#define PT_REGS_PARM4_CORE_SYSCALL(x) PT_REGS_PARM4_CORE(x)
|
||||||
|
#endif
|
||||||
|
#define PT_REGS_PARM5_CORE_SYSCALL(x) PT_REGS_PARM5_CORE(x)
|
||||||
|
|
||||||
|
#else /* defined(bpf_target_defined) */
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM2(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM3(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM4(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM5(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_RET(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_FP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_RC(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_SP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_IP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM2_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM3_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM4_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM5_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_RET_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_FP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_RC_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_SP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_IP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
|
||||||
|
#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM2_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM3_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM4_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM5_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
|
||||||
|
#define PT_REGS_PARM1_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM2_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM3_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM4_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
#define PT_REGS_PARM5_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
|
||||||
|
|
||||||
|
#endif /* defined(bpf_target_defined) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When invoked from a syscall handler kprobe, returns a pointer to a
|
||||||
|
* struct pt_regs containing syscall arguments and suitable for passing to
|
||||||
|
* PT_REGS_PARMn_SYSCALL() and PT_REGS_PARMn_CORE_SYSCALL().
|
||||||
|
*/
|
||||||
|
#ifndef PT_REGS_SYSCALL_REGS
|
||||||
|
/* By default, assume that the arch selects ARCH_HAS_SYSCALL_WRAPPER. */
|
||||||
|
#define PT_REGS_SYSCALL_REGS(ctx) ((struct pt_regs *)PT_REGS_PARM1(ctx))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ___bpf_concat
|
||||||
|
#define ___bpf_concat(a, b) a ## b
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_apply
|
||||||
|
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_nth
|
||||||
|
#define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N
|
||||||
|
#endif
|
||||||
|
#ifndef ___bpf_narg
|
||||||
|
#define ___bpf_narg(...) ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ___bpf_ctx_cast0() ctx
|
||||||
|
#define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0]
|
||||||
|
#define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1]
|
||||||
|
#define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2]
|
||||||
|
#define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3]
|
||||||
|
#define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4]
|
||||||
|
#define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5]
|
||||||
|
#define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6]
|
||||||
|
#define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7]
|
||||||
|
#define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8]
|
||||||
|
#define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9]
|
||||||
|
#define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10]
|
||||||
|
#define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11]
|
||||||
|
#define ___bpf_ctx_cast(args...) ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and
|
||||||
|
* similar kinds of BPF programs, that accept input arguments as a single
|
||||||
|
* pointer to untyped u64 array, where each u64 can actually be a typed
|
||||||
|
* pointer or integer of different size. Instead of requring user to write
|
||||||
|
* manual casts and work with array elements by index, BPF_PROG macro
|
||||||
|
* allows user to declare a list of named and typed input arguments in the
|
||||||
|
* same syntax as for normal C function. All the casting is hidden and
|
||||||
|
* performed transparently, while user code can just assume working with
|
||||||
|
* function arguments of specified type and name.
|
||||||
|
*
|
||||||
|
* Original raw context argument is preserved as well as 'ctx' argument.
|
||||||
|
* This is useful when using BPF helpers that expect original context
|
||||||
|
* as one of the parameters (e.g., for bpf_perf_event_output()).
|
||||||
|
*/
|
||||||
|
#define BPF_PROG(name, args...) \
|
||||||
|
name(unsigned long long *ctx); \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(unsigned long long *ctx, ##args); \
|
||||||
|
typeof(name(0)) name(unsigned long long *ctx) \
|
||||||
|
{ \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
return ____##name(___bpf_ctx_cast(args)); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
} \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(unsigned long long *ctx, ##args)
|
||||||
|
|
||||||
|
struct pt_regs;
|
||||||
|
|
||||||
|
#define ___bpf_kprobe_args0() ctx
|
||||||
|
#define ___bpf_kprobe_args1(x) ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
|
||||||
|
#define ___bpf_kprobe_args2(x, args...) ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx)
|
||||||
|
#define ___bpf_kprobe_args3(x, args...) ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx)
|
||||||
|
#define ___bpf_kprobe_args4(x, args...) ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx)
|
||||||
|
#define ___bpf_kprobe_args5(x, args...) ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx)
|
||||||
|
#define ___bpf_kprobe_args(args...) ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for
|
||||||
|
* tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific
|
||||||
|
* low-level way of getting kprobe input arguments from struct pt_regs, and
|
||||||
|
* provides a familiar typed and named function arguments syntax and
|
||||||
|
* semantics of accessing kprobe input paremeters.
|
||||||
|
*
|
||||||
|
* Original struct pt_regs* context is preserved as 'ctx' argument. This might
|
||||||
|
* be necessary when using BPF helpers like bpf_perf_event_output().
|
||||||
|
*/
|
||||||
|
#define BPF_KPROBE(name, args...) \
|
||||||
|
name(struct pt_regs *ctx); \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(struct pt_regs *ctx, ##args); \
|
||||||
|
typeof(name(0)) name(struct pt_regs *ctx) \
|
||||||
|
{ \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
return ____##name(___bpf_kprobe_args(args)); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
} \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(struct pt_regs *ctx, ##args)
|
||||||
|
|
||||||
|
#define ___bpf_kretprobe_args0() ctx
|
||||||
|
#define ___bpf_kretprobe_args1(x) ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx)
|
||||||
|
#define ___bpf_kretprobe_args(args...) ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_KRETPROBE is similar to BPF_KPROBE, except, it only provides optional
|
||||||
|
* return value (in addition to `struct pt_regs *ctx`), but no input
|
||||||
|
* arguments, because they will be clobbered by the time probed function
|
||||||
|
* returns.
|
||||||
|
*/
|
||||||
|
#define BPF_KRETPROBE(name, args...) \
|
||||||
|
name(struct pt_regs *ctx); \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(struct pt_regs *ctx, ##args); \
|
||||||
|
typeof(name(0)) name(struct pt_regs *ctx) \
|
||||||
|
{ \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
return ____##name(___bpf_kretprobe_args(args)); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
} \
|
||||||
|
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
|
||||||
|
|
||||||
|
/* If kernel has CONFIG_ARCH_HAS_SYSCALL_WRAPPER, read pt_regs directly */
|
||||||
|
#define ___bpf_syscall_args0() ctx
|
||||||
|
#define ___bpf_syscall_args1(x) ___bpf_syscall_args0(), (void *)PT_REGS_PARM1_SYSCALL(regs)
|
||||||
|
#define ___bpf_syscall_args2(x, args...) ___bpf_syscall_args1(args), (void *)PT_REGS_PARM2_SYSCALL(regs)
|
||||||
|
#define ___bpf_syscall_args3(x, args...) ___bpf_syscall_args2(args), (void *)PT_REGS_PARM3_SYSCALL(regs)
|
||||||
|
#define ___bpf_syscall_args4(x, args...) ___bpf_syscall_args3(args), (void *)PT_REGS_PARM4_SYSCALL(regs)
|
||||||
|
#define ___bpf_syscall_args5(x, args...) ___bpf_syscall_args4(args), (void *)PT_REGS_PARM5_SYSCALL(regs)
|
||||||
|
#define ___bpf_syscall_args(args...) ___bpf_apply(___bpf_syscall_args, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/* If kernel doesn't have CONFIG_ARCH_HAS_SYSCALL_WRAPPER, we have to BPF_CORE_READ from pt_regs */
|
||||||
|
#define ___bpf_syswrap_args0() ctx
|
||||||
|
#define ___bpf_syswrap_args1(x) ___bpf_syswrap_args0(), (void *)PT_REGS_PARM1_CORE_SYSCALL(regs)
|
||||||
|
#define ___bpf_syswrap_args2(x, args...) ___bpf_syswrap_args1(args), (void *)PT_REGS_PARM2_CORE_SYSCALL(regs)
|
||||||
|
#define ___bpf_syswrap_args3(x, args...) ___bpf_syswrap_args2(args), (void *)PT_REGS_PARM3_CORE_SYSCALL(regs)
|
||||||
|
#define ___bpf_syswrap_args4(x, args...) ___bpf_syswrap_args3(args), (void *)PT_REGS_PARM4_CORE_SYSCALL(regs)
|
||||||
|
#define ___bpf_syswrap_args5(x, args...) ___bpf_syswrap_args4(args), (void *)PT_REGS_PARM5_CORE_SYSCALL(regs)
|
||||||
|
#define ___bpf_syswrap_args(args...) ___bpf_apply(___bpf_syswrap_args, ___bpf_narg(args))(args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BPF_KSYSCALL is a variant of BPF_KPROBE, which is intended for
|
||||||
|
* tracing syscall functions, like __x64_sys_close. It hides the underlying
|
||||||
|
* platform-specific low-level way of getting syscall input arguments from
|
||||||
|
* struct pt_regs, and provides a familiar typed and named function arguments
|
||||||
|
* syntax and semantics of accessing syscall input parameters.
|
||||||
|
*
|
||||||
|
* Original struct pt_regs * context is preserved as 'ctx' argument. This might
|
||||||
|
* be necessary when using BPF helpers like bpf_perf_event_output().
|
||||||
|
*
|
||||||
|
* At the moment BPF_KSYSCALL does not transparently handle all the calling
|
||||||
|
* convention quirks for the following syscalls:
|
||||||
|
*
|
||||||
|
* - mmap(): __ARCH_WANT_SYS_OLD_MMAP.
|
||||||
|
* - clone(): CONFIG_CLONE_BACKWARDS, CONFIG_CLONE_BACKWARDS2 and
|
||||||
|
* CONFIG_CLONE_BACKWARDS3.
|
||||||
|
* - socket-related syscalls: __ARCH_WANT_SYS_SOCKETCALL.
|
||||||
|
* - compat syscalls.
|
||||||
|
*
|
||||||
|
* This may or may not change in the future. User needs to take extra measures
|
||||||
|
* to handle such quirks explicitly, if necessary.
|
||||||
|
*
|
||||||
|
* This macro relies on BPF CO-RE support and virtual __kconfig externs.
|
||||||
|
*/
|
||||||
|
#define BPF_KSYSCALL(name, args...) \
|
||||||
|
name(struct pt_regs *ctx); \
|
||||||
|
extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(struct pt_regs *ctx, ##args); \
|
||||||
|
typeof(name(0)) name(struct pt_regs *ctx) \
|
||||||
|
{ \
|
||||||
|
struct pt_regs *regs = LINUX_HAS_SYSCALL_WRAPPER \
|
||||||
|
? (struct pt_regs *)PT_REGS_PARM1(ctx) \
|
||||||
|
: ctx; \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||||
|
if (LINUX_HAS_SYSCALL_WRAPPER) \
|
||||||
|
return ____##name(___bpf_syswrap_args(args)); \
|
||||||
|
else \
|
||||||
|
return ____##name(___bpf_syscall_args(args)); \
|
||||||
|
_Pragma("GCC diagnostic pop") \
|
||||||
|
} \
|
||||||
|
static __always_inline typeof(name(0)) \
|
||||||
|
____##name(struct pt_regs *ctx, ##args)
|
||||||
|
|
||||||
|
#define BPF_KPROBE_SYSCALL BPF_KSYSCALL
|
||||||
|
|
||||||
|
#endif
|
||||||
395
src/btf.h
395
src/btf.h
@@ -1,21 +1,21 @@
|
|||||||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
/* Copyright (c) 2018 Facebook */
|
/* Copyright (c) 2018 Facebook */
|
||||||
|
/*! \file */
|
||||||
|
|
||||||
#ifndef __LIBBPF_BTF_H
|
#ifndef __LIBBPF_BTF_H
|
||||||
#define __LIBBPF_BTF_H
|
#define __LIBBPF_BTF_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <linux/btf.h>
|
#include <linux/btf.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include "libbpf_common.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LIBBPF_API
|
|
||||||
#define LIBBPF_API __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BTF_ELF_SEC ".BTF"
|
#define BTF_ELF_SEC ".BTF"
|
||||||
#define BTF_EXT_ELF_SEC ".BTF.ext"
|
#define BTF_EXT_ELF_SEC ".BTF.ext"
|
||||||
#define MAPS_ELF_SEC ".maps"
|
#define MAPS_ELF_SEC ".maps"
|
||||||
@@ -26,108 +26,297 @@ struct btf_type;
|
|||||||
|
|
||||||
struct bpf_object;
|
struct bpf_object;
|
||||||
|
|
||||||
/*
|
enum btf_endianness {
|
||||||
* The .BTF.ext ELF section layout defined as
|
BTF_LITTLE_ENDIAN = 0,
|
||||||
* struct btf_ext_header
|
BTF_BIG_ENDIAN = 1,
|
||||||
* func_info subsection
|
|
||||||
*
|
|
||||||
* The func_info subsection layout:
|
|
||||||
* record size for struct bpf_func_info in the func_info subsection
|
|
||||||
* struct btf_sec_func_info for section #1
|
|
||||||
* a list of bpf_func_info records for section #1
|
|
||||||
* where struct bpf_func_info mimics one in include/uapi/linux/bpf.h
|
|
||||||
* but may not be identical
|
|
||||||
* struct btf_sec_func_info for section #2
|
|
||||||
* a list of bpf_func_info records for section #2
|
|
||||||
* ......
|
|
||||||
*
|
|
||||||
* Note that the bpf_func_info record size in .BTF.ext may not
|
|
||||||
* be the same as the one defined in include/uapi/linux/bpf.h.
|
|
||||||
* The loader should ensure that record_size meets minimum
|
|
||||||
* requirement and pass the record as is to the kernel. The
|
|
||||||
* kernel will handle the func_info properly based on its contents.
|
|
||||||
*/
|
|
||||||
struct btf_ext_header {
|
|
||||||
__u16 magic;
|
|
||||||
__u8 version;
|
|
||||||
__u8 flags;
|
|
||||||
__u32 hdr_len;
|
|
||||||
|
|
||||||
/* All offsets are in bytes relative to the end of this header */
|
|
||||||
__u32 func_info_off;
|
|
||||||
__u32 func_info_len;
|
|
||||||
__u32 line_info_off;
|
|
||||||
__u32 line_info_len;
|
|
||||||
|
|
||||||
/* optional part of .BTF.ext header */
|
|
||||||
__u32 offset_reloc_off;
|
|
||||||
__u32 offset_reloc_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **btf__free()** frees all data of a BTF object
|
||||||
|
* @param btf BTF object to free
|
||||||
|
*/
|
||||||
LIBBPF_API void btf__free(struct btf *btf);
|
LIBBPF_API void btf__free(struct btf *btf);
|
||||||
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
|
|
||||||
LIBBPF_API struct btf *btf__parse_elf(const char *path,
|
/**
|
||||||
struct btf_ext **btf_ext);
|
* @brief **btf__new()** creates a new instance of a BTF object from the raw
|
||||||
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
|
* bytes of an ELF's BTF section
|
||||||
LIBBPF_API int btf__load(struct btf *btf);
|
* @param data raw bytes
|
||||||
|
* @param size number of bytes passed in `data`
|
||||||
|
* @return new BTF object instance which has to be eventually freed with
|
||||||
|
* **btf__free()**
|
||||||
|
*
|
||||||
|
* On error, error-code-encoded-as-pointer is returned, not a NULL. To extract
|
||||||
|
* error code from such a pointer `libbpf_get_error()` should be used. If
|
||||||
|
* `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is
|
||||||
|
* returned on error instead. In both cases thread-local `errno` variable is
|
||||||
|
* always set to error code as well.
|
||||||
|
*/
|
||||||
|
LIBBPF_API struct btf *btf__new(const void *data, __u32 size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **btf__new_split()** create a new instance of a BTF object from the
|
||||||
|
* provided raw data bytes. It takes another BTF instance, **base_btf**, which
|
||||||
|
* serves as a base BTF, which is extended by types in a newly created BTF
|
||||||
|
* instance
|
||||||
|
* @param data raw bytes
|
||||||
|
* @param size length of raw bytes
|
||||||
|
* @param base_btf the base BTF object
|
||||||
|
* @return new BTF object instance which has to be eventually freed with
|
||||||
|
* **btf__free()**
|
||||||
|
*
|
||||||
|
* If *base_btf* is NULL, `btf__new_split()` is equivalent to `btf__new()` and
|
||||||
|
* creates non-split BTF.
|
||||||
|
*
|
||||||
|
* On error, error-code-encoded-as-pointer is returned, not a NULL. To extract
|
||||||
|
* error code from such a pointer `libbpf_get_error()` should be used. If
|
||||||
|
* `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is
|
||||||
|
* returned on error instead. In both cases thread-local `errno` variable is
|
||||||
|
* always set to error code as well.
|
||||||
|
*/
|
||||||
|
LIBBPF_API struct btf *btf__new_split(const void *data, __u32 size, struct btf *base_btf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **btf__new_empty()** creates an empty BTF object. Use
|
||||||
|
* `btf__add_*()` to populate such BTF object.
|
||||||
|
* @return new BTF object instance which has to be eventually freed with
|
||||||
|
* **btf__free()**
|
||||||
|
*
|
||||||
|
* On error, error-code-encoded-as-pointer is returned, not a NULL. To extract
|
||||||
|
* error code from such a pointer `libbpf_get_error()` should be used. If
|
||||||
|
* `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is
|
||||||
|
* returned on error instead. In both cases thread-local `errno` variable is
|
||||||
|
* always set to error code as well.
|
||||||
|
*/
|
||||||
|
LIBBPF_API struct btf *btf__new_empty(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **btf__new_empty_split()** creates an unpopulated BTF object from an
|
||||||
|
* ELF BTF section except with a base BTF on top of which split BTF should be
|
||||||
|
* based
|
||||||
|
* @return new BTF object instance which has to be eventually freed with
|
||||||
|
* **btf__free()**
|
||||||
|
*
|
||||||
|
* If *base_btf* is NULL, `btf__new_empty_split()` is equivalent to
|
||||||
|
* `btf__new_empty()` and creates non-split BTF.
|
||||||
|
*
|
||||||
|
* On error, error-code-encoded-as-pointer is returned, not a NULL. To extract
|
||||||
|
* error code from such a pointer `libbpf_get_error()` should be used. If
|
||||||
|
* `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is
|
||||||
|
* returned on error instead. In both cases thread-local `errno` variable is
|
||||||
|
* always set to error code as well.
|
||||||
|
*/
|
||||||
|
LIBBPF_API struct btf *btf__new_empty_split(struct btf *base_btf);
|
||||||
|
|
||||||
|
LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext);
|
||||||
|
LIBBPF_API struct btf *btf__parse_split(const char *path, struct btf *base_btf);
|
||||||
|
LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext);
|
||||||
|
LIBBPF_API struct btf *btf__parse_elf_split(const char *path, struct btf *base_btf);
|
||||||
|
LIBBPF_API struct btf *btf__parse_raw(const char *path);
|
||||||
|
LIBBPF_API struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf);
|
||||||
|
|
||||||
|
LIBBPF_API struct btf *btf__load_vmlinux_btf(void);
|
||||||
|
LIBBPF_API struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_btf);
|
||||||
|
|
||||||
|
LIBBPF_API struct btf *btf__load_from_kernel_by_id(__u32 id);
|
||||||
|
LIBBPF_API struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf);
|
||||||
|
|
||||||
|
LIBBPF_API int btf__load_into_kernel(struct btf *btf);
|
||||||
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
||||||
const char *type_name);
|
const char *type_name);
|
||||||
LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
|
LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
|
||||||
|
const char *type_name, __u32 kind);
|
||||||
|
LIBBPF_API __u32 btf__type_cnt(const struct btf *btf);
|
||||||
|
LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
|
||||||
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
|
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
|
||||||
__u32 id);
|
__u32 id);
|
||||||
|
LIBBPF_API size_t btf__pointer_size(const struct btf *btf);
|
||||||
|
LIBBPF_API int btf__set_pointer_size(struct btf *btf, size_t ptr_sz);
|
||||||
|
LIBBPF_API enum btf_endianness btf__endianness(const struct btf *btf);
|
||||||
|
LIBBPF_API int btf__set_endianness(struct btf *btf, enum btf_endianness endian);
|
||||||
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
||||||
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
||||||
|
LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
|
||||||
LIBBPF_API int btf__fd(const struct btf *btf);
|
LIBBPF_API int btf__fd(const struct btf *btf);
|
||||||
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
LIBBPF_API void btf__set_fd(struct btf *btf, int fd);
|
||||||
|
LIBBPF_API const void *btf__raw_data(const struct btf *btf, __u32 *size);
|
||||||
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||||
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
|
LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset);
|
||||||
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
|
|
||||||
__u32 expected_key_size,
|
|
||||||
__u32 expected_value_size,
|
|
||||||
__u32 *key_type_id, __u32 *value_type_id);
|
|
||||||
|
|
||||||
LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
|
LIBBPF_API struct btf_ext *btf_ext__new(const __u8 *data, __u32 size);
|
||||||
LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
|
LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
|
||||||
LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext,
|
LIBBPF_API const void *btf_ext__raw_data(const struct btf_ext *btf_ext, __u32 *size);
|
||||||
__u32 *size);
|
|
||||||
LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf,
|
|
||||||
const struct btf_ext *btf_ext,
|
|
||||||
const char *sec_name, __u32 insns_cnt,
|
|
||||||
void **func_info, __u32 *cnt);
|
|
||||||
LIBBPF_API int btf_ext__reloc_line_info(const struct btf *btf,
|
|
||||||
const struct btf_ext *btf_ext,
|
|
||||||
const char *sec_name, __u32 insns_cnt,
|
|
||||||
void **line_info, __u32 *cnt);
|
|
||||||
LIBBPF_API __u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
|
|
||||||
LIBBPF_API __u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
|
|
||||||
|
|
||||||
struct btf_dedup_opts {
|
LIBBPF_API int btf__find_str(struct btf *btf, const char *s);
|
||||||
unsigned int dedup_table_size;
|
LIBBPF_API int btf__add_str(struct btf *btf, const char *s);
|
||||||
bool dont_resolve_fwds;
|
LIBBPF_API int btf__add_type(struct btf *btf, const struct btf *src_btf,
|
||||||
|
const struct btf_type *src_type);
|
||||||
|
/**
|
||||||
|
* @brief **btf__add_btf()** appends all the BTF types from *src_btf* into *btf*
|
||||||
|
* @param btf BTF object which all the BTF types and strings are added to
|
||||||
|
* @param src_btf BTF object which all BTF types and referenced strings are copied from
|
||||||
|
* @return BTF type ID of the first appended BTF type, or negative error code
|
||||||
|
*
|
||||||
|
* **btf__add_btf()** can be used to simply and efficiently append the entire
|
||||||
|
* contents of one BTF object to another one. All the BTF type data is copied
|
||||||
|
* over, all referenced type IDs are adjusted by adding a necessary ID offset.
|
||||||
|
* Only strings referenced from BTF types are copied over and deduplicated, so
|
||||||
|
* if there were some unused strings in *src_btf*, those won't be copied over,
|
||||||
|
* which is consistent with the general string deduplication semantics of BTF
|
||||||
|
* writing APIs.
|
||||||
|
*
|
||||||
|
* If any error is encountered during this process, the contents of *btf* is
|
||||||
|
* left intact, which means that **btf__add_btf()** follows the transactional
|
||||||
|
* semantics and the operation as a whole is all-or-nothing.
|
||||||
|
*
|
||||||
|
* *src_btf* has to be non-split BTF, as of now copying types from split BTF
|
||||||
|
* is not supported and will result in -ENOTSUP error code returned.
|
||||||
|
*/
|
||||||
|
LIBBPF_API int btf__add_btf(struct btf *btf, const struct btf *src_btf);
|
||||||
|
|
||||||
|
LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
|
||||||
|
LIBBPF_API int btf__add_float(struct btf *btf, const char *name, size_t byte_sz);
|
||||||
|
LIBBPF_API int btf__add_ptr(struct btf *btf, int ref_type_id);
|
||||||
|
LIBBPF_API int btf__add_array(struct btf *btf,
|
||||||
|
int index_type_id, int elem_type_id, __u32 nr_elems);
|
||||||
|
/* struct/union construction APIs */
|
||||||
|
LIBBPF_API int btf__add_struct(struct btf *btf, const char *name, __u32 sz);
|
||||||
|
LIBBPF_API int btf__add_union(struct btf *btf, const char *name, __u32 sz);
|
||||||
|
LIBBPF_API int btf__add_field(struct btf *btf, const char *name, int field_type_id,
|
||||||
|
__u32 bit_offset, __u32 bit_size);
|
||||||
|
|
||||||
|
/* enum construction APIs */
|
||||||
|
LIBBPF_API int btf__add_enum(struct btf *btf, const char *name, __u32 bytes_sz);
|
||||||
|
LIBBPF_API int btf__add_enum_value(struct btf *btf, const char *name, __s64 value);
|
||||||
|
LIBBPF_API int btf__add_enum64(struct btf *btf, const char *name, __u32 bytes_sz, bool is_signed);
|
||||||
|
LIBBPF_API int btf__add_enum64_value(struct btf *btf, const char *name, __u64 value);
|
||||||
|
|
||||||
|
enum btf_fwd_kind {
|
||||||
|
BTF_FWD_STRUCT = 0,
|
||||||
|
BTF_FWD_UNION = 1,
|
||||||
|
BTF_FWD_ENUM = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBBPF_API int btf__dedup(struct btf *btf, struct btf_ext *btf_ext,
|
LIBBPF_API int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind);
|
||||||
const struct btf_dedup_opts *opts);
|
LIBBPF_API int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id);
|
||||||
|
LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id);
|
||||||
|
LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id);
|
||||||
|
LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id);
|
||||||
|
LIBBPF_API int btf__add_type_tag(struct btf *btf, const char *value, int ref_type_id);
|
||||||
|
|
||||||
|
/* func and func_proto construction APIs */
|
||||||
|
LIBBPF_API int btf__add_func(struct btf *btf, const char *name,
|
||||||
|
enum btf_func_linkage linkage, int proto_type_id);
|
||||||
|
LIBBPF_API int btf__add_func_proto(struct btf *btf, int ret_type_id);
|
||||||
|
LIBBPF_API int btf__add_func_param(struct btf *btf, const char *name, int type_id);
|
||||||
|
|
||||||
|
/* var & datasec construction APIs */
|
||||||
|
LIBBPF_API int btf__add_var(struct btf *btf, const char *name, int linkage, int type_id);
|
||||||
|
LIBBPF_API int btf__add_datasec(struct btf *btf, const char *name, __u32 byte_sz);
|
||||||
|
LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id,
|
||||||
|
__u32 offset, __u32 byte_sz);
|
||||||
|
|
||||||
|
/* tag construction API */
|
||||||
|
LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_type_id,
|
||||||
|
int component_idx);
|
||||||
|
|
||||||
|
struct btf_dedup_opts {
|
||||||
|
size_t sz;
|
||||||
|
/* optional .BTF.ext info to dedup along the main BTF info */
|
||||||
|
struct btf_ext *btf_ext;
|
||||||
|
/* force hash collisions (used for testing) */
|
||||||
|
bool force_collisions;
|
||||||
|
size_t :0;
|
||||||
|
};
|
||||||
|
#define btf_dedup_opts__last_field force_collisions
|
||||||
|
|
||||||
|
LIBBPF_API int btf__dedup(struct btf *btf, const struct btf_dedup_opts *opts);
|
||||||
|
|
||||||
struct btf_dump;
|
struct btf_dump;
|
||||||
|
|
||||||
struct btf_dump_opts {
|
struct btf_dump_opts {
|
||||||
void *ctx;
|
size_t sz;
|
||||||
};
|
};
|
||||||
|
#define btf_dump_opts__last_field sz
|
||||||
|
|
||||||
typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args);
|
typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args);
|
||||||
|
|
||||||
LIBBPF_API struct btf_dump *btf_dump__new(const struct btf *btf,
|
LIBBPF_API struct btf_dump *btf_dump__new(const struct btf *btf,
|
||||||
const struct btf_ext *btf_ext,
|
btf_dump_printf_fn_t printf_fn,
|
||||||
const struct btf_dump_opts *opts,
|
void *ctx,
|
||||||
btf_dump_printf_fn_t printf_fn);
|
const struct btf_dump_opts *opts);
|
||||||
|
|
||||||
LIBBPF_API void btf_dump__free(struct btf_dump *d);
|
LIBBPF_API void btf_dump__free(struct btf_dump *d);
|
||||||
|
|
||||||
LIBBPF_API int btf_dump__dump_type(struct btf_dump *d, __u32 id);
|
LIBBPF_API int btf_dump__dump_type(struct btf_dump *d, __u32 id);
|
||||||
|
|
||||||
|
struct btf_dump_emit_type_decl_opts {
|
||||||
|
/* size of this struct, for forward/backward compatiblity */
|
||||||
|
size_t sz;
|
||||||
|
/* optional field name for type declaration, e.g.:
|
||||||
|
* - struct my_struct <FNAME>
|
||||||
|
* - void (*<FNAME>)(int)
|
||||||
|
* - char (*<FNAME>)[123]
|
||||||
|
*/
|
||||||
|
const char *field_name;
|
||||||
|
/* extra indentation level (in number of tabs) to emit for multi-line
|
||||||
|
* type declarations (e.g., anonymous struct); applies for lines
|
||||||
|
* starting from the second one (first line is assumed to have
|
||||||
|
* necessary indentation already
|
||||||
|
*/
|
||||||
|
int indent_level;
|
||||||
|
/* strip all the const/volatile/restrict mods */
|
||||||
|
bool strip_mods;
|
||||||
|
size_t :0;
|
||||||
|
};
|
||||||
|
#define btf_dump_emit_type_decl_opts__last_field strip_mods
|
||||||
|
|
||||||
|
LIBBPF_API int
|
||||||
|
btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
|
||||||
|
const struct btf_dump_emit_type_decl_opts *opts);
|
||||||
|
|
||||||
|
|
||||||
|
struct btf_dump_type_data_opts {
|
||||||
|
/* size of this struct, for forward/backward compatibility */
|
||||||
|
size_t sz;
|
||||||
|
const char *indent_str;
|
||||||
|
int indent_level;
|
||||||
|
/* below match "show" flags for bpf_show_snprintf() */
|
||||||
|
bool compact; /* no newlines/indentation */
|
||||||
|
bool skip_names; /* skip member/type names */
|
||||||
|
bool emit_zeroes; /* show 0-valued fields */
|
||||||
|
size_t :0;
|
||||||
|
};
|
||||||
|
#define btf_dump_type_data_opts__last_field emit_zeroes
|
||||||
|
|
||||||
|
LIBBPF_API int
|
||||||
|
btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
|
||||||
|
const void *data, size_t data_sz,
|
||||||
|
const struct btf_dump_type_data_opts *opts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A set of helpers for easier BTF types handling
|
* A set of helpers for easier BTF types handling.
|
||||||
|
*
|
||||||
|
* The inline functions below rely on constants from the kernel headers which
|
||||||
|
* may not be available for applications including this header file. To avoid
|
||||||
|
* compilation errors, we define all the constants here that were added after
|
||||||
|
* the initial introduction of the BTF_KIND* constants.
|
||||||
*/
|
*/
|
||||||
|
#ifndef BTF_KIND_FUNC
|
||||||
|
#define BTF_KIND_FUNC 12 /* Function */
|
||||||
|
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
|
||||||
|
#endif
|
||||||
|
#ifndef BTF_KIND_VAR
|
||||||
|
#define BTF_KIND_VAR 14 /* Variable */
|
||||||
|
#define BTF_KIND_DATASEC 15 /* Section */
|
||||||
|
#endif
|
||||||
|
#ifndef BTF_KIND_FLOAT
|
||||||
|
#define BTF_KIND_FLOAT 16 /* Floating point */
|
||||||
|
#endif
|
||||||
|
/* The kernel header switched to enums, so the following were never #defined */
|
||||||
|
#define BTF_KIND_DECL_TAG 17 /* Decl Tag */
|
||||||
|
#define BTF_KIND_TYPE_TAG 18 /* Type Tag */
|
||||||
|
#define BTF_KIND_ENUM64 19 /* Enum for up-to 64bit values */
|
||||||
|
|
||||||
static inline __u16 btf_kind(const struct btf_type *t)
|
static inline __u16 btf_kind(const struct btf_type *t)
|
||||||
{
|
{
|
||||||
return BTF_INFO_KIND(t->info);
|
return BTF_INFO_KIND(t->info);
|
||||||
@@ -143,6 +332,11 @@ static inline bool btf_kflag(const struct btf_type *t)
|
|||||||
return BTF_INFO_KFLAG(t->info);
|
return BTF_INFO_KFLAG(t->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_void(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_UNKN;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool btf_is_int(const struct btf_type *t)
|
static inline bool btf_is_int(const struct btf_type *t)
|
||||||
{
|
{
|
||||||
return btf_kind(t) == BTF_KIND_INT;
|
return btf_kind(t) == BTF_KIND_INT;
|
||||||
@@ -180,6 +374,11 @@ static inline bool btf_is_enum(const struct btf_type *t)
|
|||||||
return btf_kind(t) == BTF_KIND_ENUM;
|
return btf_kind(t) == BTF_KIND_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_enum64(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_ENUM64;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool btf_is_fwd(const struct btf_type *t)
|
static inline bool btf_is_fwd(const struct btf_type *t)
|
||||||
{
|
{
|
||||||
return btf_kind(t) == BTF_KIND_FWD;
|
return btf_kind(t) == BTF_KIND_FWD;
|
||||||
@@ -211,7 +410,8 @@ static inline bool btf_is_mod(const struct btf_type *t)
|
|||||||
|
|
||||||
return kind == BTF_KIND_VOLATILE ||
|
return kind == BTF_KIND_VOLATILE ||
|
||||||
kind == BTF_KIND_CONST ||
|
kind == BTF_KIND_CONST ||
|
||||||
kind == BTF_KIND_RESTRICT;
|
kind == BTF_KIND_RESTRICT ||
|
||||||
|
kind == BTF_KIND_TYPE_TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool btf_is_func(const struct btf_type *t)
|
static inline bool btf_is_func(const struct btf_type *t)
|
||||||
@@ -234,6 +434,33 @@ static inline bool btf_is_datasec(const struct btf_type *t)
|
|||||||
return btf_kind(t) == BTF_KIND_DATASEC;
|
return btf_kind(t) == BTF_KIND_DATASEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_float(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_decl_tag(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_DECL_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_type_tag(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_any_enum(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_is_enum(t) || btf_is_enum64(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_kind_core_compat(const struct btf_type *t1,
|
||||||
|
const struct btf_type *t2)
|
||||||
|
{
|
||||||
|
return btf_kind(t1) == btf_kind(t2) ||
|
||||||
|
(btf_is_any_enum(t1) && btf_is_any_enum(t2));
|
||||||
|
}
|
||||||
|
|
||||||
static inline __u8 btf_int_encoding(const struct btf_type *t)
|
static inline __u8 btf_int_encoding(const struct btf_type *t)
|
||||||
{
|
{
|
||||||
return BTF_INT_ENCODING(*(__u32 *)(t + 1));
|
return BTF_INT_ENCODING(*(__u32 *)(t + 1));
|
||||||
@@ -259,6 +486,16 @@ static inline struct btf_enum *btf_enum(const struct btf_type *t)
|
|||||||
return (struct btf_enum *)(t + 1);
|
return (struct btf_enum *)(t + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (struct btf_enum64 *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __u64 btf_enum64_value(const struct btf_enum64 *e)
|
||||||
|
{
|
||||||
|
return ((__u64)e->val_hi32 << 32) | e->val_lo32;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct btf_member *btf_members(const struct btf_type *t)
|
static inline struct btf_member *btf_members(const struct btf_type *t)
|
||||||
{
|
{
|
||||||
return (struct btf_member *)(t + 1);
|
return (struct btf_member *)(t + 1);
|
||||||
@@ -302,6 +539,12 @@ btf_var_secinfos(const struct btf_type *t)
|
|||||||
return (struct btf_var_secinfo *)(t + 1);
|
return (struct btf_var_secinfo *)(t + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct btf_decl_tag;
|
||||||
|
static inline struct btf_decl_tag *btf_decl_tag(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (struct btf_decl_tag *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1324
src/btf_dump.c
1324
src/btf_dump.c
File diff suppressed because it is too large
Load Diff
1121
src/gen_loader.c
Normal file
1121
src/gen_loader.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,12 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
|
|
||||||
|
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||||
|
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||||
|
|
||||||
|
/* prevent accidental re-addition of reallocarray() */
|
||||||
|
#pragma GCC poison reallocarray
|
||||||
|
|
||||||
/* start with 4 buckets */
|
/* start with 4 buckets */
|
||||||
#define HASHMAP_MIN_CAP_BITS 2
|
#define HASHMAP_MIN_CAP_BITS 2
|
||||||
|
|
||||||
@@ -56,13 +62,20 @@ struct hashmap *hashmap__new(hashmap_hash_fn hash_fn,
|
|||||||
|
|
||||||
void hashmap__clear(struct hashmap *map)
|
void hashmap__clear(struct hashmap *map)
|
||||||
{
|
{
|
||||||
|
struct hashmap_entry *cur, *tmp;
|
||||||
|
size_t bkt;
|
||||||
|
|
||||||
|
hashmap__for_each_entry_safe(map, cur, tmp, bkt) {
|
||||||
|
free(cur);
|
||||||
|
}
|
||||||
free(map->buckets);
|
free(map->buckets);
|
||||||
|
map->buckets = NULL;
|
||||||
map->cap = map->cap_bits = map->sz = 0;
|
map->cap = map->cap_bits = map->sz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashmap__free(struct hashmap *map)
|
void hashmap__free(struct hashmap *map)
|
||||||
{
|
{
|
||||||
if (!map)
|
if (IS_ERR_OR_NULL(map))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hashmap__clear(map);
|
hashmap__clear(map);
|
||||||
@@ -90,8 +103,7 @@ static int hashmap_grow(struct hashmap *map)
|
|||||||
struct hashmap_entry **new_buckets;
|
struct hashmap_entry **new_buckets;
|
||||||
struct hashmap_entry *cur, *tmp;
|
struct hashmap_entry *cur, *tmp;
|
||||||
size_t new_cap_bits, new_cap;
|
size_t new_cap_bits, new_cap;
|
||||||
size_t h;
|
size_t h, bkt;
|
||||||
int bkt;
|
|
||||||
|
|
||||||
new_cap_bits = map->cap_bits + 1;
|
new_cap_bits = map->cap_bits + 1;
|
||||||
if (new_cap_bits < HASHMAP_MIN_CAP_BITS)
|
if (new_cap_bits < HASHMAP_MIN_CAP_BITS)
|
||||||
@@ -226,4 +238,3 @@ bool hashmap__delete(struct hashmap *map, const void *key,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,17 +10,34 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#ifdef __GLIBC__
|
#include <limits.h>
|
||||||
#include <bits/wordsize.h>
|
|
||||||
#else
|
|
||||||
#include <bits/reg.h>
|
|
||||||
#endif
|
|
||||||
#include "libbpf_internal.h"
|
|
||||||
|
|
||||||
static inline size_t hash_bits(size_t h, int bits)
|
static inline size_t hash_bits(size_t h, int bits)
|
||||||
{
|
{
|
||||||
/* shuffle bits and return requested number of upper bits */
|
/* shuffle bits and return requested number of upper bits */
|
||||||
return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
if (bits == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||||
|
/* LP64 case */
|
||||||
|
return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||||
|
#elif (__SIZEOF_SIZE_T__ <= __SIZEOF_LONG__)
|
||||||
|
return (h * 2654435769lu) >> (__SIZEOF_LONG__ * 8 - bits);
|
||||||
|
#else
|
||||||
|
# error "Unsupported size_t size"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generic C-string hashing function */
|
||||||
|
static inline size_t str_hash(const char *s)
|
||||||
|
{
|
||||||
|
size_t h = 0;
|
||||||
|
|
||||||
|
while (*s) {
|
||||||
|
h = h * 31 + *s;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||||
@@ -160,17 +177,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
|||||||
* @key: key to iterate entries for
|
* @key: key to iterate entries for
|
||||||
*/
|
*/
|
||||||
#define hashmap__for_each_key_entry(map, cur, _key) \
|
#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||||
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
for (cur = map->buckets \
|
||||||
map->cap_bits); \
|
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||||
map->buckets ? map->buckets[bkt] : NULL; }); \
|
: NULL; \
|
||||||
cur; \
|
cur; \
|
||||||
cur = cur->next) \
|
cur = cur->next) \
|
||||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||||
|
|
||||||
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||||
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
for (cur = map->buckets \
|
||||||
map->cap_bits); \
|
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||||
cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
: NULL; \
|
||||||
cur && ({ tmp = cur->next; true; }); \
|
cur && ({ tmp = cur->next; true; }); \
|
||||||
cur = tmp) \
|
cur = tmp) \
|
||||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||||
|
|||||||
13719
src/libbpf.c
13719
src/libbpf.c
File diff suppressed because it is too large
Load Diff
1470
src/libbpf.h
1470
src/libbpf.h
File diff suppressed because it is too large
Load Diff
348
src/libbpf.map
348
src/libbpf.map
@@ -1,29 +1,14 @@
|
|||||||
LIBBPF_0.0.1 {
|
LIBBPF_0.0.1 {
|
||||||
global:
|
global:
|
||||||
bpf_btf_get_fd_by_id;
|
bpf_btf_get_fd_by_id;
|
||||||
bpf_create_map;
|
|
||||||
bpf_create_map_in_map;
|
|
||||||
bpf_create_map_in_map_node;
|
|
||||||
bpf_create_map_name;
|
|
||||||
bpf_create_map_node;
|
|
||||||
bpf_create_map_xattr;
|
|
||||||
bpf_load_btf;
|
|
||||||
bpf_load_program;
|
|
||||||
bpf_load_program_xattr;
|
|
||||||
bpf_map__btf_key_type_id;
|
bpf_map__btf_key_type_id;
|
||||||
bpf_map__btf_value_type_id;
|
bpf_map__btf_value_type_id;
|
||||||
bpf_map__def;
|
|
||||||
bpf_map__fd;
|
bpf_map__fd;
|
||||||
bpf_map__is_offload_neutral;
|
|
||||||
bpf_map__name;
|
bpf_map__name;
|
||||||
bpf_map__next;
|
|
||||||
bpf_map__pin;
|
bpf_map__pin;
|
||||||
bpf_map__prev;
|
|
||||||
bpf_map__priv;
|
|
||||||
bpf_map__reuse_fd;
|
bpf_map__reuse_fd;
|
||||||
bpf_map__set_ifindex;
|
bpf_map__set_ifindex;
|
||||||
bpf_map__set_inner_map_fd;
|
bpf_map__set_inner_map_fd;
|
||||||
bpf_map__set_priv;
|
|
||||||
bpf_map__unpin;
|
bpf_map__unpin;
|
||||||
bpf_map_delete_elem;
|
bpf_map_delete_elem;
|
||||||
bpf_map_get_fd_by_id;
|
bpf_map_get_fd_by_id;
|
||||||
@@ -38,79 +23,37 @@ LIBBPF_0.0.1 {
|
|||||||
bpf_object__btf_fd;
|
bpf_object__btf_fd;
|
||||||
bpf_object__close;
|
bpf_object__close;
|
||||||
bpf_object__find_map_by_name;
|
bpf_object__find_map_by_name;
|
||||||
bpf_object__find_map_by_offset;
|
|
||||||
bpf_object__find_program_by_title;
|
|
||||||
bpf_object__kversion;
|
bpf_object__kversion;
|
||||||
bpf_object__load;
|
bpf_object__load;
|
||||||
bpf_object__name;
|
bpf_object__name;
|
||||||
bpf_object__next;
|
|
||||||
bpf_object__open;
|
bpf_object__open;
|
||||||
bpf_object__open_buffer;
|
|
||||||
bpf_object__open_xattr;
|
|
||||||
bpf_object__pin;
|
bpf_object__pin;
|
||||||
bpf_object__pin_maps;
|
bpf_object__pin_maps;
|
||||||
bpf_object__pin_programs;
|
bpf_object__pin_programs;
|
||||||
bpf_object__priv;
|
|
||||||
bpf_object__set_priv;
|
|
||||||
bpf_object__unload;
|
|
||||||
bpf_object__unpin_maps;
|
bpf_object__unpin_maps;
|
||||||
bpf_object__unpin_programs;
|
bpf_object__unpin_programs;
|
||||||
bpf_perf_event_read_simple;
|
|
||||||
bpf_prog_attach;
|
bpf_prog_attach;
|
||||||
bpf_prog_detach;
|
bpf_prog_detach;
|
||||||
bpf_prog_detach2;
|
bpf_prog_detach2;
|
||||||
bpf_prog_get_fd_by_id;
|
bpf_prog_get_fd_by_id;
|
||||||
bpf_prog_get_next_id;
|
bpf_prog_get_next_id;
|
||||||
bpf_prog_load;
|
|
||||||
bpf_prog_load_xattr;
|
|
||||||
bpf_prog_query;
|
bpf_prog_query;
|
||||||
bpf_prog_test_run;
|
|
||||||
bpf_prog_test_run_xattr;
|
|
||||||
bpf_program__fd;
|
bpf_program__fd;
|
||||||
bpf_program__is_kprobe;
|
|
||||||
bpf_program__is_perf_event;
|
|
||||||
bpf_program__is_raw_tracepoint;
|
|
||||||
bpf_program__is_sched_act;
|
|
||||||
bpf_program__is_sched_cls;
|
|
||||||
bpf_program__is_socket_filter;
|
|
||||||
bpf_program__is_tracepoint;
|
|
||||||
bpf_program__is_xdp;
|
|
||||||
bpf_program__load;
|
|
||||||
bpf_program__next;
|
|
||||||
bpf_program__nth_fd;
|
|
||||||
bpf_program__pin;
|
bpf_program__pin;
|
||||||
bpf_program__pin_instance;
|
|
||||||
bpf_program__prev;
|
|
||||||
bpf_program__priv;
|
|
||||||
bpf_program__set_expected_attach_type;
|
bpf_program__set_expected_attach_type;
|
||||||
bpf_program__set_ifindex;
|
bpf_program__set_ifindex;
|
||||||
bpf_program__set_kprobe;
|
|
||||||
bpf_program__set_perf_event;
|
|
||||||
bpf_program__set_prep;
|
|
||||||
bpf_program__set_priv;
|
|
||||||
bpf_program__set_raw_tracepoint;
|
|
||||||
bpf_program__set_sched_act;
|
|
||||||
bpf_program__set_sched_cls;
|
|
||||||
bpf_program__set_socket_filter;
|
|
||||||
bpf_program__set_tracepoint;
|
|
||||||
bpf_program__set_type;
|
bpf_program__set_type;
|
||||||
bpf_program__set_xdp;
|
|
||||||
bpf_program__title;
|
|
||||||
bpf_program__unload;
|
bpf_program__unload;
|
||||||
bpf_program__unpin;
|
bpf_program__unpin;
|
||||||
bpf_program__unpin_instance;
|
|
||||||
bpf_prog_linfo__free;
|
bpf_prog_linfo__free;
|
||||||
bpf_prog_linfo__new;
|
bpf_prog_linfo__new;
|
||||||
bpf_prog_linfo__lfind_addr_func;
|
bpf_prog_linfo__lfind_addr_func;
|
||||||
bpf_prog_linfo__lfind;
|
bpf_prog_linfo__lfind;
|
||||||
bpf_raw_tracepoint_open;
|
bpf_raw_tracepoint_open;
|
||||||
bpf_set_link_xdp_fd;
|
|
||||||
bpf_task_fd_query;
|
bpf_task_fd_query;
|
||||||
bpf_verify_program;
|
|
||||||
btf__fd;
|
btf__fd;
|
||||||
btf__find_by_name;
|
btf__find_by_name;
|
||||||
btf__free;
|
btf__free;
|
||||||
btf__get_from_id;
|
|
||||||
btf__name_by_offset;
|
btf__name_by_offset;
|
||||||
btf__new;
|
btf__new;
|
||||||
btf__resolve_size;
|
btf__resolve_size;
|
||||||
@@ -127,48 +70,24 @@ LIBBPF_0.0.1 {
|
|||||||
|
|
||||||
LIBBPF_0.0.2 {
|
LIBBPF_0.0.2 {
|
||||||
global:
|
global:
|
||||||
bpf_probe_helper;
|
|
||||||
bpf_probe_map_type;
|
|
||||||
bpf_probe_prog_type;
|
|
||||||
bpf_map__resize;
|
|
||||||
bpf_map_lookup_elem_flags;
|
bpf_map_lookup_elem_flags;
|
||||||
bpf_object__btf;
|
bpf_object__btf;
|
||||||
bpf_object__find_map_fd_by_name;
|
bpf_object__find_map_fd_by_name;
|
||||||
bpf_get_link_xdp_id;
|
|
||||||
btf__dedup;
|
|
||||||
btf__get_map_kv_tids;
|
|
||||||
btf__get_nr_types;
|
|
||||||
btf__get_raw_data;
|
btf__get_raw_data;
|
||||||
btf__load;
|
|
||||||
btf_ext__free;
|
btf_ext__free;
|
||||||
btf_ext__func_info_rec_size;
|
|
||||||
btf_ext__get_raw_data;
|
btf_ext__get_raw_data;
|
||||||
btf_ext__line_info_rec_size;
|
|
||||||
btf_ext__new;
|
btf_ext__new;
|
||||||
btf_ext__reloc_func_info;
|
|
||||||
btf_ext__reloc_line_info;
|
|
||||||
xsk_umem__create;
|
|
||||||
xsk_socket__create;
|
|
||||||
xsk_umem__delete;
|
|
||||||
xsk_socket__delete;
|
|
||||||
xsk_umem__fd;
|
|
||||||
xsk_socket__fd;
|
|
||||||
bpf_program__get_prog_info_linear;
|
|
||||||
bpf_program__bpil_addr_to_offs;
|
|
||||||
bpf_program__bpil_offs_to_addr;
|
|
||||||
} LIBBPF_0.0.1;
|
} LIBBPF_0.0.1;
|
||||||
|
|
||||||
LIBBPF_0.0.3 {
|
LIBBPF_0.0.3 {
|
||||||
global:
|
global:
|
||||||
bpf_map__is_internal;
|
bpf_map__is_internal;
|
||||||
bpf_map_freeze;
|
bpf_map_freeze;
|
||||||
btf__finalize_data;
|
|
||||||
} LIBBPF_0.0.2;
|
} LIBBPF_0.0.2;
|
||||||
|
|
||||||
LIBBPF_0.0.4 {
|
LIBBPF_0.0.4 {
|
||||||
global:
|
global:
|
||||||
bpf_link__destroy;
|
bpf_link__destroy;
|
||||||
bpf_object__load_xattr;
|
|
||||||
bpf_program__attach_kprobe;
|
bpf_program__attach_kprobe;
|
||||||
bpf_program__attach_perf_event;
|
bpf_program__attach_perf_event;
|
||||||
bpf_program__attach_raw_tracepoint;
|
bpf_program__attach_raw_tracepoint;
|
||||||
@@ -176,17 +95,276 @@ LIBBPF_0.0.4 {
|
|||||||
bpf_program__attach_uprobe;
|
bpf_program__attach_uprobe;
|
||||||
btf_dump__dump_type;
|
btf_dump__dump_type;
|
||||||
btf_dump__free;
|
btf_dump__free;
|
||||||
btf_dump__new;
|
|
||||||
btf__parse_elf;
|
btf__parse_elf;
|
||||||
libbpf_num_possible_cpus;
|
libbpf_num_possible_cpus;
|
||||||
perf_buffer__free;
|
perf_buffer__free;
|
||||||
perf_buffer__new;
|
|
||||||
perf_buffer__new_raw;
|
|
||||||
perf_buffer__poll;
|
perf_buffer__poll;
|
||||||
xsk_umem__create;
|
|
||||||
} LIBBPF_0.0.3;
|
} LIBBPF_0.0.3;
|
||||||
|
|
||||||
LIBBPF_0.0.5 {
|
LIBBPF_0.0.5 {
|
||||||
global:
|
global:
|
||||||
bpf_btf_get_next_id;
|
bpf_btf_get_next_id;
|
||||||
} LIBBPF_0.0.4;
|
} LIBBPF_0.0.4;
|
||||||
|
|
||||||
|
LIBBPF_0.0.6 {
|
||||||
|
global:
|
||||||
|
bpf_map__get_pin_path;
|
||||||
|
bpf_map__is_pinned;
|
||||||
|
bpf_map__set_pin_path;
|
||||||
|
bpf_object__open_file;
|
||||||
|
bpf_object__open_mem;
|
||||||
|
bpf_program__attach_trace;
|
||||||
|
bpf_program__get_expected_attach_type;
|
||||||
|
bpf_program__get_type;
|
||||||
|
btf__find_by_name_kind;
|
||||||
|
libbpf_find_vmlinux_btf_id;
|
||||||
|
} LIBBPF_0.0.5;
|
||||||
|
|
||||||
|
LIBBPF_0.0.7 {
|
||||||
|
global:
|
||||||
|
btf_dump__emit_type_decl;
|
||||||
|
bpf_link__disconnect;
|
||||||
|
bpf_map__attach_struct_ops;
|
||||||
|
bpf_map_delete_batch;
|
||||||
|
bpf_map_lookup_and_delete_batch;
|
||||||
|
bpf_map_lookup_batch;
|
||||||
|
bpf_map_update_batch;
|
||||||
|
bpf_object__find_program_by_name;
|
||||||
|
bpf_object__attach_skeleton;
|
||||||
|
bpf_object__destroy_skeleton;
|
||||||
|
bpf_object__detach_skeleton;
|
||||||
|
bpf_object__load_skeleton;
|
||||||
|
bpf_object__open_skeleton;
|
||||||
|
bpf_program__attach;
|
||||||
|
bpf_program__name;
|
||||||
|
btf__align_of;
|
||||||
|
libbpf_find_kernel_btf;
|
||||||
|
} LIBBPF_0.0.6;
|
||||||
|
|
||||||
|
LIBBPF_0.0.8 {
|
||||||
|
global:
|
||||||
|
bpf_link__fd;
|
||||||
|
bpf_link__open;
|
||||||
|
bpf_link__pin;
|
||||||
|
bpf_link__pin_path;
|
||||||
|
bpf_link__unpin;
|
||||||
|
bpf_link__update_program;
|
||||||
|
bpf_link_create;
|
||||||
|
bpf_link_update;
|
||||||
|
bpf_map__set_initial_value;
|
||||||
|
bpf_prog_attach_opts;
|
||||||
|
bpf_program__attach_cgroup;
|
||||||
|
bpf_program__attach_lsm;
|
||||||
|
bpf_program__set_attach_target;
|
||||||
|
} LIBBPF_0.0.7;
|
||||||
|
|
||||||
|
LIBBPF_0.0.9 {
|
||||||
|
global:
|
||||||
|
bpf_enable_stats;
|
||||||
|
bpf_iter_create;
|
||||||
|
bpf_link_get_fd_by_id;
|
||||||
|
bpf_link_get_next_id;
|
||||||
|
bpf_program__attach_iter;
|
||||||
|
bpf_program__attach_netns;
|
||||||
|
perf_buffer__consume;
|
||||||
|
ring_buffer__add;
|
||||||
|
ring_buffer__consume;
|
||||||
|
ring_buffer__free;
|
||||||
|
ring_buffer__new;
|
||||||
|
ring_buffer__poll;
|
||||||
|
} LIBBPF_0.0.8;
|
||||||
|
|
||||||
|
LIBBPF_0.1.0 {
|
||||||
|
global:
|
||||||
|
bpf_link__detach;
|
||||||
|
bpf_link_detach;
|
||||||
|
bpf_map__ifindex;
|
||||||
|
bpf_map__key_size;
|
||||||
|
bpf_map__map_flags;
|
||||||
|
bpf_map__max_entries;
|
||||||
|
bpf_map__numa_node;
|
||||||
|
bpf_map__set_key_size;
|
||||||
|
bpf_map__set_map_flags;
|
||||||
|
bpf_map__set_max_entries;
|
||||||
|
bpf_map__set_numa_node;
|
||||||
|
bpf_map__set_type;
|
||||||
|
bpf_map__set_value_size;
|
||||||
|
bpf_map__type;
|
||||||
|
bpf_map__value_size;
|
||||||
|
bpf_program__attach_xdp;
|
||||||
|
bpf_program__autoload;
|
||||||
|
bpf_program__set_autoload;
|
||||||
|
btf__parse;
|
||||||
|
btf__parse_raw;
|
||||||
|
btf__pointer_size;
|
||||||
|
btf__set_fd;
|
||||||
|
btf__set_pointer_size;
|
||||||
|
} LIBBPF_0.0.9;
|
||||||
|
|
||||||
|
LIBBPF_0.2.0 {
|
||||||
|
global:
|
||||||
|
bpf_prog_bind_map;
|
||||||
|
bpf_prog_test_run_opts;
|
||||||
|
bpf_program__attach_freplace;
|
||||||
|
bpf_program__section_name;
|
||||||
|
btf__add_array;
|
||||||
|
btf__add_const;
|
||||||
|
btf__add_enum;
|
||||||
|
btf__add_enum_value;
|
||||||
|
btf__add_datasec;
|
||||||
|
btf__add_datasec_var_info;
|
||||||
|
btf__add_field;
|
||||||
|
btf__add_func;
|
||||||
|
btf__add_func_param;
|
||||||
|
btf__add_func_proto;
|
||||||
|
btf__add_fwd;
|
||||||
|
btf__add_int;
|
||||||
|
btf__add_ptr;
|
||||||
|
btf__add_restrict;
|
||||||
|
btf__add_str;
|
||||||
|
btf__add_struct;
|
||||||
|
btf__add_typedef;
|
||||||
|
btf__add_union;
|
||||||
|
btf__add_var;
|
||||||
|
btf__add_volatile;
|
||||||
|
btf__endianness;
|
||||||
|
btf__find_str;
|
||||||
|
btf__new_empty;
|
||||||
|
btf__set_endianness;
|
||||||
|
btf__str_by_offset;
|
||||||
|
perf_buffer__buffer_cnt;
|
||||||
|
perf_buffer__buffer_fd;
|
||||||
|
perf_buffer__epoll_fd;
|
||||||
|
perf_buffer__consume_buffer;
|
||||||
|
} LIBBPF_0.1.0;
|
||||||
|
|
||||||
|
LIBBPF_0.3.0 {
|
||||||
|
global:
|
||||||
|
btf__base_btf;
|
||||||
|
btf__parse_elf_split;
|
||||||
|
btf__parse_raw_split;
|
||||||
|
btf__parse_split;
|
||||||
|
btf__new_empty_split;
|
||||||
|
btf__new_split;
|
||||||
|
ring_buffer__epoll_fd;
|
||||||
|
} LIBBPF_0.2.0;
|
||||||
|
|
||||||
|
LIBBPF_0.4.0 {
|
||||||
|
global:
|
||||||
|
btf__add_float;
|
||||||
|
btf__add_type;
|
||||||
|
bpf_linker__add_file;
|
||||||
|
bpf_linker__finalize;
|
||||||
|
bpf_linker__free;
|
||||||
|
bpf_linker__new;
|
||||||
|
bpf_map__inner_map;
|
||||||
|
bpf_object__set_kversion;
|
||||||
|
bpf_tc_attach;
|
||||||
|
bpf_tc_detach;
|
||||||
|
bpf_tc_hook_create;
|
||||||
|
bpf_tc_hook_destroy;
|
||||||
|
bpf_tc_query;
|
||||||
|
} LIBBPF_0.3.0;
|
||||||
|
|
||||||
|
LIBBPF_0.5.0 {
|
||||||
|
global:
|
||||||
|
bpf_map__initial_value;
|
||||||
|
bpf_map__pin_path;
|
||||||
|
bpf_map_lookup_and_delete_elem_flags;
|
||||||
|
bpf_program__attach_kprobe_opts;
|
||||||
|
bpf_program__attach_perf_event_opts;
|
||||||
|
bpf_program__attach_tracepoint_opts;
|
||||||
|
bpf_program__attach_uprobe_opts;
|
||||||
|
bpf_object__gen_loader;
|
||||||
|
btf__load_from_kernel_by_id;
|
||||||
|
btf__load_from_kernel_by_id_split;
|
||||||
|
btf__load_into_kernel;
|
||||||
|
btf__load_module_btf;
|
||||||
|
btf__load_vmlinux_btf;
|
||||||
|
btf_dump__dump_type_data;
|
||||||
|
libbpf_set_strict_mode;
|
||||||
|
} LIBBPF_0.4.0;
|
||||||
|
|
||||||
|
LIBBPF_0.6.0 {
|
||||||
|
global:
|
||||||
|
bpf_map__map_extra;
|
||||||
|
bpf_map__set_map_extra;
|
||||||
|
bpf_map_create;
|
||||||
|
bpf_object__next_map;
|
||||||
|
bpf_object__next_program;
|
||||||
|
bpf_object__prev_map;
|
||||||
|
bpf_object__prev_program;
|
||||||
|
bpf_prog_load;
|
||||||
|
bpf_program__flags;
|
||||||
|
bpf_program__insn_cnt;
|
||||||
|
bpf_program__insns;
|
||||||
|
bpf_program__set_flags;
|
||||||
|
btf__add_btf;
|
||||||
|
btf__add_decl_tag;
|
||||||
|
btf__add_type_tag;
|
||||||
|
btf__dedup;
|
||||||
|
btf__raw_data;
|
||||||
|
btf__type_cnt;
|
||||||
|
btf_dump__new;
|
||||||
|
libbpf_major_version;
|
||||||
|
libbpf_minor_version;
|
||||||
|
libbpf_version_string;
|
||||||
|
perf_buffer__new;
|
||||||
|
perf_buffer__new_raw;
|
||||||
|
} LIBBPF_0.5.0;
|
||||||
|
|
||||||
|
LIBBPF_0.7.0 {
|
||||||
|
global:
|
||||||
|
bpf_btf_load;
|
||||||
|
bpf_program__expected_attach_type;
|
||||||
|
bpf_program__log_buf;
|
||||||
|
bpf_program__log_level;
|
||||||
|
bpf_program__set_log_buf;
|
||||||
|
bpf_program__set_log_level;
|
||||||
|
bpf_program__type;
|
||||||
|
bpf_xdp_attach;
|
||||||
|
bpf_xdp_detach;
|
||||||
|
bpf_xdp_query;
|
||||||
|
bpf_xdp_query_id;
|
||||||
|
btf_ext__raw_data;
|
||||||
|
libbpf_probe_bpf_helper;
|
||||||
|
libbpf_probe_bpf_map_type;
|
||||||
|
libbpf_probe_bpf_prog_type;
|
||||||
|
libbpf_set_memlock_rlim;
|
||||||
|
} LIBBPF_0.6.0;
|
||||||
|
|
||||||
|
LIBBPF_0.8.0 {
|
||||||
|
global:
|
||||||
|
bpf_map__autocreate;
|
||||||
|
bpf_map__get_next_key;
|
||||||
|
bpf_map__delete_elem;
|
||||||
|
bpf_map__lookup_and_delete_elem;
|
||||||
|
bpf_map__lookup_elem;
|
||||||
|
bpf_map__set_autocreate;
|
||||||
|
bpf_map__update_elem;
|
||||||
|
bpf_map_delete_elem_flags;
|
||||||
|
bpf_object__destroy_subskeleton;
|
||||||
|
bpf_object__open_subskeleton;
|
||||||
|
bpf_program__attach_kprobe_multi_opts;
|
||||||
|
bpf_program__attach_trace_opts;
|
||||||
|
bpf_program__attach_usdt;
|
||||||
|
bpf_program__set_insns;
|
||||||
|
libbpf_register_prog_handler;
|
||||||
|
libbpf_unregister_prog_handler;
|
||||||
|
} LIBBPF_0.7.0;
|
||||||
|
|
||||||
|
LIBBPF_1.0.0 {
|
||||||
|
global:
|
||||||
|
bpf_obj_get_opts;
|
||||||
|
bpf_prog_query_opts;
|
||||||
|
bpf_program__attach_ksyscall;
|
||||||
|
bpf_program__autoattach;
|
||||||
|
bpf_program__set_autoattach;
|
||||||
|
btf__add_enum64;
|
||||||
|
btf__add_enum64_value;
|
||||||
|
libbpf_bpf_attach_type_str;
|
||||||
|
libbpf_bpf_link_type_str;
|
||||||
|
libbpf_bpf_map_type_str;
|
||||||
|
libbpf_bpf_prog_type_str;
|
||||||
|
perf_buffer__buffer;
|
||||||
|
};
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ Name: libbpf
|
|||||||
Description: BPF library
|
Description: BPF library
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
Libs: -L${libdir} -lbpf
|
Libs: -L${libdir} -lbpf
|
||||||
Requires.private: libelf
|
Requires.private: libelf zlib
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|||||||
73
src/libbpf_common.h
Normal file
73
src/libbpf_common.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common user-facing libbpf helpers.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Facebook
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LIBBPF_LIBBPF_COMMON_H
|
||||||
|
#define __LIBBPF_LIBBPF_COMMON_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "libbpf_version.h"
|
||||||
|
|
||||||
|
#ifndef LIBBPF_API
|
||||||
|
#define LIBBPF_API __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
|
|
||||||
|
/* Mark a symbol as deprecated when libbpf version is >= {major}.{minor} */
|
||||||
|
#define LIBBPF_DEPRECATED_SINCE(major, minor, msg) \
|
||||||
|
__LIBBPF_MARK_DEPRECATED_ ## major ## _ ## minor \
|
||||||
|
(LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg))
|
||||||
|
|
||||||
|
#define __LIBBPF_CURRENT_VERSION_GEQ(major, minor) \
|
||||||
|
(LIBBPF_MAJOR_VERSION > (major) || \
|
||||||
|
(LIBBPF_MAJOR_VERSION == (major) && LIBBPF_MINOR_VERSION >= (minor)))
|
||||||
|
|
||||||
|
/* Add checks for other versions below when planning deprecation of API symbols
|
||||||
|
* with the LIBBPF_DEPRECATED_SINCE macro.
|
||||||
|
*/
|
||||||
|
#if __LIBBPF_CURRENT_VERSION_GEQ(1, 0)
|
||||||
|
#define __LIBBPF_MARK_DEPRECATED_1_0(X) X
|
||||||
|
#else
|
||||||
|
#define __LIBBPF_MARK_DEPRECATED_1_0(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This set of internal macros allows to do "function overloading" based on
|
||||||
|
* number of arguments provided by used in backwards-compatible way during the
|
||||||
|
* transition to libbpf 1.0
|
||||||
|
* It's ugly but necessary evil that will be cleaned up when we get to 1.0.
|
||||||
|
* See bpf_prog_load() overload for example.
|
||||||
|
*/
|
||||||
|
#define ___libbpf_cat(A, B) A ## B
|
||||||
|
#define ___libbpf_select(NAME, NUM) ___libbpf_cat(NAME, NUM)
|
||||||
|
#define ___libbpf_nth(_1, _2, _3, _4, _5, _6, N, ...) N
|
||||||
|
#define ___libbpf_cnt(...) ___libbpf_nth(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
|
||||||
|
#define ___libbpf_overload(NAME, ...) ___libbpf_select(NAME, ___libbpf_cnt(__VA_ARGS__))(__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Helper macro to declare and initialize libbpf options struct
|
||||||
|
*
|
||||||
|
* This dance with uninitialized declaration, followed by memset to zero,
|
||||||
|
* followed by assignment using compound literal syntax is done to preserve
|
||||||
|
* ability to use a nice struct field initialization syntax and **hopefully**
|
||||||
|
* have all the padding bytes initialized to zero. It's not guaranteed though,
|
||||||
|
* when copying literal, that compiler won't copy garbage in literal's padding
|
||||||
|
* bytes, but that's the best way I've found and it seems to work in practice.
|
||||||
|
*
|
||||||
|
* Macro declares opts struct of given type and name, zero-initializes,
|
||||||
|
* including any extra padding, it with memset() and then assigns initial
|
||||||
|
* values provided by users in struct initializer-syntax as varargs.
|
||||||
|
*/
|
||||||
|
#define LIBBPF_OPTS(TYPE, NAME, ...) \
|
||||||
|
struct TYPE NAME = ({ \
|
||||||
|
memset(&NAME, 0, sizeof(struct TYPE)); \
|
||||||
|
(struct TYPE) { \
|
||||||
|
.sz = sizeof(struct TYPE), \
|
||||||
|
__VA_ARGS__ \
|
||||||
|
}; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif /* __LIBBPF_LIBBPF_COMMON_H */
|
||||||
@@ -12,6 +12,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "libbpf.h"
|
#include "libbpf.h"
|
||||||
|
#include "libbpf_internal.h"
|
||||||
|
|
||||||
|
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||||
|
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||||
|
|
||||||
#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
|
#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
|
||||||
#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
|
#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
|
||||||
@@ -36,7 +40,7 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
|
|||||||
int libbpf_strerror(int err, char *buf, size_t size)
|
int libbpf_strerror(int err, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
if (!buf || !size)
|
if (!buf || !size)
|
||||||
return -1;
|
return libbpf_err(-EINVAL);
|
||||||
|
|
||||||
err = err > 0 ? err : -err;
|
err = err > 0 ? err : -err;
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@ int libbpf_strerror(int err, char *buf, size_t size)
|
|||||||
|
|
||||||
ret = strerror_r(err, buf, size);
|
ret = strerror_r(err, buf, size);
|
||||||
buf[size - 1] = '\0';
|
buf[size - 1] = '\0';
|
||||||
return ret;
|
return libbpf_err_errno(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err < __LIBBPF_ERRNO__END) {
|
if (err < __LIBBPF_ERRNO__END) {
|
||||||
@@ -59,5 +63,5 @@ int libbpf_strerror(int err, char *buf, size_t size)
|
|||||||
|
|
||||||
snprintf(buf, size, "Unknown libbpf error %d", err);
|
snprintf(buf, size, "Unknown libbpf error %d", err);
|
||||||
buf[size - 1] = '\0';
|
buf[size - 1] = '\0';
|
||||||
return -1;
|
return libbpf_err(-ENOENT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,53 @@
|
|||||||
#ifndef __LIBBPF_LIBBPF_INTERNAL_H
|
#ifndef __LIBBPF_LIBBPF_INTERNAL_H
|
||||||
#define __LIBBPF_LIBBPF_INTERNAL_H
|
#define __LIBBPF_LIBBPF_INTERNAL_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "relo_core.h"
|
||||||
|
|
||||||
|
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||||
|
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||||
|
|
||||||
|
/* prevent accidental re-addition of reallocarray() */
|
||||||
|
#pragma GCC poison reallocarray
|
||||||
|
|
||||||
#include "libbpf.h"
|
#include "libbpf.h"
|
||||||
|
#include "btf.h"
|
||||||
|
|
||||||
|
#ifndef EM_BPF
|
||||||
|
#define EM_BPF 247
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef R_BPF_64_64
|
||||||
|
#define R_BPF_64_64 1
|
||||||
|
#endif
|
||||||
|
#ifndef R_BPF_64_ABS64
|
||||||
|
#define R_BPF_64_ABS64 2
|
||||||
|
#endif
|
||||||
|
#ifndef R_BPF_64_ABS32
|
||||||
|
#define R_BPF_64_ABS32 3
|
||||||
|
#endif
|
||||||
|
#ifndef R_BPF_64_32
|
||||||
|
#define R_BPF_64_32 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SHT_LLVM_ADDRSIG
|
||||||
|
#define SHT_LLVM_ADDRSIG 0x6FFF4C03
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* if libelf is old and doesn't support mmap(), fall back to read() */
|
||||||
|
#ifndef ELF_C_READ_MMAP
|
||||||
|
#define ELF_C_READ_MMAP ELF_C_READ
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Older libelf all end up in this expression, for both 32 and 64 bit */
|
||||||
|
#ifndef ELF64_ST_VISIBILITY
|
||||||
|
#define ELF64_ST_VISIBILITY(o) ((o) & 0x03)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
|
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
|
||||||
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
|
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
|
||||||
@@ -22,7 +68,19 @@
|
|||||||
#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
|
#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
|
||||||
#define BTF_PARAM_ENC(name, type) (name), (type)
|
#define BTF_PARAM_ENC(name, type) (name), (type)
|
||||||
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
|
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
|
||||||
|
#define BTF_TYPE_FLOAT_ENC(name, sz) \
|
||||||
|
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
|
||||||
|
#define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \
|
||||||
|
BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx)
|
||||||
|
#define BTF_TYPE_TYPE_TAG_ENC(value, type) \
|
||||||
|
BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_TYPE_TAG, 0, 0), type)
|
||||||
|
|
||||||
|
#ifndef likely
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#endif
|
||||||
|
#ifndef unlikely
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#endif
|
||||||
#ifndef min
|
#ifndef min
|
||||||
# define min(x, y) ((x) < (y) ? (x) : (y))
|
# define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
@@ -33,21 +91,55 @@
|
|||||||
# define offsetofend(TYPE, FIELD) \
|
# define offsetofend(TYPE, FIELD) \
|
||||||
(offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
|
(offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __alias
|
||||||
|
#define __alias(symbol) __attribute__((alias(#symbol)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check whether a string `str` has prefix `pfx`, regardless if `pfx` is
|
||||||
|
* a string literal known at compilation time or char * pointer known only at
|
||||||
|
* runtime.
|
||||||
|
*/
|
||||||
|
#define str_has_pfx(str, pfx) \
|
||||||
|
(strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0)
|
||||||
|
|
||||||
|
/* suffix check */
|
||||||
|
static inline bool str_has_sfx(const char *str, const char *sfx)
|
||||||
|
{
|
||||||
|
size_t str_len = strlen(str);
|
||||||
|
size_t sfx_len = strlen(sfx);
|
||||||
|
|
||||||
|
if (sfx_len > str_len)
|
||||||
|
return false;
|
||||||
|
return strcmp(str + str_len - sfx_len, sfx) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Symbol versioning is different between static and shared library.
|
/* Symbol versioning is different between static and shared library.
|
||||||
* Properly versioned symbols are needed for shared library, but
|
* Properly versioned symbols are needed for shared library, but
|
||||||
* only the symbol of the new version is needed for static library.
|
* only the symbol of the new version is needed for static library.
|
||||||
|
* Starting with GNU C 10, use symver attribute instead of .symver assembler
|
||||||
|
* directive, which works better with GCC LTO builds.
|
||||||
*/
|
*/
|
||||||
#ifdef SHARED
|
#if defined(SHARED) && defined(__GNUC__) && __GNUC__ >= 10
|
||||||
# define COMPAT_VERSION(internal_name, api_name, version) \
|
|
||||||
|
#define DEFAULT_VERSION(internal_name, api_name, version) \
|
||||||
|
__attribute__((symver(#api_name "@@" #version)))
|
||||||
|
#define COMPAT_VERSION(internal_name, api_name, version) \
|
||||||
|
__attribute__((symver(#api_name "@" #version)))
|
||||||
|
|
||||||
|
#elif defined(SHARED)
|
||||||
|
|
||||||
|
#define COMPAT_VERSION(internal_name, api_name, version) \
|
||||||
asm(".symver " #internal_name "," #api_name "@" #version);
|
asm(".symver " #internal_name "," #api_name "@" #version);
|
||||||
# define DEFAULT_VERSION(internal_name, api_name, version) \
|
#define DEFAULT_VERSION(internal_name, api_name, version) \
|
||||||
asm(".symver " #internal_name "," #api_name "@@" #version);
|
asm(".symver " #internal_name "," #api_name "@@" #version);
|
||||||
#else
|
|
||||||
# define COMPAT_VERSION(internal_name, api_name, version)
|
#else /* !SHARED */
|
||||||
# define DEFAULT_VERSION(internal_name, api_name, version) \
|
|
||||||
|
#define COMPAT_VERSION(internal_name, api_name, version)
|
||||||
|
#define DEFAULT_VERSION(internal_name, api_name, version) \
|
||||||
extern typeof(internal_name) api_name \
|
extern typeof(internal_name) api_name \
|
||||||
__attribute__((alias(#internal_name)));
|
__attribute__((alias(#internal_name)));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void libbpf_print(enum libbpf_print_level level,
|
extern void libbpf_print(enum libbpf_print_level level,
|
||||||
@@ -59,12 +151,225 @@ do { \
|
|||||||
libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
|
libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define pr_warning(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
|
#define pr_warn(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
|
||||||
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
|
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
|
||||||
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
|
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifndef __has_builtin
|
||||||
|
#define __has_builtin(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct bpf_link {
|
||||||
|
int (*detach)(struct bpf_link *link);
|
||||||
|
void (*dealloc)(struct bpf_link *link);
|
||||||
|
char *pin_path; /* NULL, if not pinned */
|
||||||
|
int fd; /* hook FD, -1 if not applicable */
|
||||||
|
bool disconnected;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-implement glibc's reallocarray() for libbpf internal-only use.
|
||||||
|
* reallocarray(), unfortunately, is not available in all versions of glibc,
|
||||||
|
* so requires extra feature detection and using reallocarray() stub from
|
||||||
|
* <tools/libc_compat.h> and COMPAT_NEED_REALLOCARRAY. All this complicates
|
||||||
|
* build of libbpf unnecessarily and is just a maintenance burden. Instead,
|
||||||
|
* it's trivial to implement libbpf-specific internal version and use it
|
||||||
|
* throughout libbpf.
|
||||||
|
*/
|
||||||
|
static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
size_t total;
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_mul_overflow)
|
||||||
|
if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
if (size == 0 || nmemb > ULONG_MAX / size)
|
||||||
|
return NULL;
|
||||||
|
total = nmemb * size;
|
||||||
|
#endif
|
||||||
|
return realloc(ptr, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst
|
||||||
|
* is zero-terminated string no matter what (unless sz == 0, in which case
|
||||||
|
* it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs
|
||||||
|
* in what is returned. Given this is internal helper, it's trivial to extend
|
||||||
|
* this, when necessary. Use this instead of strncpy inside libbpf source code.
|
||||||
|
*/
|
||||||
|
static inline void libbpf_strlcpy(char *dst, const char *src, size_t sz)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (sz == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sz--;
|
||||||
|
for (i = 0; i < sz && src[i]; i++)
|
||||||
|
dst[i] = src[i];
|
||||||
|
dst[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
__u32 get_kernel_version(void);
|
||||||
|
|
||||||
|
struct btf;
|
||||||
|
struct btf_type;
|
||||||
|
|
||||||
|
struct btf_type *btf_type_by_id(const struct btf *btf, __u32 type_id);
|
||||||
|
const char *btf_kind_str(const struct btf_type *t);
|
||||||
|
const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id);
|
||||||
|
|
||||||
|
static inline enum btf_func_linkage btf_func_linkage(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (enum btf_func_linkage)(int)btf_vlen(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __u32 btf_type_info(int kind, int vlen, int kflag)
|
||||||
|
{
|
||||||
|
return (kflag << 31) | (kind << 24) | vlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum map_def_parts {
|
||||||
|
MAP_DEF_MAP_TYPE = 0x001,
|
||||||
|
MAP_DEF_KEY_TYPE = 0x002,
|
||||||
|
MAP_DEF_KEY_SIZE = 0x004,
|
||||||
|
MAP_DEF_VALUE_TYPE = 0x008,
|
||||||
|
MAP_DEF_VALUE_SIZE = 0x010,
|
||||||
|
MAP_DEF_MAX_ENTRIES = 0x020,
|
||||||
|
MAP_DEF_MAP_FLAGS = 0x040,
|
||||||
|
MAP_DEF_NUMA_NODE = 0x080,
|
||||||
|
MAP_DEF_PINNING = 0x100,
|
||||||
|
MAP_DEF_INNER_MAP = 0x200,
|
||||||
|
MAP_DEF_MAP_EXTRA = 0x400,
|
||||||
|
|
||||||
|
MAP_DEF_ALL = 0x7ff, /* combination of all above */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct btf_map_def {
|
||||||
|
enum map_def_parts parts;
|
||||||
|
__u32 map_type;
|
||||||
|
__u32 key_type_id;
|
||||||
|
__u32 key_size;
|
||||||
|
__u32 value_type_id;
|
||||||
|
__u32 value_size;
|
||||||
|
__u32 max_entries;
|
||||||
|
__u32 map_flags;
|
||||||
|
__u32 numa_node;
|
||||||
|
__u32 pinning;
|
||||||
|
__u64 map_extra;
|
||||||
|
};
|
||||||
|
|
||||||
|
int parse_btf_map_def(const char *map_name, struct btf *btf,
|
||||||
|
const struct btf_type *def_t, bool strict,
|
||||||
|
struct btf_map_def *map_def, struct btf_map_def *inner_def);
|
||||||
|
|
||||||
|
void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
|
||||||
|
size_t cur_cnt, size_t max_cnt, size_t add_cnt);
|
||||||
|
int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
|
||||||
|
|
||||||
|
static inline bool libbpf_is_mem_zeroed(const char *p, ssize_t len)
|
||||||
|
{
|
||||||
|
while (len > 0) {
|
||||||
|
if (*p)
|
||||||
|
return false;
|
||||||
|
p++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool libbpf_validate_opts(const char *opts,
|
||||||
|
size_t opts_sz, size_t user_sz,
|
||||||
|
const char *type_name)
|
||||||
|
{
|
||||||
|
if (user_sz < sizeof(size_t)) {
|
||||||
|
pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!libbpf_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
|
||||||
|
pr_warn("%s has non-zero extra bytes\n", type_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPTS_VALID(opts, type) \
|
||||||
|
(!(opts) || libbpf_validate_opts((const char *)opts, \
|
||||||
|
offsetofend(struct type, \
|
||||||
|
type##__last_field), \
|
||||||
|
(opts)->sz, #type))
|
||||||
|
#define OPTS_HAS(opts, field) \
|
||||||
|
((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
|
||||||
|
#define OPTS_GET(opts, field, fallback_value) \
|
||||||
|
(OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
|
||||||
|
#define OPTS_SET(opts, field, value) \
|
||||||
|
do { \
|
||||||
|
if (OPTS_HAS(opts, field)) \
|
||||||
|
(opts)->field = value; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define OPTS_ZEROED(opts, last_nonzero_field) \
|
||||||
|
({ \
|
||||||
|
ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
|
||||||
|
!(opts) || libbpf_is_mem_zeroed((const void *)opts + __off, \
|
||||||
|
(opts)->sz - __off); \
|
||||||
|
})
|
||||||
|
|
||||||
|
enum kern_feature_id {
|
||||||
|
/* v4.14: kernel support for program & map names. */
|
||||||
|
FEAT_PROG_NAME,
|
||||||
|
/* v5.2: kernel support for global data sections. */
|
||||||
|
FEAT_GLOBAL_DATA,
|
||||||
|
/* BTF support */
|
||||||
|
FEAT_BTF,
|
||||||
|
/* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */
|
||||||
|
FEAT_BTF_FUNC,
|
||||||
|
/* BTF_KIND_VAR and BTF_KIND_DATASEC support */
|
||||||
|
FEAT_BTF_DATASEC,
|
||||||
|
/* BTF_FUNC_GLOBAL is supported */
|
||||||
|
FEAT_BTF_GLOBAL_FUNC,
|
||||||
|
/* BPF_F_MMAPABLE is supported for arrays */
|
||||||
|
FEAT_ARRAY_MMAP,
|
||||||
|
/* kernel support for expected_attach_type in BPF_PROG_LOAD */
|
||||||
|
FEAT_EXP_ATTACH_TYPE,
|
||||||
|
/* bpf_probe_read_{kernel,user}[_str] helpers */
|
||||||
|
FEAT_PROBE_READ_KERN,
|
||||||
|
/* BPF_PROG_BIND_MAP is supported */
|
||||||
|
FEAT_PROG_BIND_MAP,
|
||||||
|
/* Kernel support for module BTFs */
|
||||||
|
FEAT_MODULE_BTF,
|
||||||
|
/* BTF_KIND_FLOAT support */
|
||||||
|
FEAT_BTF_FLOAT,
|
||||||
|
/* BPF perf link support */
|
||||||
|
FEAT_PERF_LINK,
|
||||||
|
/* BTF_KIND_DECL_TAG support */
|
||||||
|
FEAT_BTF_DECL_TAG,
|
||||||
|
/* BTF_KIND_TYPE_TAG support */
|
||||||
|
FEAT_BTF_TYPE_TAG,
|
||||||
|
/* memcg-based accounting for BPF maps and progs */
|
||||||
|
FEAT_MEMCG_ACCOUNT,
|
||||||
|
/* BPF cookie (bpf_get_attach_cookie() BPF helper) support */
|
||||||
|
FEAT_BPF_COOKIE,
|
||||||
|
/* BTF_KIND_ENUM64 support and BTF_KIND_ENUM kflag support */
|
||||||
|
FEAT_BTF_ENUM64,
|
||||||
|
/* Kernel uses syscall wrapper (CONFIG_ARCH_HAS_SYSCALL_WRAPPER) */
|
||||||
|
FEAT_SYSCALL_WRAPPER,
|
||||||
|
__FEAT_CNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
int probe_memcg_account(void);
|
||||||
|
bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id);
|
||||||
|
int bump_rlimit_memlock(void);
|
||||||
|
|
||||||
|
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
|
||||||
|
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
|
||||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||||
const char *str_sec, size_t str_len);
|
const char *str_sec, size_t str_len);
|
||||||
|
int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level);
|
||||||
|
|
||||||
|
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
|
||||||
|
void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
|
||||||
|
const char **prefix, int *kind);
|
||||||
|
|
||||||
struct btf_ext_info {
|
struct btf_ext_info {
|
||||||
/*
|
/*
|
||||||
@@ -74,6 +379,13 @@ struct btf_ext_info {
|
|||||||
void *info;
|
void *info;
|
||||||
__u32 rec_size;
|
__u32 rec_size;
|
||||||
__u32 len;
|
__u32 len;
|
||||||
|
/* optional (maintained internally by libbpf) mapping between .BTF.ext
|
||||||
|
* section and corresponding ELF section. This is used to join
|
||||||
|
* information like CO-RE relocation records with corresponding BPF
|
||||||
|
* programs defined in ELF sections
|
||||||
|
*/
|
||||||
|
__u32 *sec_idxs;
|
||||||
|
int sec_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define for_each_btf_ext_sec(seg, sec) \
|
#define for_each_btf_ext_sec(seg, sec) \
|
||||||
@@ -87,6 +399,44 @@ struct btf_ext_info {
|
|||||||
i < (sec)->num_info; \
|
i < (sec)->num_info; \
|
||||||
i++, rec = (void *)rec + (seg)->rec_size)
|
i++, rec = (void *)rec + (seg)->rec_size)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The .BTF.ext ELF section layout defined as
|
||||||
|
* struct btf_ext_header
|
||||||
|
* func_info subsection
|
||||||
|
*
|
||||||
|
* The func_info subsection layout:
|
||||||
|
* record size for struct bpf_func_info in the func_info subsection
|
||||||
|
* struct btf_sec_func_info for section #1
|
||||||
|
* a list of bpf_func_info records for section #1
|
||||||
|
* where struct bpf_func_info mimics one in include/uapi/linux/bpf.h
|
||||||
|
* but may not be identical
|
||||||
|
* struct btf_sec_func_info for section #2
|
||||||
|
* a list of bpf_func_info records for section #2
|
||||||
|
* ......
|
||||||
|
*
|
||||||
|
* Note that the bpf_func_info record size in .BTF.ext may not
|
||||||
|
* be the same as the one defined in include/uapi/linux/bpf.h.
|
||||||
|
* The loader should ensure that record_size meets minimum
|
||||||
|
* requirement and pass the record as is to the kernel. The
|
||||||
|
* kernel will handle the func_info properly based on its contents.
|
||||||
|
*/
|
||||||
|
struct btf_ext_header {
|
||||||
|
__u16 magic;
|
||||||
|
__u8 version;
|
||||||
|
__u8 flags;
|
||||||
|
__u32 hdr_len;
|
||||||
|
|
||||||
|
/* All offsets are in bytes relative to the end of this header */
|
||||||
|
__u32 func_info_off;
|
||||||
|
__u32 func_info_len;
|
||||||
|
__u32 line_info_off;
|
||||||
|
__u32 line_info_len;
|
||||||
|
|
||||||
|
/* optional part of .BTF.ext header */
|
||||||
|
__u32 core_relo_off;
|
||||||
|
__u32 core_relo_len;
|
||||||
|
};
|
||||||
|
|
||||||
struct btf_ext {
|
struct btf_ext {
|
||||||
union {
|
union {
|
||||||
struct btf_ext_header *hdr;
|
struct btf_ext_header *hdr;
|
||||||
@@ -94,7 +444,7 @@ struct btf_ext {
|
|||||||
};
|
};
|
||||||
struct btf_ext_info func_info;
|
struct btf_ext_info func_info;
|
||||||
struct btf_ext_info line_info;
|
struct btf_ext_info line_info;
|
||||||
struct btf_ext_info offset_reloc_info;
|
struct btf_ext_info core_relo_info;
|
||||||
__u32 data_size;
|
__u32 data_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,7 +452,7 @@ struct btf_ext_info_sec {
|
|||||||
__u32 sec_name_off;
|
__u32 sec_name_off;
|
||||||
__u32 num_info;
|
__u32 num_info;
|
||||||
/* Followed by num_info * record_size number of bytes */
|
/* Followed by num_info * record_size number of bytes */
|
||||||
__u8 data[0];
|
__u8 data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The minimum bpf_func_info checked by the loader */
|
/* The minimum bpf_func_info checked by the loader */
|
||||||
@@ -119,52 +469,111 @@ struct bpf_line_info_min {
|
|||||||
__u32 line_col;
|
__u32 line_col;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The minimum bpf_offset_reloc checked by the loader
|
|
||||||
*
|
typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
|
||||||
* Offset relocation captures the following data:
|
typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
|
||||||
* - insn_off - instruction offset (in bytes) within a BPF program that needs
|
int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx);
|
||||||
* its insn->imm field to be relocated with actual offset;
|
int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx);
|
||||||
* - type_id - BTF type ID of the "root" (containing) entity of a relocatable
|
int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
|
||||||
* offset;
|
int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
|
||||||
* - access_str_off - offset into corresponding .BTF string section. String
|
__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
|
||||||
* itself encodes an accessed field using a sequence of field and array
|
__u32 kind);
|
||||||
* indicies, separated by colon (:). It's conceptually very close to LLVM's
|
|
||||||
* getelementptr ([0]) instruction's arguments for identifying offset to
|
typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,
|
||||||
* a field.
|
const char *sym_name, void *ctx);
|
||||||
*
|
|
||||||
* Example to provide a better feel.
|
int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *arg);
|
||||||
*
|
|
||||||
* struct sample {
|
/* handle direct returned errors */
|
||||||
* int a;
|
static inline int libbpf_err(int ret)
|
||||||
* struct {
|
{
|
||||||
* int b[10];
|
if (ret < 0)
|
||||||
* };
|
errno = -ret;
|
||||||
* };
|
return ret;
|
||||||
*
|
}
|
||||||
* struct sample *s = ...;
|
|
||||||
* int x = &s->a; // encoded as "0:0" (a is field #0)
|
/* handle errno-based (e.g., syscall or libc) errors according to libbpf's
|
||||||
* int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1,
|
* strict mode settings
|
||||||
* // b is field #0 inside anon struct, accessing elem #5)
|
|
||||||
* int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array)
|
|
||||||
*
|
|
||||||
* type_id for all relocs in this example will capture BTF type id of
|
|
||||||
* `struct sample`.
|
|
||||||
*
|
|
||||||
* Such relocation is emitted when using __builtin_preserve_access_index()
|
|
||||||
* Clang built-in, passing expression that captures field address, e.g.:
|
|
||||||
*
|
|
||||||
* bpf_probe_read(&dst, sizeof(dst),
|
|
||||||
* __builtin_preserve_access_index(&src->a.b.c));
|
|
||||||
*
|
|
||||||
* In this case Clang will emit offset relocation recording necessary data to
|
|
||||||
* be able to find offset of embedded `a.b.c` field within `src` struct.
|
|
||||||
*
|
|
||||||
* [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
|
|
||||||
*/
|
*/
|
||||||
struct bpf_offset_reloc {
|
static inline int libbpf_err_errno(int ret)
|
||||||
__u32 insn_off;
|
{
|
||||||
__u32 type_id;
|
/* errno is already assumed to be set on error */
|
||||||
__u32 access_str_off;
|
return ret < 0 ? -errno : ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/* handle error for pointer-returning APIs, err is assumed to be < 0 always */
|
||||||
|
static inline void *libbpf_err_ptr(int err)
|
||||||
|
{
|
||||||
|
/* set errno on error, this doesn't break anything */
|
||||||
|
errno = -err;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle pointer-returning APIs' error handling */
|
||||||
|
static inline void *libbpf_ptr(void *ret)
|
||||||
|
{
|
||||||
|
/* set errno on error, this doesn't break anything */
|
||||||
|
if (IS_ERR(ret))
|
||||||
|
errno = -PTR_ERR(ret);
|
||||||
|
|
||||||
|
return IS_ERR(ret) ? NULL : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool str_is_empty(const char *s)
|
||||||
|
{
|
||||||
|
return !s || !s[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_ldimm64_insn(struct bpf_insn *insn)
|
||||||
|
{
|
||||||
|
return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if fd is stdin, stdout, or stderr, dup to a fd greater than 2
|
||||||
|
* Takes ownership of the fd passed in, and closes it if calling
|
||||||
|
* fcntl(fd, F_DUPFD_CLOEXEC, 3).
|
||||||
|
*/
|
||||||
|
static inline int ensure_good_fd(int fd)
|
||||||
|
{
|
||||||
|
int old_fd = fd, saved_errno;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
if (fd < 3) {
|
||||||
|
fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
||||||
|
saved_errno = errno;
|
||||||
|
close(old_fd);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
|
||||||
|
errno = saved_errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following two functions are exposed to bpftool */
|
||||||
|
int bpf_core_add_cands(struct bpf_core_cand *local_cand,
|
||||||
|
size_t local_essent_len,
|
||||||
|
const struct btf *targ_btf,
|
||||||
|
const char *targ_btf_name,
|
||||||
|
int targ_start_id,
|
||||||
|
struct bpf_core_cand_list *cands);
|
||||||
|
void bpf_core_free_cands(struct bpf_core_cand_list *cands);
|
||||||
|
|
||||||
|
struct usdt_manager *usdt_manager_new(struct bpf_object *obj);
|
||||||
|
void usdt_manager_free(struct usdt_manager *man);
|
||||||
|
struct bpf_link * usdt_manager_attach_usdt(struct usdt_manager *man,
|
||||||
|
const struct bpf_program *prog,
|
||||||
|
pid_t pid, const char *path,
|
||||||
|
const char *usdt_provider, const char *usdt_name,
|
||||||
|
__u64 usdt_cookie);
|
||||||
|
|
||||||
|
static inline bool is_pow_of_2(size_t x)
|
||||||
|
{
|
||||||
|
return x && (x & (x - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROG_LOAD_ATTEMPTS 5
|
||||||
|
int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts);
|
||||||
|
|
||||||
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
||||||
|
|||||||
140
src/libbpf_legacy.h
Normal file
140
src/libbpf_legacy.h
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Libbpf legacy APIs (either discouraged or deprecated, as mentioned in [0])
|
||||||
|
*
|
||||||
|
* [0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Facebook
|
||||||
|
*/
|
||||||
|
#ifndef __LIBBPF_LEGACY_BPF_H
|
||||||
|
#define __LIBBPF_LEGACY_BPF_H
|
||||||
|
|
||||||
|
#include <linux/bpf.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "libbpf_common.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* As of libbpf 1.0 libbpf_set_strict_mode() and enum libbpf_struct_mode have
|
||||||
|
* no effect. But they are left in libbpf_legacy.h so that applications that
|
||||||
|
* prepared for libbpf 1.0 before final release by using
|
||||||
|
* libbpf_set_strict_mode() still work with libbpf 1.0+ without any changes.
|
||||||
|
*/
|
||||||
|
enum libbpf_strict_mode {
|
||||||
|
/* Turn on all supported strict features of libbpf to simulate libbpf
|
||||||
|
* v1.0 behavior.
|
||||||
|
* This will be the default behavior in libbpf v1.0.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_ALL = 0xffffffff,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable any libbpf 1.0 behaviors. This is the default before libbpf
|
||||||
|
* v1.0. It won't be supported anymore in v1.0, please update your
|
||||||
|
* code so that it handles LIBBPF_STRICT_ALL mode before libbpf v1.0.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_NONE = 0x00,
|
||||||
|
/*
|
||||||
|
* Return NULL pointers on error, not ERR_PTR(err).
|
||||||
|
* Additionally, libbpf also always sets errno to corresponding Exx
|
||||||
|
* (positive) error code.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_CLEAN_PTRS = 0x01,
|
||||||
|
/*
|
||||||
|
* Return actual error codes from low-level APIs directly, not just -1.
|
||||||
|
* Additionally, libbpf also always sets errno to corresponding Exx
|
||||||
|
* (positive) error code.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_DIRECT_ERRS = 0x02,
|
||||||
|
/*
|
||||||
|
* Enforce strict BPF program section (SEC()) names.
|
||||||
|
* E.g., while prefiously SEC("xdp_whatever") or SEC("perf_event_blah") were
|
||||||
|
* allowed, with LIBBPF_STRICT_SEC_PREFIX this will become
|
||||||
|
* unrecognized by libbpf and would have to be just SEC("xdp") and
|
||||||
|
* SEC("xdp") and SEC("perf_event").
|
||||||
|
*
|
||||||
|
* Note, in this mode the program pin path will be based on the
|
||||||
|
* function name instead of section name.
|
||||||
|
*
|
||||||
|
* Additionally, routines in the .text section are always considered
|
||||||
|
* sub-programs. Legacy behavior allows for a single routine in .text
|
||||||
|
* to be a program.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_SEC_NAME = 0x04,
|
||||||
|
/*
|
||||||
|
* Disable the global 'bpf_objects_list'. Maintaining this list adds
|
||||||
|
* a race condition to bpf_object__open() and bpf_object__close().
|
||||||
|
* Clients can maintain it on their own if it is valuable for them.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_NO_OBJECT_LIST = 0x08,
|
||||||
|
/*
|
||||||
|
* Automatically bump RLIMIT_MEMLOCK using setrlimit() before the
|
||||||
|
* first BPF program or map creation operation. This is done only if
|
||||||
|
* kernel is too old to support memcg-based memory accounting for BPF
|
||||||
|
* subsystem. By default, RLIMIT_MEMLOCK limit is set to RLIM_INFINITY,
|
||||||
|
* but it can be overriden with libbpf_set_memlock_rlim() API.
|
||||||
|
* Note that libbpf_set_memlock_rlim() needs to be called before
|
||||||
|
* the very first bpf_prog_load(), bpf_map_create() or bpf_object__load()
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_AUTO_RLIMIT_MEMLOCK = 0x10,
|
||||||
|
/*
|
||||||
|
* Error out on any SEC("maps") map definition, which are deprecated
|
||||||
|
* in favor of BTF-defined map definitions in SEC(".maps").
|
||||||
|
*/
|
||||||
|
LIBBPF_STRICT_MAP_DEFINITIONS = 0x20,
|
||||||
|
|
||||||
|
__LIBBPF_STRICT_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBBPF_API int libbpf_set_strict_mode(enum libbpf_strict_mode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief **libbpf_get_error()** extracts the error code from the passed
|
||||||
|
* pointer
|
||||||
|
* @param ptr pointer returned from libbpf API function
|
||||||
|
* @return error code; or 0 if no error occured
|
||||||
|
*
|
||||||
|
* Note, as of libbpf 1.0 this function is not necessary and not recommended
|
||||||
|
* to be used. Libbpf doesn't return error code embedded into the pointer
|
||||||
|
* itself. Instead, NULL is returned on error and error code is passed through
|
||||||
|
* thread-local errno variable. **libbpf_get_error()** is just returning -errno
|
||||||
|
* value if it receives NULL, which is correct only if errno hasn't been
|
||||||
|
* modified between libbpf API call and corresponding **libbpf_get_error()**
|
||||||
|
* call. Prefer to check return for NULL and use errno directly.
|
||||||
|
*
|
||||||
|
* This API is left in libbpf 1.0 to allow applications that were 1.0-ready
|
||||||
|
* before final libbpf 1.0 without needing to change them.
|
||||||
|
*/
|
||||||
|
LIBBPF_API long libbpf_get_error(const void *ptr);
|
||||||
|
|
||||||
|
#define DECLARE_LIBBPF_OPTS LIBBPF_OPTS
|
||||||
|
|
||||||
|
/* "Discouraged" APIs which don't follow consistent libbpf naming patterns.
|
||||||
|
* They are normally a trivial aliases or wrappers for proper APIs and are
|
||||||
|
* left to minimize unnecessary disruption for users of libbpf. But they
|
||||||
|
* shouldn't be used going forward.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct bpf_program;
|
||||||
|
struct bpf_map;
|
||||||
|
struct btf;
|
||||||
|
struct btf_ext;
|
||||||
|
|
||||||
|
LIBBPF_API struct btf *libbpf_find_kernel_btf(void);
|
||||||
|
|
||||||
|
LIBBPF_API enum bpf_prog_type bpf_program__get_type(const struct bpf_program *prog);
|
||||||
|
LIBBPF_API enum bpf_attach_type bpf_program__get_expected_attach_type(const struct bpf_program *prog);
|
||||||
|
LIBBPF_API const char *bpf_map__get_pin_path(const struct bpf_map *map);
|
||||||
|
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
||||||
|
LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __LIBBPF_LEGACY_BPF_H */
|
||||||
@@ -17,66 +17,63 @@
|
|||||||
#include "libbpf.h"
|
#include "libbpf.h"
|
||||||
#include "libbpf_internal.h"
|
#include "libbpf_internal.h"
|
||||||
|
|
||||||
static bool grep(const char *buffer, const char *pattern)
|
static int probe_prog_load(enum bpf_prog_type prog_type,
|
||||||
|
const struct bpf_insn *insns, size_t insns_cnt,
|
||||||
|
char *log_buf, size_t log_buf_sz)
|
||||||
{
|
{
|
||||||
return !!strstr(buffer, pattern);
|
LIBBPF_OPTS(bpf_prog_load_opts, opts,
|
||||||
}
|
.log_buf = log_buf,
|
||||||
|
.log_size = log_buf_sz,
|
||||||
static int get_vendor_id(int ifindex)
|
.log_level = log_buf ? 1 : 0,
|
||||||
{
|
);
|
||||||
char ifname[IF_NAMESIZE], path[64], buf[8];
|
int fd, err, exp_err = 0;
|
||||||
ssize_t len;
|
const char *exp_msg = NULL;
|
||||||
int fd;
|
char buf[4096];
|
||||||
|
|
||||||
if (!if_indextoname(ifindex, ifname))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "/sys/class/net/%s/device/vendor", ifname);
|
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
len = read(fd, buf, sizeof(buf));
|
|
||||||
close(fd);
|
|
||||||
if (len < 0)
|
|
||||||
return -1;
|
|
||||||
if (len >= (ssize_t)sizeof(buf))
|
|
||||||
return -1;
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
return strtol(buf, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_kernel_version(void)
|
|
||||||
{
|
|
||||||
int version, subversion, patchlevel;
|
|
||||||
struct utsname utsn;
|
|
||||||
|
|
||||||
/* Return 0 on failure, and attempt to probe with empty kversion */
|
|
||||||
if (uname(&utsn))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sscanf(utsn.release, "%d.%d.%d",
|
|
||||||
&version, &subversion, &patchlevel) != 3)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (version << 16) + (subversion << 8) + patchlevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns,
|
|
||||||
size_t insns_cnt, char *buf, size_t buf_len, __u32 ifindex)
|
|
||||||
{
|
|
||||||
struct bpf_load_program_attr xattr = {};
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
switch (prog_type) {
|
switch (prog_type) {
|
||||||
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
||||||
xattr.expected_attach_type = BPF_CGROUP_INET4_CONNECT;
|
opts.expected_attach_type = BPF_CGROUP_INET4_CONNECT;
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
|
||||||
|
opts.expected_attach_type = BPF_CGROUP_GETSOCKOPT;
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_SK_LOOKUP:
|
||||||
|
opts.expected_attach_type = BPF_SK_LOOKUP;
|
||||||
break;
|
break;
|
||||||
case BPF_PROG_TYPE_KPROBE:
|
case BPF_PROG_TYPE_KPROBE:
|
||||||
xattr.kern_version = get_kernel_version();
|
opts.kern_version = get_kernel_version();
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_LIRC_MODE2:
|
||||||
|
opts.expected_attach_type = BPF_LIRC_MODE2;
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_TRACING:
|
||||||
|
case BPF_PROG_TYPE_LSM:
|
||||||
|
opts.log_buf = buf;
|
||||||
|
opts.log_size = sizeof(buf);
|
||||||
|
opts.log_level = 1;
|
||||||
|
if (prog_type == BPF_PROG_TYPE_TRACING)
|
||||||
|
opts.expected_attach_type = BPF_TRACE_FENTRY;
|
||||||
|
else
|
||||||
|
opts.expected_attach_type = BPF_MODIFY_RETURN;
|
||||||
|
opts.attach_btf_id = 1;
|
||||||
|
|
||||||
|
exp_err = -EINVAL;
|
||||||
|
exp_msg = "attach_btf_id 1 is not a function";
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_EXT:
|
||||||
|
opts.log_buf = buf;
|
||||||
|
opts.log_size = sizeof(buf);
|
||||||
|
opts.log_level = 1;
|
||||||
|
opts.attach_btf_id = 1;
|
||||||
|
|
||||||
|
exp_err = -EINVAL;
|
||||||
|
exp_msg = "Cannot replace kernel functions";
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_SYSCALL:
|
||||||
|
opts.prog_flags = BPF_F_SLEEPABLE;
|
||||||
|
break;
|
||||||
|
case BPF_PROG_TYPE_STRUCT_OPS:
|
||||||
|
exp_err = -524; /* -ENOTSUPP */
|
||||||
break;
|
break;
|
||||||
case BPF_PROG_TYPE_UNSPEC:
|
case BPF_PROG_TYPE_UNSPEC:
|
||||||
case BPF_PROG_TYPE_SOCKET_FILTER:
|
case BPF_PROG_TYPE_SOCKET_FILTER:
|
||||||
@@ -97,41 +94,42 @@ probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns,
|
|||||||
case BPF_PROG_TYPE_RAW_TRACEPOINT:
|
case BPF_PROG_TYPE_RAW_TRACEPOINT:
|
||||||
case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
|
case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
|
||||||
case BPF_PROG_TYPE_LWT_SEG6LOCAL:
|
case BPF_PROG_TYPE_LWT_SEG6LOCAL:
|
||||||
case BPF_PROG_TYPE_LIRC_MODE2:
|
|
||||||
case BPF_PROG_TYPE_SK_REUSEPORT:
|
case BPF_PROG_TYPE_SK_REUSEPORT:
|
||||||
case BPF_PROG_TYPE_FLOW_DISSECTOR:
|
case BPF_PROG_TYPE_FLOW_DISSECTOR:
|
||||||
case BPF_PROG_TYPE_CGROUP_SYSCTL:
|
case BPF_PROG_TYPE_CGROUP_SYSCTL:
|
||||||
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
xattr.prog_type = prog_type;
|
fd = bpf_prog_load(prog_type, NULL, "GPL", insns, insns_cnt, &opts);
|
||||||
xattr.insns = insns;
|
err = -errno;
|
||||||
xattr.insns_cnt = insns_cnt;
|
|
||||||
xattr.license = "GPL";
|
|
||||||
xattr.prog_ifindex = ifindex;
|
|
||||||
|
|
||||||
fd = bpf_load_program_xattr(&xattr, buf, buf_len);
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
if (exp_err) {
|
||||||
|
if (fd >= 0 || err != exp_err)
|
||||||
|
return 0;
|
||||||
|
if (exp_msg && !strstr(buf, exp_msg))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return fd >= 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bpf_probe_prog_type(enum bpf_prog_type prog_type, __u32 ifindex)
|
int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts)
|
||||||
{
|
{
|
||||||
struct bpf_insn insns[2] = {
|
struct bpf_insn insns[] = {
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN()
|
BPF_EXIT_INSN()
|
||||||
};
|
};
|
||||||
|
const size_t insn_cnt = ARRAY_SIZE(insns);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (ifindex && prog_type == BPF_PROG_TYPE_SCHED_CLS)
|
if (opts)
|
||||||
/* nfp returns -EINVAL on exit(0) with TC offload */
|
return libbpf_err(-EINVAL);
|
||||||
insns[0].imm = 2;
|
|
||||||
|
|
||||||
errno = 0;
|
ret = probe_prog_load(prog_type, insns, insn_cnt, NULL, 0);
|
||||||
probe_load(prog_type, insns, ARRAY_SIZE(insns), NULL, 0, ifindex);
|
return libbpf_err(ret);
|
||||||
|
|
||||||
return errno != EINVAL && errno != EOPNOTSUPP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||||
@@ -157,13 +155,13 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
|||||||
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
|
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
|
||||||
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
|
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
|
||||||
|
|
||||||
btf_fd = bpf_load_btf(raw_btf, btf_len, NULL, 0, false);
|
btf_fd = bpf_btf_load(raw_btf, btf_len, NULL);
|
||||||
|
|
||||||
free(raw_btf);
|
free(raw_btf);
|
||||||
return btf_fd;
|
return btf_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_sk_storage_btf(void)
|
static int load_local_storage_btf(void)
|
||||||
{
|
{
|
||||||
const char strs[] = "\0bpf_spin_lock\0val\0cnt\0l";
|
const char strs[] = "\0bpf_spin_lock\0val\0cnt\0l";
|
||||||
/* struct bpf_spin_lock {
|
/* struct bpf_spin_lock {
|
||||||
@@ -190,17 +188,16 @@ static int load_sk_storage_btf(void)
|
|||||||
strs, sizeof(strs));
|
strs, sizeof(strs));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
static int probe_map_create(enum bpf_map_type map_type)
|
||||||
{
|
{
|
||||||
int key_size, value_size, max_entries, map_flags;
|
LIBBPF_OPTS(bpf_map_create_opts, opts);
|
||||||
|
int key_size, value_size, max_entries;
|
||||||
__u32 btf_key_type_id = 0, btf_value_type_id = 0;
|
__u32 btf_key_type_id = 0, btf_value_type_id = 0;
|
||||||
struct bpf_create_map_attr attr = {};
|
int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err = 0;
|
||||||
int fd = -1, btf_fd = -1, fd_inner;
|
|
||||||
|
|
||||||
key_size = sizeof(__u32);
|
key_size = sizeof(__u32);
|
||||||
value_size = sizeof(__u32);
|
value_size = sizeof(__u32);
|
||||||
max_entries = 1;
|
max_entries = 1;
|
||||||
map_flags = 0;
|
|
||||||
|
|
||||||
switch (map_type) {
|
switch (map_type) {
|
||||||
case BPF_MAP_TYPE_STACK_TRACE:
|
case BPF_MAP_TYPE_STACK_TRACE:
|
||||||
@@ -209,7 +206,7 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
|||||||
case BPF_MAP_TYPE_LPM_TRIE:
|
case BPF_MAP_TYPE_LPM_TRIE:
|
||||||
key_size = sizeof(__u64);
|
key_size = sizeof(__u64);
|
||||||
value_size = sizeof(__u64);
|
value_size = sizeof(__u64);
|
||||||
map_flags = BPF_F_NO_PREALLOC;
|
opts.map_flags = BPF_F_NO_PREALLOC;
|
||||||
break;
|
break;
|
||||||
case BPF_MAP_TYPE_CGROUP_STORAGE:
|
case BPF_MAP_TYPE_CGROUP_STORAGE:
|
||||||
case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE:
|
case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE:
|
||||||
@@ -222,16 +219,31 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
|||||||
key_size = 0;
|
key_size = 0;
|
||||||
break;
|
break;
|
||||||
case BPF_MAP_TYPE_SK_STORAGE:
|
case BPF_MAP_TYPE_SK_STORAGE:
|
||||||
|
case BPF_MAP_TYPE_INODE_STORAGE:
|
||||||
|
case BPF_MAP_TYPE_TASK_STORAGE:
|
||||||
btf_key_type_id = 1;
|
btf_key_type_id = 1;
|
||||||
btf_value_type_id = 3;
|
btf_value_type_id = 3;
|
||||||
value_size = 8;
|
value_size = 8;
|
||||||
max_entries = 0;
|
max_entries = 0;
|
||||||
map_flags = BPF_F_NO_PREALLOC;
|
opts.map_flags = BPF_F_NO_PREALLOC;
|
||||||
btf_fd = load_sk_storage_btf();
|
btf_fd = load_local_storage_btf();
|
||||||
if (btf_fd < 0)
|
if (btf_fd < 0)
|
||||||
return false;
|
return btf_fd;
|
||||||
|
break;
|
||||||
|
case BPF_MAP_TYPE_RINGBUF:
|
||||||
|
key_size = 0;
|
||||||
|
value_size = 0;
|
||||||
|
max_entries = 4096;
|
||||||
|
break;
|
||||||
|
case BPF_MAP_TYPE_STRUCT_OPS:
|
||||||
|
/* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */
|
||||||
|
opts.btf_vmlinux_value_type_id = 1;
|
||||||
|
exp_err = -524; /* -ENOTSUPP */
|
||||||
|
break;
|
||||||
|
case BPF_MAP_TYPE_BLOOM_FILTER:
|
||||||
|
key_size = 0;
|
||||||
|
max_entries = 1;
|
||||||
break;
|
break;
|
||||||
case BPF_MAP_TYPE_UNSPEC:
|
|
||||||
case BPF_MAP_TYPE_HASH:
|
case BPF_MAP_TYPE_HASH:
|
||||||
case BPF_MAP_TYPE_ARRAY:
|
case BPF_MAP_TYPE_ARRAY:
|
||||||
case BPF_MAP_TYPE_PROG_ARRAY:
|
case BPF_MAP_TYPE_PROG_ARRAY:
|
||||||
@@ -250,73 +262,101 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
|||||||
case BPF_MAP_TYPE_XSKMAP:
|
case BPF_MAP_TYPE_XSKMAP:
|
||||||
case BPF_MAP_TYPE_SOCKHASH:
|
case BPF_MAP_TYPE_SOCKHASH:
|
||||||
case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:
|
case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
|
case BPF_MAP_TYPE_UNSPEC:
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
|
if (map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
|
||||||
map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
|
map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
|
||||||
/* TODO: probe for device, once libbpf has a function to create
|
fd_inner = bpf_map_create(BPF_MAP_TYPE_HASH, NULL,
|
||||||
* map-in-map for offload
|
sizeof(__u32), sizeof(__u32), 1, NULL);
|
||||||
*/
|
|
||||||
if (ifindex)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
fd_inner = bpf_create_map(BPF_MAP_TYPE_HASH,
|
|
||||||
sizeof(__u32), sizeof(__u32), 1, 0);
|
|
||||||
if (fd_inner < 0)
|
if (fd_inner < 0)
|
||||||
return false;
|
goto cleanup;
|
||||||
fd = bpf_create_map_in_map(map_type, NULL, sizeof(__u32),
|
|
||||||
fd_inner, 1, 0);
|
|
||||||
close(fd_inner);
|
|
||||||
} else {
|
|
||||||
/* Note: No other restriction on map type probes for offload */
|
|
||||||
attr.map_type = map_type;
|
|
||||||
attr.key_size = key_size;
|
|
||||||
attr.value_size = value_size;
|
|
||||||
attr.max_entries = max_entries;
|
|
||||||
attr.map_flags = map_flags;
|
|
||||||
attr.map_ifindex = ifindex;
|
|
||||||
if (btf_fd >= 0) {
|
|
||||||
attr.btf_fd = btf_fd;
|
|
||||||
attr.btf_key_type_id = btf_key_type_id;
|
|
||||||
attr.btf_value_type_id = btf_value_type_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = bpf_create_map_xattr(&attr);
|
opts.inner_map_fd = fd_inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (btf_fd >= 0) {
|
||||||
|
opts.btf_fd = btf_fd;
|
||||||
|
opts.btf_key_type_id = btf_key_type_id;
|
||||||
|
opts.btf_value_type_id = btf_value_type_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = bpf_map_create(map_type, NULL, key_size, value_size, max_entries, &opts);
|
||||||
|
err = -errno;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
if (fd_inner >= 0)
|
||||||
|
close(fd_inner);
|
||||||
if (btf_fd >= 0)
|
if (btf_fd >= 0)
|
||||||
close(btf_fd);
|
close(btf_fd);
|
||||||
|
|
||||||
return fd >= 0;
|
if (exp_err)
|
||||||
|
return fd < 0 && err == exp_err ? 1 : 0;
|
||||||
|
else
|
||||||
|
return fd >= 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bpf_probe_helper(enum bpf_func_id id, enum bpf_prog_type prog_type,
|
int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void *opts)
|
||||||
__u32 ifindex)
|
|
||||||
{
|
{
|
||||||
struct bpf_insn insns[2] = {
|
int ret;
|
||||||
BPF_EMIT_CALL(id),
|
|
||||||
BPF_EXIT_INSN()
|
if (opts)
|
||||||
|
return libbpf_err(-EINVAL);
|
||||||
|
|
||||||
|
ret = probe_map_create(map_type);
|
||||||
|
return libbpf_err(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
|
||||||
|
const void *opts)
|
||||||
|
{
|
||||||
|
struct bpf_insn insns[] = {
|
||||||
|
BPF_EMIT_CALL((__u32)helper_id),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
};
|
};
|
||||||
char buf[4096] = {};
|
const size_t insn_cnt = ARRAY_SIZE(insns);
|
||||||
bool res;
|
char buf[4096];
|
||||||
|
int ret;
|
||||||
|
|
||||||
probe_load(prog_type, insns, ARRAY_SIZE(insns), buf, sizeof(buf),
|
if (opts)
|
||||||
ifindex);
|
return libbpf_err(-EINVAL);
|
||||||
res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ");
|
|
||||||
|
|
||||||
if (ifindex) {
|
/* we can't successfully load all prog types to check for BPF helper
|
||||||
switch (get_vendor_id(ifindex)) {
|
* support, so bail out with -EOPNOTSUPP error
|
||||||
case 0x19ee: /* Netronome specific */
|
*/
|
||||||
res = res && !grep(buf, "not supported by FW") &&
|
switch (prog_type) {
|
||||||
!grep(buf, "unsupported function id");
|
case BPF_PROG_TYPE_TRACING:
|
||||||
break;
|
case BPF_PROG_TYPE_EXT:
|
||||||
default:
|
case BPF_PROG_TYPE_LSM:
|
||||||
break;
|
case BPF_PROG_TYPE_STRUCT_OPS:
|
||||||
}
|
return -EOPNOTSUPP;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
buf[0] = '\0';
|
||||||
|
ret = probe_prog_load(prog_type, insns, insn_cnt, buf, sizeof(buf));
|
||||||
|
if (ret < 0)
|
||||||
|
return libbpf_err(ret);
|
||||||
|
|
||||||
|
/* If BPF verifier doesn't recognize BPF helper ID (enum bpf_func_id)
|
||||||
|
* at all, it will emit something like "invalid func unknown#181".
|
||||||
|
* If BPF verifier recognizes BPF helper but it's not supported for
|
||||||
|
* given BPF program type, it will emit "unknown func bpf_sys_bpf#166".
|
||||||
|
* In both cases, provided combination of BPF program type and BPF
|
||||||
|
* helper is not supported by the kernel.
|
||||||
|
* In all other cases, probe_prog_load() above will either succeed (e.g.,
|
||||||
|
* because BPF helper happens to accept no input arguments or it
|
||||||
|
* accepts one input argument and initial PTR_TO_CTX is fine for
|
||||||
|
* that), or we'll get some more specific BPF verifier error about
|
||||||
|
* some unsatisfied conditions.
|
||||||
|
*/
|
||||||
|
if (ret == 0 && (strstr(buf, "invalid func ") || strstr(buf, "unknown func ")))
|
||||||
|
return 0;
|
||||||
|
return 1; /* assume supported */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
|
||||||
/* Copyright (c) 2019 Facebook */
|
|
||||||
|
|
||||||
#ifndef __LIBBPF_LIBBPF_UTIL_H
|
|
||||||
#define __LIBBPF_LIBBPF_UTIL_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Use these barrier functions instead of smp_[rw]mb() when they are
|
|
||||||
* used in a libbpf header file. That way they can be built into the
|
|
||||||
* application that uses libbpf.
|
|
||||||
*/
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
# define libbpf_smp_rmb() asm volatile("" : : : "memory")
|
|
||||||
# define libbpf_smp_wmb() asm volatile("" : : : "memory")
|
|
||||||
# define libbpf_smp_mb() \
|
|
||||||
asm volatile("lock; addl $0,-4(%%rsp)" : : : "memory", "cc")
|
|
||||||
/* Hinders stores to be observed before older loads. */
|
|
||||||
# define libbpf_smp_rwmb() asm volatile("" : : : "memory")
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
# define libbpf_smp_rmb() asm volatile("dmb ishld" : : : "memory")
|
|
||||||
# define libbpf_smp_wmb() asm volatile("dmb ishst" : : : "memory")
|
|
||||||
# define libbpf_smp_mb() asm volatile("dmb ish" : : : "memory")
|
|
||||||
# define libbpf_smp_rwmb() libbpf_smp_mb()
|
|
||||||
#elif defined(__arm__)
|
|
||||||
/* These are only valid for armv7 and above */
|
|
||||||
# define libbpf_smp_rmb() asm volatile("dmb ish" : : : "memory")
|
|
||||||
# define libbpf_smp_wmb() asm volatile("dmb ishst" : : : "memory")
|
|
||||||
# define libbpf_smp_mb() asm volatile("dmb ish" : : : "memory")
|
|
||||||
# define libbpf_smp_rwmb() libbpf_smp_mb()
|
|
||||||
#else
|
|
||||||
/* Architecture missing native barrier functions. */
|
|
||||||
# define libbpf_smp_rmb() __sync_synchronize()
|
|
||||||
# define libbpf_smp_wmb() __sync_synchronize()
|
|
||||||
# define libbpf_smp_mb() __sync_synchronize()
|
|
||||||
# define libbpf_smp_rwmb() __sync_synchronize()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
9
src/libbpf_version.h
Normal file
9
src/libbpf_version.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||||
|
/* Copyright (C) 2021 Facebook */
|
||||||
|
#ifndef __LIBBPF_VERSION_H
|
||||||
|
#define __LIBBPF_VERSION_H
|
||||||
|
|
||||||
|
#define LIBBPF_MAJOR_VERSION 1
|
||||||
|
#define LIBBPF_MINOR_VERSION 0
|
||||||
|
|
||||||
|
#endif /* __LIBBPF_VERSION_H */
|
||||||
2900
src/linker.c
Normal file
2900
src/linker.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user