mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-24 10:19:07 +08:00
Compare commits
1595 Commits
v0.0.4
...
v1.0.0_net
| 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 | ||
|
|
1a26b51b1c | ||
|
|
2cc0829775 | ||
|
|
92cb475558 | ||
|
|
8b2782a1f2 | ||
|
|
886e8149a0 | ||
|
|
d275397111 | ||
|
|
ede18f80d8 | ||
|
|
07cd489681 | ||
|
|
d2f307c7f6 | ||
|
|
990cef2a0c | ||
|
|
4c2c521513 | ||
|
|
b1e911e9ba | ||
|
|
ae673dc91f | ||
|
|
5a256d12bf | ||
|
|
ae8edc7624 | ||
|
|
8f8b4a14fa | ||
|
|
476e158b07 | ||
|
|
13e1ee420e | ||
|
|
3e2bab6d2c | ||
|
|
9084f4cd4d | ||
|
|
66d20edaf0 | ||
|
|
d8d6772ab8 | ||
|
|
4397d09cd8 | ||
|
|
5771dacd3d | ||
|
|
d34efeeef1 | ||
|
|
db63a5aa5d | ||
|
|
d60f568961 | ||
|
|
e78a36f4b0 | ||
|
|
c8a7eb06bd | ||
|
|
b48c14807b | ||
|
|
a3b4055ec7 | ||
|
|
30603852f4 | ||
|
|
1a28fa5dac | ||
|
|
def5576b37 | ||
|
|
3e45a16621 | ||
|
|
2c0e53cb08 | ||
|
|
6227c6f8dd | ||
|
|
00ad180d07 | ||
|
|
715a58d593 | ||
|
|
11052fc1be | ||
|
|
97ecda3b25 | ||
|
|
342bcfa319 | ||
|
|
c020432531 | ||
|
|
99ce275b52 | ||
|
|
c0a5f7ee11 | ||
|
|
0da9ba439f | ||
|
|
c4735d9e05 | ||
|
|
563f1d3fff | ||
|
|
c5d4295fc5 | ||
|
|
b606dc725e | ||
|
|
f615047aa0 | ||
|
|
84a508a51f | ||
|
|
c59016e100 | ||
|
|
509ef92905 | ||
|
|
2c9394f2a3 | ||
|
|
0f4d83f3ab | ||
|
|
6a7b28b6a1 | ||
|
|
d76d264ac0 | ||
|
|
63a3bdf23a | ||
|
|
12fa15e89a | ||
|
|
b987dcfecb | ||
|
|
9c1ab4d070 |
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
BPF-CHECKPOINT-COMMIT
Normal file
1
BPF-CHECKPOINT-COMMIT
Normal file
@@ -0,0 +1 @@
|
|||||||
|
14b20b784f59bdd95f6f1cfb112c9818bcec4d84
|
||||||
@@ -1 +1 @@
|
|||||||
66b5f1c439843bcbab01cc7f3854ae2742f3d1e3
|
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!
|
||||||
185
README.md
185
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
|
||||||
@@ -48,23 +81,105 @@ $ 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
|
||||||
```
|
```
|
||||||
|
|
||||||
To integrate libbpf into a project which uses Meson building system define
|
BPF CO-RE (Compile Once – Run Everywhere)
|
||||||
`[wrap-git]` file in `subprojects` folder.
|
=========================================
|
||||||
To add libbpf dependency to the parent parent project, e.g. for
|
|
||||||
libbpf_static_dep:
|
|
||||||
```
|
|
||||||
libbpf_obj = subproject('libbpf', required : true)
|
|
||||||
libbpf_static_dep = libbpf_proj.get_variable('libbpf_static_dep')
|
|
||||||
```
|
|
||||||
|
|
||||||
To validate changes to meson.build
|
Libbpf supports building BPF CO-RE-enabled applications, which, in contrast to
|
||||||
```bash
|
[BCC](https://github.com/iovisor/bcc/), do not require Clang/LLVM runtime
|
||||||
$ python3 meson.py build
|
being deployed to target servers and doesn't rely on kernel-devel headers
|
||||||
$ ninja -C build/
|
being available.
|
||||||
```
|
|
||||||
|
|
||||||
To install headers, libs and pkgconfig
|
It does rely on kernel to be built with [BTF type
|
||||||
```bash
|
information](https://www.kernel.org/doc/html/latest/bpf/btf.html), though.
|
||||||
$ cd build
|
Some major Linux distributions come with kernel BTF already built in:
|
||||||
$ ninja install
|
- 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
|
||||||
90
ci/managers/debian.sh
Executable file
90
ci/managers/debian.sh
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
|
||||||
|
DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}"
|
||||||
|
CONT_NAME="${CONT_NAME:-libbpf-debian-$DEBIAN_RELEASE}"
|
||||||
|
ENV_VARS="${ENV_VARS:-}"
|
||||||
|
DOCKER_RUN="${DOCKER_RUN:-docker run}"
|
||||||
|
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||||
|
ADDITIONAL_DEPS=(clang pkg-config gcc-10)
|
||||||
|
EXTRA_CFLAGS=""
|
||||||
|
EXTRA_LDFLAGS=""
|
||||||
|
|
||||||
|
function info() {
|
||||||
|
echo -e "\033[33;1m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
echo -e "\033[31;1m$1\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function docker_exec() {
|
||||||
|
docker exec $ENV_VARS $CONT_NAME "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
source "$(dirname $0)/travis_wait.bash"
|
||||||
|
|
||||||
|
for phase in "${PHASES[@]}"; do
|
||||||
|
case $phase in
|
||||||
|
SETUP)
|
||||||
|
info "Setup phase"
|
||||||
|
info "Using Debian $DEBIAN_RELEASE"
|
||||||
|
|
||||||
|
docker --version
|
||||||
|
|
||||||
|
docker pull debian:$DEBIAN_RELEASE
|
||||||
|
info "Starting container $CONT_NAME"
|
||||||
|
$DOCKER_RUN -v $REPO_ROOT:/build:rw \
|
||||||
|
-w /build --privileged=true --name $CONT_NAME \
|
||||||
|
-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 apt-get -y update
|
||||||
|
docker_exec apt-get -y install aptitude
|
||||||
|
docker_exec aptitude -y build-dep libelf-dev
|
||||||
|
docker_exec aptitude -y install libelf-dev
|
||||||
|
docker_exec aptitude -y install "${ADDITIONAL_DEPS[@]}"
|
||||||
|
echo -e "::endgroup::"
|
||||||
|
;;
|
||||||
|
RUN|RUN_CLANG|RUN_GCC10|RUN_ASAN|RUN_CLANG_ASAN|RUN_GCC10_ASAN)
|
||||||
|
CC="cc"
|
||||||
|
if [[ "$phase" = *"CLANG"* ]]; then
|
||||||
|
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||||
|
CC="clang"
|
||||||
|
elif [[ "$phase" = *"GCC10"* ]]; then
|
||||||
|
ENV_VARS="-e CC=gcc-10 -e CXX=g++-10"
|
||||||
|
CC="gcc-10"
|
||||||
|
else
|
||||||
|
EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-stringop-truncation"
|
||||||
|
fi
|
||||||
|
if [[ "$phase" = *"ASAN"* ]]; then
|
||||||
|
EXTRA_CFLAGS="${EXTRA_CFLAGS} -fsanitize=address,undefined"
|
||||||
|
EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -fsanitize=address,undefined"
|
||||||
|
fi
|
||||||
|
docker_exec mkdir build install
|
||||||
|
docker_exec ${CC} --version
|
||||||
|
info "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:"
|
||||||
|
docker_exec ldd build/libbpf.so
|
||||||
|
if ! docker_exec ldd build/libbpf.so | grep -q libelf; then
|
||||||
|
error "No reference to libelf.so in libbpf.so!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
info "install"
|
||||||
|
docker_exec make -j$((4*$(nproc))) -C src OBJDIR=../build DESTDIR=../install install
|
||||||
|
info "link binary"
|
||||||
|
docker_exec bash -c "EXTRA_CFLAGS=\"${EXTRA_CFLAGS}\" EXTRA_LDFLAGS=\"${EXTRA_LDFLAGS}\" ./ci/managers/test_compile.sh"
|
||||||
|
;;
|
||||||
|
CLEANUP)
|
||||||
|
info "Cleanup phase"
|
||||||
|
docker stop $CONT_NAME
|
||||||
|
docker rm -f $CONT_NAME
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo >&2 "Unknown phase '$phase'"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
done
|
||||||
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, \
|
||||||
@@ -96,7 +112,7 @@
|
|||||||
MAP_FD, 0)
|
MAP_FD, 0)
|
||||||
|
|
||||||
#define BPF_LD_MAP_VALUE(DST, MAP_FD, VALUE_OFF) \
|
#define BPF_LD_MAP_VALUE(DST, MAP_FD, VALUE_OFF) \
|
||||||
BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_FD, 0, 0, \
|
BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_VALUE, 0, 0, \
|
||||||
MAP_FD, VALUE_OFF)
|
MAP_FD, VALUE_OFF)
|
||||||
|
|
||||||
#define BPF_JMP_IMM(OP, DST, IMM, OFF) \
|
#define BPF_JMP_IMM(OP, DST, IMM, OFF) \
|
||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -695,6 +922,7 @@ enum {
|
|||||||
IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
|
IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
|
||||||
IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
|
IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
|
||||||
IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
|
IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
|
||||||
|
IFLA_VF_BROADCAST, /* VF broadcast */
|
||||||
__IFLA_VF_MAX,
|
__IFLA_VF_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -705,6 +933,10 @@ struct ifla_vf_mac {
|
|||||||
__u8 mac[32]; /* MAX_ADDR_LEN */
|
__u8 mac[32]; /* MAX_ADDR_LEN */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ifla_vf_broadcast {
|
||||||
|
__u8 broadcast[32];
|
||||||
|
};
|
||||||
|
|
||||||
struct ifla_vf_vlan {
|
struct ifla_vf_vlan {
|
||||||
__u32 vf;
|
__u32 vf;
|
||||||
__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
|
__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
|
||||||
@@ -876,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,
|
||||||
@@ -886,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,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -945,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 {
|
||||||
@@ -969,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,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1008,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,
|
||||||
@@ -1023,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 */
|
||||||
|
|||||||
@@ -16,6 +16,18 @@
|
|||||||
#define XDP_SHARED_UMEM (1 << 0)
|
#define XDP_SHARED_UMEM (1 << 0)
|
||||||
#define XDP_COPY (1 << 1) /* Force copy-mode */
|
#define XDP_COPY (1 << 1) /* Force copy-mode */
|
||||||
#define XDP_ZEROCOPY (1 << 2) /* Force zero-copy mode */
|
#define XDP_ZEROCOPY (1 << 2) /* Force zero-copy mode */
|
||||||
|
/* If this option is set, the driver might go sleep and in that case
|
||||||
|
* the XDP_RING_NEED_WAKEUP flag in the fill and/or Tx rings will be
|
||||||
|
* set. If it is set, the application need to explicitly wake up the
|
||||||
|
* driver with a poll() (Rx and Tx) or sendto() (Tx only). If you are
|
||||||
|
* running the driver and the application on the same core, you should
|
||||||
|
* use this option so that the kernel will yield to the user space
|
||||||
|
* application.
|
||||||
|
*/
|
||||||
|
#define XDP_USE_NEED_WAKEUP (1 << 3)
|
||||||
|
|
||||||
|
/* Flags for xsk_umem_config flags */
|
||||||
|
#define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0)
|
||||||
|
|
||||||
struct sockaddr_xdp {
|
struct sockaddr_xdp {
|
||||||
__u16 sxdp_family;
|
__u16 sxdp_family;
|
||||||
@@ -25,10 +37,14 @@ struct sockaddr_xdp {
|
|||||||
__u32 sxdp_shared_umem_fd;
|
__u32 sxdp_shared_umem_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* XDP_RING flags */
|
||||||
|
#define XDP_RING_NEED_WAKEUP (1 << 0)
|
||||||
|
|
||||||
struct xdp_ring_offset {
|
struct xdp_ring_offset {
|
||||||
__u64 producer;
|
__u64 producer;
|
||||||
__u64 consumer;
|
__u64 consumer;
|
||||||
__u64 desc;
|
__u64 desc;
|
||||||
|
__u64 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xdp_mmap_offsets {
|
struct xdp_mmap_offsets {
|
||||||
@@ -53,12 +69,16 @@ struct xdp_umem_reg {
|
|||||||
__u64 len; /* Length of packet data area */
|
__u64 len; /* Length of packet data area */
|
||||||
__u32 chunk_size;
|
__u32 chunk_size;
|
||||||
__u32 headroom;
|
__u32 headroom;
|
||||||
|
__u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
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 {
|
||||||
@@ -74,6 +94,11 @@ struct xdp_options {
|
|||||||
#define XDP_UMEM_PGOFF_FILL_RING 0x100000000ULL
|
#define XDP_UMEM_PGOFF_FILL_RING 0x100000000ULL
|
||||||
#define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000ULL
|
#define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000ULL
|
||||||
|
|
||||||
|
/* Masks for unaligned chunks mode */
|
||||||
|
#define XSK_UNALIGNED_BUF_OFFSET_SHIFT 48
|
||||||
|
#define XSK_UNALIGNED_BUF_ADDR_MASK \
|
||||||
|
((1ULL << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1)
|
||||||
|
|
||||||
/* Rx/Tx descriptor */
|
/* Rx/Tx descriptor */
|
||||||
struct xdp_desc {
|
struct xdp_desc {
|
||||||
__u64 addr;
|
__u64 addr;
|
||||||
|
|||||||
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
95
meson.build
95
meson.build
@@ -1,95 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
|
|
||||||
project('libbpf', 'c',
|
|
||||||
version : '0.0.3',
|
|
||||||
license : 'LGPL-2.1 OR BSD-2-Clause',
|
|
||||||
default_options : [
|
|
||||||
'prefix=/usr',
|
|
||||||
],
|
|
||||||
meson_version : '>= 0.46',
|
|
||||||
)
|
|
||||||
|
|
||||||
patchlevel = meson.project_version().split('.')[1]
|
|
||||||
|
|
||||||
libbpf_source_dir = './'
|
|
||||||
|
|
||||||
libbpf_sources = files(run_command('find',
|
|
||||||
[
|
|
||||||
'@0@/src'.format(libbpf_source_dir),
|
|
||||||
'-type',
|
|
||||||
'f',
|
|
||||||
'-name',
|
|
||||||
'*.[h|c]']).stdout().split())
|
|
||||||
|
|
||||||
libbpf_headers = files(
|
|
||||||
join_paths(libbpf_source_dir, 'src/bpf.h'),
|
|
||||||
join_paths(libbpf_source_dir, 'src/btf.h'),
|
|
||||||
join_paths(libbpf_source_dir, 'src/libbpf.h'))
|
|
||||||
|
|
||||||
feature_rellocarray = run_command(join_paths(libbpf_source_dir, 'scripts/check-reallocarray.sh'))
|
|
||||||
|
|
||||||
libbpf_c_args = ['-g',
|
|
||||||
'-O2',
|
|
||||||
'-Werror',
|
|
||||||
'-Wall',
|
|
||||||
]
|
|
||||||
|
|
||||||
if feature_rellocarray.stdout().strip() != ''
|
|
||||||
libbpf_c_args += '-DCOMPAT_NEED_REALLOCARRAY'
|
|
||||||
endif
|
|
||||||
|
|
||||||
# bpf_includes are required to include bpf.h, btf.h, libbpf.h
|
|
||||||
bpf_includes = include_directories(
|
|
||||||
join_paths(libbpf_source_dir, 'src'))
|
|
||||||
|
|
||||||
libbpf_includes = include_directories(
|
|
||||||
join_paths(libbpf_source_dir, 'include'),
|
|
||||||
join_paths(libbpf_source_dir, 'include/uapi'))
|
|
||||||
|
|
||||||
libelf = dependency('libelf')
|
|
||||||
libelf = dependency('libelf', required: false)
|
|
||||||
if not libelf.found()
|
|
||||||
libelf = cc.find_library('elf', required: true)
|
|
||||||
endif
|
|
||||||
|
|
||||||
deps = [libelf]
|
|
||||||
|
|
||||||
libbpf_static = static_library(
|
|
||||||
'bpf',
|
|
||||||
libbpf_sources,
|
|
||||||
c_args : libbpf_c_args,
|
|
||||||
dependencies : deps,
|
|
||||||
include_directories : libbpf_includes,
|
|
||||||
install : true)
|
|
||||||
|
|
||||||
libbpf_static_dep = declare_dependency(link_with : libbpf_static)
|
|
||||||
|
|
||||||
libbpf_map_source_path = join_paths(libbpf_source_dir, 'src/libbpf.map')
|
|
||||||
libbpf_map_abs_path = join_paths(meson.current_source_dir(), libbpf_map_source_path)
|
|
||||||
|
|
||||||
libbpf_c_args += ['-fPIC', '-fvisibility=hidden']
|
|
||||||
|
|
||||||
libbpf_link_args = ['-Wl,--version-script=@0@'.format(libbpf_map_abs_path)]
|
|
||||||
|
|
||||||
libbpf_shared = shared_library(
|
|
||||||
'bpf',
|
|
||||||
libbpf_sources,
|
|
||||||
c_args : libbpf_c_args,
|
|
||||||
dependencies : deps,
|
|
||||||
include_directories : libbpf_includes,
|
|
||||||
install : true,
|
|
||||||
link_args : libbpf_link_args,
|
|
||||||
link_depends : libbpf_map_source_path,
|
|
||||||
soversion : patchlevel,
|
|
||||||
version : meson.project_version())
|
|
||||||
|
|
||||||
libbpf_shared_dep = declare_dependency(link_with : libbpf_shared)
|
|
||||||
|
|
||||||
install_headers(libbpf_headers, subdir : 'bpf')
|
|
||||||
|
|
||||||
pkg = import('pkgconfig')
|
|
||||||
pkg.generate(
|
|
||||||
name: meson.project_name(),
|
|
||||||
version: meson.project_version(),
|
|
||||||
libraries: libbpf_shared,
|
|
||||||
requires_private: ['libelf'],
|
|
||||||
description: '''BPF library''')
|
|
||||||
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
|
||||||
@@ -1,40 +1,209 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
echo "USAGE: ./sync-kernel.sh <kernel-repo> <libbpf-repo> [<baseline-commit>]"
|
echo "USAGE: ./sync-kernel.sh <libbpf-repo> <kernel-repo> <bpf-branch>"
|
||||||
echo ""
|
echo ""
|
||||||
echo "If <baseline-commit> is not specified, it's read from <libbpf-repo>/CHECKPOINT-COMMIT"
|
echo "Set BPF_NEXT_BASELINE to override bpf-next tree commit, otherwise read from <libbpf-repo>/CHECKPOINT-COMMIT."
|
||||||
exit 1
|
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."
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
LINUX_REPO=${1-""}
|
|
||||||
LIBBPF_REPO=${2-""}
|
|
||||||
|
|
||||||
if [ -z "${LINUX_REPO}" ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
if [ -z "${LIBBPF_REPO}" ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
WORKDIR=$(pwd)
|
LIBBPF_REPO=${1-""}
|
||||||
trap "cd ${WORKDIR}; exit" INT TERM EXIT
|
LINUX_REPO=${2-""}
|
||||||
|
BPF_BRANCH=${3-""}
|
||||||
|
BASELINE_COMMIT=${BPF_NEXT_BASELINE:-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)}
|
||||||
|
BPF_BASELINE_COMMIT=${BPF_BASELINE:-$(cat ${LIBBPF_REPO}/BPF-CHECKPOINT-COMMIT)}
|
||||||
|
|
||||||
echo "WORKDIR: ${WORKDIR}"
|
if [ -z "${LIBBPF_REPO}" ] || [ -z "${LINUX_REPO}" ]; then
|
||||||
echo "LINUX REPO: ${LINUX_REPO}"
|
echo "Error: libbpf or linux repos are not specified"
|
||||||
echo "LIBBPF REPO: ${LIBBPF_REPO}"
|
usage
|
||||||
|
fi
|
||||||
|
if [ -z "${BPF_BRANCH}" ]; then
|
||||||
|
echo "Error: linux's bpf tree branch is not specified"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
if [ -z "${BASELINE_COMMIT}" ] || [ -z "${BPF_BASELINE_COMMIT}" ]; then
|
||||||
|
echo "Error: bpf or bpf-next baseline commits are not provided"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
SUFFIX=$(date --utc +%Y-%m-%dT%H-%M-%S.%3NZ)
|
SUFFIX=$(date --utc +%Y-%m-%dT%H-%M-%S.%3NZ)
|
||||||
BASELINE_COMMIT=${3-$(cat ${LIBBPF_REPO}/CHECKPOINT-COMMIT)}
|
WORKDIR=$(pwd)
|
||||||
|
TMP_DIR=$(mktemp -d)
|
||||||
|
|
||||||
|
trap "cd ${WORKDIR}; exit" INT TERM EXIT
|
||||||
|
|
||||||
|
declare -A PATH_MAP
|
||||||
|
PATH_MAP=( \
|
||||||
|
[tools/lib/bpf]=src \
|
||||||
|
[tools/include/uapi/linux/bpf_common.h]=include/uapi/linux/bpf_common.h \
|
||||||
|
[tools/include/uapi/linux/bpf.h]=include/uapi/linux/bpf.h \
|
||||||
|
[tools/include/uapi/linux/btf.h]=include/uapi/linux/btf.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/netlink.h]=include/uapi/linux/netlink.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[@]} :^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_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'
|
||||||
|
for p in "${!PATH_MAP[@]}"; do
|
||||||
|
LIBBPF_TREE_FILTER+="git mv -kf ${p} __libbpf/${PATH_MAP[${p}]} && "$'\\\n'
|
||||||
|
done
|
||||||
|
LIBBPF_TREE_FILTER+="git rm --ignore-unmatch -f __libbpf/src/{Makefile,Build,test_libbpf.c,.gitignore} >/dev/null"
|
||||||
|
|
||||||
|
cd_to()
|
||||||
|
{
|
||||||
|
cd ${WORKDIR} && cd "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output brief single-line commit description
|
||||||
|
# $1 - commit ref
|
||||||
|
commit_desc()
|
||||||
|
{
|
||||||
|
git log -n1 --pretty='%h ("%s")' $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create commit single-line signature, which consists of:
|
||||||
|
# - full commit subject
|
||||||
|
# - author date in ISO8601 format
|
||||||
|
# - full commit body with newlines replaced with vertical bars (|)
|
||||||
|
# - shortstat appended at the end
|
||||||
|
# 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.
|
||||||
|
# $1 - commit ref
|
||||||
|
# $2 - paths filter
|
||||||
|
commit_signature()
|
||||||
|
{
|
||||||
|
git show --pretty='("%s")|%aI|%b' --shortstat $1 -- ${2-.} | tr '\n' '|'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cherry-pick commits touching libbpf-related files
|
||||||
|
# $1 - baseline_tag
|
||||||
|
# $2 - tip_tag
|
||||||
|
cherry_pick_commits()
|
||||||
|
{
|
||||||
|
local manual_mode=${MANUAL_MODE:-0}
|
||||||
|
local baseline_tag=$1
|
||||||
|
local tip_tag=$2
|
||||||
|
local new_commits
|
||||||
|
local signature
|
||||||
|
local should_skip
|
||||||
|
local synced_cnt
|
||||||
|
local manual_check
|
||||||
|
local libbpf_conflict_cnt
|
||||||
|
local desc
|
||||||
|
|
||||||
|
new_commits=$(git rev-list --no-merges --topo-order --reverse ${baseline_tag}..${tip_tag} ${LIBBPF_PATHS[@]})
|
||||||
|
for new_commit in ${new_commits}; do
|
||||||
|
desc="$(commit_desc ${new_commit})"
|
||||||
|
signature="$(commit_signature ${new_commit} "${LIBBPF_PATHS[@]}")"
|
||||||
|
synced_cnt=$(grep -F "${signature}" ${TMP_DIR}/libbpf_commits.txt | wc -l)
|
||||||
|
manual_check=0
|
||||||
|
if ((${synced_cnt} > 0)); then
|
||||||
|
# commit with the same subject is already in libbpf, but it's
|
||||||
|
# not 100% the same commit, so check with user
|
||||||
|
echo "Commit '${desc}' is synced into libbpf as:"
|
||||||
|
grep -F "${signature}" ${TMP_DIR}/libbpf_commits.txt | \
|
||||||
|
cut -d'|' -f1 | sed -e 's/^/- /'
|
||||||
|
if ((${manual_mode} != 1 && ${synced_cnt} == 1)); then
|
||||||
|
echo "Skipping '${desc}' due to unique match..."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if ((${synced_cnt} > 1)); then
|
||||||
|
echo "'${desc} matches multiple commits, please, double-check!"
|
||||||
|
manual_check=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if ((${manual_mode} == 1 || ${manual_check} == 1)); then
|
||||||
|
read -p "Do you want to skip '${desc}'? [y/N]: " should_skip
|
||||||
|
case "${should_skip}" in
|
||||||
|
"y" | "Y")
|
||||||
|
echo "Skipping '${desc}'..."
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
# commit hasn't been synced into libbpf yet
|
||||||
|
echo "Picking '${desc}'..."
|
||||||
|
if ! git cherry-pick ${new_commit} &>/dev/null; then
|
||||||
|
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)
|
||||||
|
conflict_cnt=$(git diff --name-only | wc -l)
|
||||||
|
prompt_resolution=1
|
||||||
|
|
||||||
|
if ((${libbpf_conflict_cnt} == 0)); then
|
||||||
|
echo "Looks like only non-libbpf files have conflicts, ignoring..."
|
||||||
|
if ((${conflict_cnt} == 0)); then
|
||||||
|
echo "Empty cherry-pick, skipping it..."
|
||||||
|
git cherry-pick --abort
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
git add .
|
||||||
|
# GIT_EDITOR=true to avoid editor popping up to edit commit message
|
||||||
|
if ! GIT_EDITOR=true git cherry-pick --continue &>/dev/null; then
|
||||||
|
echo "Error! That still failed! Please resolve manually."
|
||||||
|
else
|
||||||
|
echo "Success! All cherry-pick conflicts were resolved for '${desc}'!"
|
||||||
|
prompt_resolution=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ((${prompt_resolution} == 1)); then
|
||||||
|
read -p "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
GITHUB_ABS_DIR=$(pwd)
|
||||||
|
echo "Dumping existing libbpf commit signatures..."
|
||||||
|
for h in $(git log --pretty='%h' -n500); do
|
||||||
|
echo $h "$(commit_signature $h)" >> ${TMP_DIR}/libbpf_commits.txt
|
||||||
|
done
|
||||||
|
|
||||||
# Use current kernel repo HEAD as a source of patches
|
# Use current kernel repo HEAD as a source of patches
|
||||||
cd ${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})
|
||||||
BASELINE_TAG=libbpf-baseline-${SUFFIX}
|
BASELINE_TAG=libbpf-baseline-${SUFFIX}
|
||||||
TIP_TAG=libbpf-tip-${SUFFIX}
|
TIP_TAG=libbpf-tip-${SUFFIX}
|
||||||
|
BPF_BASELINE_TAG=libbpf-bpf-baseline-${SUFFIX}
|
||||||
|
BPF_TIP_TAG=libbpf-bpf-tip-${SUFFIX}
|
||||||
VIEW_TAG=libbpf-view-${SUFFIX}
|
VIEW_TAG=libbpf-view-${SUFFIX}
|
||||||
LIBBPF_SYNC_TAG=libbpf-sync-${SUFFIX}
|
LIBBPF_SYNC_TAG=libbpf-sync-${SUFFIX}
|
||||||
|
|
||||||
@@ -43,142 +212,139 @@ SQUASH_BASE_TAG=libbpf-squash-base-${SUFFIX}
|
|||||||
SQUASH_TIP_TAG=libbpf-squash-tip-${SUFFIX}
|
SQUASH_TIP_TAG=libbpf-squash-tip-${SUFFIX}
|
||||||
SQUASH_COMMIT=$(git commit-tree ${BASELINE_COMMIT}^{tree} -m "BASELINE SQUASH ${BASELINE_COMMIT}")
|
SQUASH_COMMIT=$(git commit-tree ${BASELINE_COMMIT}^{tree} -m "BASELINE SQUASH ${BASELINE_COMMIT}")
|
||||||
|
|
||||||
echo "SUFFIX: ${SUFFIX}"
|
echo "WORKDIR: ${WORKDIR}"
|
||||||
echo "BASELINE COMMIT: $(git log --pretty=oneline --no-walk ${BASELINE_COMMIT})"
|
echo "LINUX REPO: ${LINUX_REPO}"
|
||||||
echo "TIP COMMIT: $(git log --pretty=oneline --no-walk ${TIP_COMMIT})"
|
echo "LIBBPF REPO: ${LIBBPF_REPO}"
|
||||||
echo "SQUASH COMMIT: ${SQUASH_COMMIT}"
|
echo "TEMP DIR: ${TMP_DIR}"
|
||||||
echo "BASELINE TAG: ${BASELINE_TAG}"
|
echo "SUFFIX: ${SUFFIX}"
|
||||||
echo "TIP TAG: ${TIP_TAG}"
|
echo "BASE COMMIT: '$(commit_desc ${BASELINE_COMMIT})'"
|
||||||
echo "SQUASH BASE TAG: ${SQUASH_BASE_TAG}"
|
echo "TIP COMMIT: '$(commit_desc ${TIP_COMMIT})'"
|
||||||
echo "SQUASH TIP TAG: ${SQUASH_TIP_TAG}"
|
echo "BPF BASE COMMIT: '$(commit_desc ${BPF_BASELINE_COMMIT})'"
|
||||||
echo "VIEW TAG: ${VIEW_TAG}"
|
echo "BPF TIP COMMIT: '$(commit_desc ${BPF_TIP_COMMIT})'"
|
||||||
echo "LIBBPF SYNC TAG: ${LIBBPF_SYNC_TAG}"
|
echo "SQUASH COMMIT: ${SQUASH_COMMIT}"
|
||||||
|
echo "BASELINE TAG: ${BASELINE_TAG}"
|
||||||
TMP_DIR=$(mktemp -d)
|
echo "TIP TAG: ${TIP_TAG}"
|
||||||
echo "TEMP DIR: ${TMP_DIR}"
|
echo "BPF BASELINE TAG: ${BPF_BASELINE_TAG}"
|
||||||
echo "PATCHES+COVER: ${TMP_DIR}/patches"
|
echo "BPF TIP TAG: ${BPF_TIP_TAG}"
|
||||||
echo "PATCHSET: ${TMP_DIR}/patchset.patch"
|
echo "SQUASH BASE TAG: ${SQUASH_BASE_TAG}"
|
||||||
|
echo "SQUASH TIP TAG: ${SQUASH_TIP_TAG}"
|
||||||
|
echo "VIEW TAG: ${VIEW_TAG}"
|
||||||
|
echo "LIBBPF SYNC TAG: ${LIBBPF_SYNC_TAG}"
|
||||||
|
echo "PATCHES: ${TMP_DIR}/patches"
|
||||||
|
|
||||||
git branch ${BASELINE_TAG} ${BASELINE_COMMIT}
|
git branch ${BASELINE_TAG} ${BASELINE_COMMIT}
|
||||||
git branch ${TIP_TAG} ${TIP_COMMIT}
|
git branch ${TIP_TAG} ${TIP_COMMIT}
|
||||||
|
git branch ${BPF_BASELINE_TAG} ${BPF_BASELINE_COMMIT}
|
||||||
|
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}
|
||||||
|
|
||||||
# Cherry-pick new commits onto squashed baseline commit
|
# Cherry-pick new commits onto squashed baseline commit
|
||||||
LIBBPF_PATHS=(tools/lib/bpf tools/include/uapi/linux/{bpf_common.h,bpf.h,btf.h,if_link.h,if_xdp.h,netlink.h} tools/include/tools/libc_compat.h)
|
cherry_pick_commits ${BASELINE_TAG} ${TIP_TAG}
|
||||||
|
cherry_pick_commits ${BPF_BASELINE_TAG} ${BPF_TIP_TAG}
|
||||||
|
|
||||||
LIBBPF_NEW_MERGES=$(git rev-list --merges --topo-order --reverse ${BASELINE_TAG}..${TIP_TAG} ${LIBBPF_PATHS[@]})
|
|
||||||
for LIBBPF_NEW_MERGE in ${LIBBPF_NEW_MERGES}; do
|
|
||||||
printf "MERGE:\t" && git log --oneline -n1 ${LIBBPF_NEW_MERGE}
|
|
||||||
MERGE_CHANGES=$(git log --format='' -n1 ${LIBBPF_NEW_MERGE} | wc -l)
|
|
||||||
if ((${MERGE_CHANGES} > 0)); then
|
|
||||||
echo "Merge is non empty, aborting!.."
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
cd ${WORKDIR} && cd ${LIBBPF_REPO}
|
|
||||||
git log --oneline -n500 > ${TMP_DIR}/libbpf_commits.txt
|
|
||||||
cd ${WORKDIR} && cd ${LINUX_REPO}
|
|
||||||
|
|
||||||
LIBBPF_NEW_COMMITS=$(git rev-list --no-merges --topo-order --reverse ${BASELINE_TAG}..${TIP_TAG} ${LIBBPF_PATHS[@]})
|
|
||||||
for LIBBPF_NEW_COMMIT in ${LIBBPF_NEW_COMMITS}; do
|
|
||||||
echo "Checking commit '${LIBBPF_NEW_COMMIT}'"
|
|
||||||
SYNCED_COMMITS=$(grep -F "$(git log -n1 --pretty=format:%s ${LIBBPF_NEW_COMMIT})" ${TMP_DIR}/libbpf_commits.txt || echo "")
|
|
||||||
if [ -n "${SYNCED_COMMITS}" ]; then
|
|
||||||
# commit with the same subject is already in libbpf, but it's not 100% the same commit, so check with user
|
|
||||||
echo "Commit '$(git log -n1 --oneline ${LIBBPF_NEW_COMMIT})' appears to be already synced into libbpf..."
|
|
||||||
echo "Corresponding libbpf commit(s):"
|
|
||||||
echo "${SYNCED_COMMITS}"
|
|
||||||
read -p "Do you want to skip it? [y/N]: " SHOULD_SKIP
|
|
||||||
case "${SHOULD_SKIP}" in
|
|
||||||
"y" | "Y")
|
|
||||||
echo "Skipping '$(git log -n1 --oneline ${LIBBPF_NEW_COMMIT})'..."
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
# commit hasn't been synced into libbpf yet
|
|
||||||
if ! git cherry-pick ${LIBBPF_NEW_COMMIT}; then
|
|
||||||
read -p "Cherry-picking '$(git log --oneline -n1 ${LIBBPF_NEW_COMMIT})' failed, please fix manually and press <return> to proceed..."
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
LIBBPF_TREE_FILTER=' \
|
|
||||||
mkdir -p __libbpf/include/uapi/linux __libbpf/include/tools && \
|
|
||||||
git mv -kf tools/lib/bpf __libbpf/src && \
|
|
||||||
git mv -kf tools/include/uapi/linux/{bpf_common.h,bpf.h,btf.h,if_link.h,if_xdp.h,netlink.h} \
|
|
||||||
__libbpf/include/uapi/linux && \
|
|
||||||
git mv -kf tools/include/tools/libc_compat.h __libbpf/include/tools && \
|
|
||||||
git rm --ignore-unmatch -f __libbpf/src/{Makefile,Build,test_libbpf.cpp,.gitignore} \
|
|
||||||
'
|
|
||||||
# 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
|
||||||
|
|
||||||
# Exclude baseline commit and generate nice cover letter with summary
|
# Exclude baseline commit and generate nice cover letter with summary
|
||||||
git format-patch ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG} --cover-letter -o ${TMP_DIR}/patches
|
git format-patch ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG} --cover-letter -o ${TMP_DIR}/patches
|
||||||
# Now generate single-file patchset w/o cover to apply on top of libbpf repo
|
|
||||||
git format-patch ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG} --stdout > ${TMP_DIR}/patchset.patch
|
|
||||||
|
|
||||||
# Now is time to re-apply libbpf-related linux patches to libbpf repo
|
# Now is time to re-apply libbpf-related linux patches to libbpf repo
|
||||||
cd ${WORKDIR} && cd ${LIBBPF_REPO}
|
cd_to ${LIBBPF_REPO}
|
||||||
git checkout -b ${LIBBPF_SYNC_TAG}
|
git checkout -b ${LIBBPF_SYNC_TAG}
|
||||||
git am --committer-date-is-author-date ${TMP_DIR}/patchset.patch
|
|
||||||
|
for patch in $(ls -1 ${TMP_DIR}/patches | tail -n +2); do
|
||||||
|
if ! git am -3 --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
|
||||||
|
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
|
||||||
|
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)
|
||||||
echo ${TIP_COMMIT} > CHECKPOINT-COMMIT && \
|
echo ${TIP_COMMIT} > CHECKPOINT-COMMIT && \
|
||||||
|
echo ${BPF_TIP_COMMIT} > BPF-CHECKPOINT-COMMIT && \
|
||||||
git add CHECKPOINT-COMMIT && \
|
git add CHECKPOINT-COMMIT && \
|
||||||
|
git add BPF-CHECKPOINT-COMMIT && \
|
||||||
awk '/\*\*\* BLURB HERE \*\*\*/ {p=1} p' ${TMP_DIR}/patches/0000-cover-letter.patch | \
|
awk '/\*\*\* BLURB HERE \*\*\*/ {p=1} p' ${TMP_DIR}/patches/0000-cover-letter.patch | \
|
||||||
sed "s/\*\*\* BLURB HERE \*\*\*/\
|
sed "s/\*\*\* BLURB HERE \*\*\*/\
|
||||||
sync: latest libbpf changes from kernel\n\
|
sync: latest libbpf changes from kernel\n\
|
||||||
\n\
|
\n\
|
||||||
Syncing latest libbpf commits from kernel repository.\n\
|
Syncing latest libbpf commits from kernel repository.\n\
|
||||||
Baseline commit: ${BASELINE_COMMIT}\n\
|
Baseline bpf-next commit: ${BASELINE_COMMIT}\n\
|
||||||
Checkpoint commit: ${TIP_COMMIT}/" | \
|
Checkpoint bpf-next commit: ${TIP_COMMIT}\n\
|
||||||
|
Baseline bpf commit: ${BPF_BASELINE_COMMIT}\n\
|
||||||
|
Checkpoint bpf commit: ${BPF_TIP_COMMIT}/" | \
|
||||||
git commit --file=-
|
git commit --file=-
|
||||||
|
|
||||||
echo "SUCCESS! ${COMMIT_CNT} commits synced."
|
echo "SUCCESS! ${COMMIT_CNT} commits synced."
|
||||||
|
|
||||||
echo "Verifying Linux's and Github's libbpf state"
|
echo "Verifying Linux's and Github's libbpf state"
|
||||||
LIBBPF_VIEW_PATHS=(src include/uapi/linux/{bpf_common.h,bpf.h,btf.h,if_link.h,if_xdp.h,netlink.h} include/tools/libc_compat.h)
|
|
||||||
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf.cpp|\.gitignore)$'
|
|
||||||
|
|
||||||
cd ${WORKDIR} && cd ${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 ${WORKDIR} && cd ${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..."
|
||||||
diff ${TMP_DIR}/linux-view.ls ${TMP_DIR}/github-view.ls
|
diff -u ${TMP_DIR}/linux-view.ls ${TMP_DIR}/github-view.ls
|
||||||
echo "Comparing file contents..."
|
echo "Comparing file contents..."
|
||||||
|
CONSISTENT=1
|
||||||
for F in $(cat ${TMP_DIR}/linux-view.ls); do
|
for F in $(cat ${TMP_DIR}/linux-view.ls); do
|
||||||
diff "${LINUX_ABS_DIR}/${F}" "${GITHUB_ABS_DIR}/${F}"
|
if ! diff -u "${LINUX_ABS_DIR}/${F}" "${GITHUB_ABS_DIR}/${F}"; then
|
||||||
|
echo "${LINUX_ABS_DIR}/${F} and ${GITHUB_ABS_DIR}/${F} are different!"
|
||||||
|
CONSISTENT=0
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
echo "Contents appear identical!"
|
if ((${CONSISTENT} == 1)); then
|
||||||
|
echo "Great! Content is identical!"
|
||||||
echo "Cleaning up..."
|
else
|
||||||
rm -r ${TMP_DIR}
|
ignore_inconsistency=n
|
||||||
cd ${WORKDIR} && cd ${LINUX_REPO}
|
echo "Unfortunately, there are some inconsistencies, please double check."
|
||||||
git checkout ${TIP_SYM_REF}
|
read -p "Does everything look good? [y/N]: " ignore_inconsistency
|
||||||
git branch -D ${BASELINE_TAG} ${TIP_TAG} ${SQUASH_BASE_TAG} ${SQUASH_TIP_TAG} ${VIEW_TAG}
|
case "${ignore_inconsistency}" in
|
||||||
|
"y" | "Y")
|
||||||
cd ${WORKDIR}
|
echo "Ok, proceeding..."
|
||||||
echo "DONE."
|
;;
|
||||||
|
*)
|
||||||
|
echo "Oops, exiting with error..."
|
||||||
|
exit 4
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
|||||||
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@@ -2,3 +2,5 @@
|
|||||||
*.a
|
*.a
|
||||||
/libbpf.pc
|
/libbpf.pc
|
||||||
/libbpf.so*
|
/libbpf.so*
|
||||||
|
/staticobjs
|
||||||
|
/sharedobjs
|
||||||
|
|||||||
164
src/Makefile
164
src/Makefile
@@ -1,53 +1,75 @@
|
|||||||
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||||
|
|
||||||
VERSION = 0
|
ifeq ($(V),1)
|
||||||
PATCHLEVEL = 0
|
Q =
|
||||||
EXTRAVERSION = 3
|
msg =
|
||||||
|
else
|
||||||
|
Q = @
|
||||||
|
msg = @printf ' %-8s %s%s\n' "$(1)" "$(2)" "$(if $(3), $(3))";
|
||||||
|
endif
|
||||||
|
|
||||||
LIBBPF_VERSION = $(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)
|
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)
|
SHARED_CFLAGS += -fPIC -fvisibility=hidden -DSHARED
|
||||||
ifneq ($(FEATURE_REALLOCARRAY),)
|
|
||||||
ALL_CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef BUILD_STATIC_ONLY
|
CFLAGS ?= -g -O2 -Werror -Wall -std=gnu89
|
||||||
ALL_CFLAGS += -fPIC -fvisibility=hidden
|
ALL_CFLAGS += $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 $(EXTRA_CFLAGS)
|
||||||
endif
|
ALL_LDFLAGS += $(LDFLAGS) $(EXTRA_LDFLAGS)
|
||||||
|
|
||||||
CFLAGS ?= -g -O2 -Werror -Wall
|
|
||||||
ALL_CFLAGS += $(CFLAGS)
|
|
||||||
ALL_LDFLAGS += $(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
|
||||||
|
STATIC_OBJDIR := $(OBJDIR)/staticobjs
|
||||||
|
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
||||||
|
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.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))
|
||||||
|
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
||||||
|
|
||||||
OBJS := $(addprefix $(OBJDIR)/,bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
STATIC_LIBS := $(OBJDIR)/libbpf.a
|
||||||
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o xsk.o \
|
|
||||||
btf_dump.o hashmap.o)
|
|
||||||
|
|
||||||
LIBS := $(OBJDIR)/libbpf.a
|
|
||||||
ifndef BUILD_STATIC_ONLY
|
ifndef BUILD_STATIC_ONLY
|
||||||
LIBS += $(OBJDIR)/libbpf.so \
|
SHARED_LIBS := $(OBJDIR)/libbpf.so \
|
||||||
$(OBJDIR)/libbpf.so.$(VERSION) \
|
$(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
||||||
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
||||||
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 \
|
||||||
UAPI_HEADERS := $(addprefix $(TOPDIR)/include/uapi/linux/,bpf.h bpf_common.h \
|
bpf_helpers.h bpf_helper_defs.h bpf_tracing.h \
|
||||||
btf.h)
|
bpf_endian.h bpf_core_read.h skel_internal.h libbpf_version.h \
|
||||||
|
usdt.bpf.h
|
||||||
|
UAPI_HEADERS := $(addprefix $(TOPDIR)/include/uapi/linux/,\
|
||||||
|
bpf.h bpf_common.h btf.h)
|
||||||
|
|
||||||
PC_FILE := $(OBJDIR)/libbpf.pc
|
PC_FILE := $(OBJDIR)/libbpf.pc
|
||||||
|
|
||||||
@@ -55,59 +77,81 @@ 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
|
||||||
|
|
||||||
all: $(LIBS) $(PC_FILE)
|
TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.a: $(OBJS)
|
all: $(STATIC_LIBS) $(SHARED_LIBS) $(PC_FILE)
|
||||||
$(AR) rcs $@ $^
|
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so: $(OBJDIR)/libbpf.so.$(VERSION)
|
$(OBJDIR)/libbpf.a: $(STATIC_OBJS)
|
||||||
ln -sf $(^F) $@
|
$(call msg,AR,$@)
|
||||||
|
$(Q)$(AR) rcs $@ $^
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so.$(VERSION): $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
$(OBJDIR)/libbpf.so: $(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION)
|
||||||
ln -sf $(^F) $@
|
$(Q)ln -sf $(^F) $@
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(OBJS)
|
$(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION): $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
||||||
$(CC) -shared $(ALL_LDFLAGS) -Wl,--version-script=$(VERSION_SCRIPT) \
|
$(Q)ln -sf $(^F) $@
|
||||||
-Wl,-soname,libbpf.so.$(VERSION) \
|
|
||||||
$^ -o $@
|
|
||||||
|
|
||||||
$(OBJDIR)/libbpf.pc:
|
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(SHARED_OBJS)
|
||||||
sed -e "s|@PREFIX@|$(PREFIX)|" \
|
$(call msg,CC,$@)
|
||||||
-e "s|@LIBDIR@|$(LIBDIR)|" \
|
$(Q)$(CC) -shared -Wl,--version-script=$(VERSION_SCRIPT) \
|
||||||
|
-Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
||||||
|
$^ $(ALL_LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(OBJDIR)/libbpf.pc: force
|
||||||
|
$(Q)sed -e "s|@PREFIX@|$(PREFIX)|" \
|
||||||
|
-e "s|@LIBDIR@|$(LIBDIR_PC)|" \
|
||||||
-e "s|@VERSION@|$(LIBBPF_VERSION)|" \
|
-e "s|@VERSION@|$(LIBBPF_VERSION)|" \
|
||||||
< libbpf.pc.template > $@
|
< libbpf.pc.template > $@
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
$(STATIC_OBJDIR) $(SHARED_OBJDIR):
|
||||||
$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
$(call msg,MKDIR,$@)
|
||||||
|
$(Q)mkdir -p $@
|
||||||
|
|
||||||
|
$(STATIC_OBJDIR)/%.o: %.c | $(STATIC_OBJDIR)
|
||||||
|
$(call msg,CC,$@)
|
||||||
|
$(Q)$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(SHARED_OBJDIR)/%.o: %.c | $(SHARED_OBJDIR)
|
||||||
|
$(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
|
||||||
$(call do_s_install,$(LIBS),$(LIBDIR))
|
$(call do_s_install,$(STATIC_LIBS) $(SHARED_LIBS),$(LIBDIR))
|
||||||
|
|
||||||
install_headers:
|
install_headers:
|
||||||
$(call do_install,$(HEADERS),$(INCLUDEDIR)/bpf,644)
|
$(call do_install,$(HEADERS),$(INCLUDEDIR)/bpf,644)
|
||||||
@@ -121,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 -f *.o *.a *.so *.so.* *.pc
|
$(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:
|
||||||
|
|||||||
395
src/bpf.h
395
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,31 +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_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
|
||||||
565
src/btf.h
565
src/btf.h
@@ -1,20 +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/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"
|
||||||
@@ -25,101 +26,525 @@ 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
return BTF_INFO_KIND(t->info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __u16 btf_vlen(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return BTF_INFO_VLEN(t->info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_kflag(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_ptr(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_PTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_array(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_struct(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_STRUCT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_union(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_UNION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_composite(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
__u16 kind = btf_kind(t);
|
||||||
|
|
||||||
|
return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_enum(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_FWD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_typedef(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_TYPEDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_volatile(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_VOLATILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_const(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_restrict(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_RESTRICT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_mod(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
__u16 kind = btf_kind(t);
|
||||||
|
|
||||||
|
return kind == BTF_KIND_VOLATILE ||
|
||||||
|
kind == BTF_KIND_CONST ||
|
||||||
|
kind == BTF_KIND_RESTRICT ||
|
||||||
|
kind == BTF_KIND_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_func(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_func_proto(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_FUNC_PROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_var(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return btf_kind(t) == BTF_KIND_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool btf_is_datasec(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return BTF_INT_ENCODING(*(__u32 *)(t + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __u8 btf_int_offset(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return BTF_INT_OFFSET(*(__u32 *)(t + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __u8 btf_int_bits(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return BTF_INT_BITS(*(__u32 *)(t + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct btf_array *btf_array(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (struct btf_array *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct btf_enum *btf_enum(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return (struct btf_member *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get bit offset of a member with specified index. */
|
||||||
|
static inline __u32 btf_member_bit_offset(const struct btf_type *t,
|
||||||
|
__u32 member_idx)
|
||||||
|
{
|
||||||
|
const struct btf_member *m = btf_members(t) + member_idx;
|
||||||
|
bool kflag = btf_kflag(t);
|
||||||
|
|
||||||
|
return kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Get bitfield size of a member, assuming t is BTF_KIND_STRUCT or
|
||||||
|
* BTF_KIND_UNION. If member is not a bitfield, zero is returned.
|
||||||
|
*/
|
||||||
|
static inline __u32 btf_member_bitfield_size(const struct btf_type *t,
|
||||||
|
__u32 member_idx)
|
||||||
|
{
|
||||||
|
const struct btf_member *m = btf_members(t) + member_idx;
|
||||||
|
bool kflag = btf_kflag(t);
|
||||||
|
|
||||||
|
return kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct btf_param *btf_params(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (struct btf_param *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct btf_var *btf_var(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
return (struct btf_var *)(t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct btf_var_secinfo *
|
||||||
|
btf_var_secinfos(const struct btf_type *t)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|||||||
1506
src/btf_dump.c
1506
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,12 +10,34 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "libbpf_internal.h"
|
#include <limits.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);
|
||||||
@@ -155,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))
|
||||||
|
|||||||
13212
src/libbpf.c
13212
src/libbpf.c
File diff suppressed because it is too large
Load Diff
1471
src/libbpf.h
1471
src/libbpf.h
File diff suppressed because it is too large
Load Diff
352
src/libbpf.map
352
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,11 +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;
|
||||||
} LIBBPF_0.0.3;
|
} LIBBPF_0.0.3;
|
||||||
|
|
||||||
|
LIBBPF_0.0.5 {
|
||||||
|
global:
|
||||||
|
bpf_btf_get_next_id;
|
||||||
|
} 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,13 +68,79 @@
|
|||||||
#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
|
||||||
#ifndef max
|
#ifndef max
|
||||||
# define max(x, y) ((x) < (y) ? (y) : (x))
|
# define max(x, y) ((x) < (y) ? (y) : (x))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef offsetofend
|
||||||
|
# define offsetofend(TYPE, FIELD) \
|
||||||
|
(offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
|
||||||
|
#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.
|
||||||
|
* Properly versioned symbols are needed for shared library, but
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#if defined(SHARED) && defined(__GNUC__) && __GNUC__ >= 10
|
||||||
|
|
||||||
|
#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);
|
||||||
|
#define DEFAULT_VERSION(internal_name, api_name, version) \
|
||||||
|
asm(".symver " #internal_name "," #api_name "@@" #version);
|
||||||
|
|
||||||
|
#else /* !SHARED */
|
||||||
|
|
||||||
|
#define COMPAT_VERSION(internal_name, api_name, version)
|
||||||
|
#define DEFAULT_VERSION(internal_name, api_name, version) \
|
||||||
|
extern typeof(internal_name) api_name \
|
||||||
|
__attribute__((alias(#internal_name)));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void libbpf_print(enum libbpf_print_level level,
|
extern void libbpf_print(enum libbpf_print_level level,
|
||||||
const char *format, ...)
|
const char *format, ...)
|
||||||
@@ -39,11 +151,429 @@ 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 {
|
||||||
|
/*
|
||||||
|
* info points to the individual info section (e.g. func_info and
|
||||||
|
* line_info) from the .BTF.ext. It does not include the __u32 rec_size.
|
||||||
|
*/
|
||||||
|
void *info;
|
||||||
|
__u32 rec_size;
|
||||||
|
__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) \
|
||||||
|
for (sec = (seg)->info; \
|
||||||
|
(void *)sec < (seg)->info + (seg)->len; \
|
||||||
|
sec = (void *)sec + sizeof(struct btf_ext_info_sec) + \
|
||||||
|
(seg)->rec_size * sec->num_info)
|
||||||
|
|
||||||
|
#define for_each_btf_ext_rec(seg, sec, i, rec) \
|
||||||
|
for (i = 0, rec = (void *)&(sec)->data; \
|
||||||
|
i < (sec)->num_info; \
|
||||||
|
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 {
|
||||||
|
union {
|
||||||
|
struct btf_ext_header *hdr;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
struct btf_ext_info func_info;
|
||||||
|
struct btf_ext_info line_info;
|
||||||
|
struct btf_ext_info core_relo_info;
|
||||||
|
__u32 data_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct btf_ext_info_sec {
|
||||||
|
__u32 sec_name_off;
|
||||||
|
__u32 num_info;
|
||||||
|
/* Followed by num_info * record_size number of bytes */
|
||||||
|
__u8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The minimum bpf_func_info checked by the loader */
|
||||||
|
struct bpf_func_info_min {
|
||||||
|
__u32 insn_off;
|
||||||
|
__u32 type_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The minimum bpf_line_info checked by the loader */
|
||||||
|
struct bpf_line_info_min {
|
||||||
|
__u32 insn_off;
|
||||||
|
__u32 file_name_off;
|
||||||
|
__u32 line_off;
|
||||||
|
__u32 line_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
|
||||||
|
typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
|
||||||
|
int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx);
|
||||||
|
int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx);
|
||||||
|
int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
|
||||||
|
int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
|
||||||
|
__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
|
||||||
|
__u32 kind);
|
||||||
|
|
||||||
|
typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,
|
||||||
|
const char *sym_name, void *ctx);
|
||||||
|
|
||||||
|
int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *arg);
|
||||||
|
|
||||||
|
/* handle direct returned errors */
|
||||||
|
static inline int libbpf_err(int ret)
|
||||||
|
{
|
||||||
|
if (ret < 0)
|
||||||
|
errno = -ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle errno-based (e.g., syscall or libc) errors according to libbpf's
|
||||||
|
* strict mode settings
|
||||||
|
*/
|
||||||
|
static inline int libbpf_err_errno(int ret)
|
||||||
|
{
|
||||||
|
/* errno is already assumed to be set on error */
|
||||||
|
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:
|
||||||
@@ -244,78 +256,107 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
|||||||
case BPF_MAP_TYPE_ARRAY_OF_MAPS:
|
case BPF_MAP_TYPE_ARRAY_OF_MAPS:
|
||||||
case BPF_MAP_TYPE_HASH_OF_MAPS:
|
case BPF_MAP_TYPE_HASH_OF_MAPS:
|
||||||
case BPF_MAP_TYPE_DEVMAP:
|
case BPF_MAP_TYPE_DEVMAP:
|
||||||
|
case BPF_MAP_TYPE_DEVMAP_HASH:
|
||||||
case BPF_MAP_TYPE_SOCKMAP:
|
case BPF_MAP_TYPE_SOCKMAP:
|
||||||
case BPF_MAP_TYPE_CPUMAP:
|
case BPF_MAP_TYPE_CPUMAP:
|
||||||
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
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user