diff --git a/.github/workflows/ebpf_net_manager.yml b/.github/workflows/ebpf_net_manager.yml index a0364aef2..4e18ac35e 100644 --- a/.github/workflows/ebpf_net_manager.yml +++ b/.github/workflows/ebpf_net_manager.yml @@ -41,9 +41,8 @@ jobs: cd testenv sudo ./testenv.sh setup --name veth-basic02 cd .. - cd net_manager - sudo timeout -s SIGINT 5 ./xdp_loader -d eth0 -S || if [[ $? != 124 && $? != 0 ]];then exit $?;fi - sudo ./xdp_loader -d eth0 -S + sudo timeout -s SIGINT 5 ./netmanager -d eth0 -S || if [[ $? != 124 && $? != 0 ]];then exit $?;fi + sudo ./netmanager -d eth0 -S diff --git a/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/package.json b/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/package.json index e22b892cc..b22e18720 100644 --- a/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/package.json +++ b/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/package.json @@ -173,7 +173,7 @@ "prettier": "3.0.2", "ts-loader": "^9.4.2", "typescript": "^4.9.5", - "webpack": "^5.75.0", + "webpack": "^5.94.0", "webpack-cli": "^5.0.1" }, "dependencies": { diff --git a/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/yarn.lock b/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/yarn.lock index c983e7f2c..48708f63c 100644 --- a/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/yarn.lock +++ b/MagicEyes/src/visualization/vscode_ext/lmp_ext_vscode/yarn.lock @@ -95,7 +95,15 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.20": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.20" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== @@ -151,26 +159,10 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.6" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" - integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.44.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" - integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" - integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== +"@types/estree@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/express-serve-static-core@^4.17.33": version "4.17.39" @@ -212,7 +204,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.14" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== @@ -397,10 +389,10 @@ jszip "^3.10.1" semver "^7.5.2" -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: "@webassemblyjs/helper-numbers" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" @@ -415,10 +407,10 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== "@webassemblyjs/helper-numbers@1.11.6": version "1.11.6" @@ -434,15 +426,15 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/ieee754@1.11.6": version "1.11.6" @@ -463,59 +455,59 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" - -"@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== - dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-api-error" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^2.1.1": @@ -551,10 +543,10 @@ accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn-jsx@^5.3.2: version "5.3.2" @@ -702,15 +694,15 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.14.5: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== +browserslist@^4.21.10: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" buffer-from@^1.0.0: version "1.1.2" @@ -741,10 +733,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001541: - version "1.0.30001559" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001559.tgz#95a982440d3d314c471db68d02664fb7536c5a30" - integrity sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA== +caniuse-lite@^1.0.30001646: + version "1.0.30001655" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz#0ce881f5a19a2dcfda2ecd927df4d5c1684b982f" + integrity sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg== chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" @@ -952,10 +944,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.535: - version "1.4.572" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.572.tgz#ed9876658998138fe9e3aa47ecfa0bf914192a86" - integrity sha512-RlFobl4D3ieetbnR+2EpxdzFl9h0RAJkPK3pfiwMug2nhBin2ZCsGIAJWdpNniLz43sgXam/CgipOmvTA+rUiA== +electron-to-chromium@^1.5.4: + version "1.5.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" + integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== emitter-component@^1.1.1: version "1.1.1" @@ -972,10 +964,10 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== +enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -995,6 +987,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -1394,7 +1391,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -1892,10 +1889,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -2027,10 +2024,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -2409,21 +2406,21 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.17" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.8" + terser "^5.26.0" -terser@^5.16.8: - version "5.24.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" - integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== +terser@^5.26.0: + version "5.31.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -2514,13 +2511,13 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.1.2" + picocolors "^1.0.1" uri-js@^4.2.2: version "4.4.1" @@ -2556,10 +2553,10 @@ vary@^1, vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -2597,34 +2594,33 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.75.0: - version "5.89.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" - integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== +webpack@^5.94.0: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" which@^2.0.1: diff --git a/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse b/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse deleted file mode 100755 index 8b255be73..000000000 Binary files a/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse and /dev/null differ diff --git a/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse.c b/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse.c index 03cdec001..0c2443e79 100644 --- a/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse.c +++ b/eBPF_Supermarket/Filesystem_Subsystem/fast_fuse/difuse/src/difuse.c @@ -15,16 +15,25 @@ #define DIRECTORY_TYPE 2 #define MAX_INODES 1000 //最大 inode 数量 #define HASH_SIZE 1024 +#define CHUNK_SIZE 4096 // 数据块的大小 uint32_t next_ino = 1; struct dfs_data { - int chunk_size; + char *data; size_t size; struct dfs_data *next; }; +static struct dfs_data *allocate_data_block() +{ + struct dfs_data *new_data = (struct dfs_data *)malloc(sizeof(struct dfs_data)); + new_data->data = (char *)malloc(CHUNK_SIZE); + new_data->next = NULL; + return new_data; +} + struct dfs_inode { uint32_t ino; //inode编号 @@ -401,16 +410,106 @@ static int di_read(const char *path, char *buf, size_t size, off_t offset, struc if (dentry->ftype != FILE_TYPE) return -EISDIR; - if (offset < dentry->inode->size) + struct dfs_inode *inode = dentry->inode; + size_t file_size = inode->size; + + if (offset >= file_size) + return 0; + + if (offset + size > file_size) + size = file_size - offset; + + // 初始化缓冲区 + memset(buf, 0, size); + + // 从数据块中读取数据 + size_t bytes_read = 0; + struct dfs_data *data_block = inode->data_pointer; + + // 遍历数据块 + while (data_block != NULL && bytes_read < size) { - if (offset + size > dentry->inode->size) - size = dentry->inode->size - offset; - memcpy(buf, "dummy_content", size); + // 计算当前块的有效数据长度 + size_t block_size = data_block->size; + if (offset >= block_size) + { + offset -= block_size; + } + else + { + // 从当前块读取数据 + size_t to_read = block_size - offset; + if (to_read > size - bytes_read) + to_read = size - bytes_read; + + // 复制数据到缓冲区 + memcpy(buf + bytes_read, ((char *)data_block) + offset, to_read); + bytes_read += to_read; + offset = 0; + } + + data_block = data_block->next; + } + + return bytes_read; +} + +static int di_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) +{ + (void)fi; + struct dfs_dentry *dentry = look_up(root, path); + + if (dentry == NULL) return -ENOENT; + if (dentry->ftype != FILE_TYPE) return -EISDIR; + + struct dfs_inode *inode = dentry->inode; + struct dfs_data *data_block = inode->data_pointer; + + if (data_block == NULL) + { + data_block = allocate_data_block(); + inode->data_pointer = data_block; + } + + size_t bytes_written = 0; + size_t total_offset = offset; + + while (data_block != NULL && total_offset >= data_block->size) + { + total_offset -= data_block->size; + if (data_block->next == NULL) + { + data_block->next = allocate_data_block(); + } + data_block = data_block->next; + } + + while (bytes_written < size) + { + size_t space_in_block = CHUNK_SIZE - total_offset; + size_t to_write = size - bytes_written; + + if (to_write > space_in_block) to_write = space_in_block; + + memcpy(data_block->data + total_offset, buf + bytes_written, to_write); + + total_offset = 0; + bytes_written += to_write; + data_block->size += to_write; + + if (bytes_written < size && data_block->next == NULL) + { + data_block->next = allocate_data_block(); + } + data_block = data_block->next; + } + + if (offset + bytes_written > inode->size) + { + inode->size = offset + bytes_written; } - else - size = 0; - return size; + return bytes_written; } static void *di_init(struct fuse_conn_info *conn, struct fuse_config *cfg) @@ -430,6 +529,7 @@ static struct fuse_operations difs_ops = { .getattr = di_getattr, .open = di_open, .read = di_read, + .write = di_write, .mkdir = di_mkdir, .create = dfs_create, .utimens = di_utimens, diff --git a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/bpf/fraginfo.bpf.c b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/bpf/fraginfo.bpf.c index 342411373..9d199da7b 100644 --- a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/bpf/fraginfo.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/bpf/fraginfo.bpf.c @@ -87,9 +87,6 @@ int BPF_KPROBE(get_page_from_freelist, gfp_t gfp_mask, unsigned int order, int a struct contig_page_info ctg_info = {}; fill_contig_page_info(z, a_order, &ctg_info); bpf_map_update_elem(&orders,&order_key,&ctg_info,BPF_ANY); - bpf_printk("Order: %d, Free pages: %lu, Free blocks total: %lu, Free blocks suitable: %lu", - a_order, ctg_info.free_pages, ctg_info.free_blocks_total, ctg_info.free_blocks_suitable); - bpf_printk("2"); } bpf_map_update_elem(&zones, &zone_key, &zone_data, BPF_ANY); diff --git a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c index f00b7ca05..ea2944f6a 100644 --- a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c +++ b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c @@ -1193,18 +1193,39 @@ static int process_memleak(struct memleak_bpf *skel_memleak, struct env env) } // ================================================== fraginfo==================================================================== -void print_nodes(int fd) { - struct pgdat_info pinfo; - __u64 key = 0, next_key; - printf(" Node ID PGDAT_PTR NR_ZONES \n"); - while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { - bpf_map_lookup_elem(fd, &next_key, &pinfo); - printf(" %5d 0x%llx %5d\n", - pinfo.node_id, pinfo.pgdat_ptr, pinfo.nr_zones); - key = next_key; - } -} +//compute order +static int __fragmentation_index(unsigned int order, long unsigned int total,long unsigned int suitable,long unsigned int free) { + unsigned long requested = 1UL << order; + if (order > MAX_ORDER) + return 0; + if (!total) + return 0; + if (suitable) + return -1000; + double res1,res2; + res1 = (double)(free * 1000ULL)/requested; + res1 +=1000; + res2 = (double)res1/total; + return 1000 - res2; + } +static int unusable_free_index(unsigned int order, long unsigned int total,long unsigned int suitable,long unsigned int free) +{ + /* No free memory is interpreted as all free memory is unusable */ + if (free == 0) + return 1000; + + /* + * Index should be a value between 0 and 1. Return a value to 3 + * decimal places. + * + * 0 => no fragmentation + * 1 => high fragmentation + */ + long unsigned int res1 = free - (suitable</dev/null) ]; then \ + echo "*** ERROR: Cannot find tool $${TOOL}" ;\ + exit 1; \ + else true; fi; \ + done + +$(OBJECT_LIBBPF): + @if [ ! -d $(LIBBPF_DIR) ]; then \ + echo "Error: Need libbpf submodule" $(LIBBPF_DIR); \ + echo "May need to run git submodule update --init"; \ + exit 1; \ + else \ + cd $(LIBBPF_DIR) && $(MAKE) all OBJDIR=.; \ + mkdir -p build; $(MAKE) install_headers DESTDIR=build OBJDIR=.; \ + fi + +$(OBJECT_LIBXDP): + @if [ ! -d $(LIBXDP_DIR) ]; then \ + echo "Error: Need libxdp submodule" $(LIBXDP_DIR); \ + echo "May need to run git submodule update --init"; \ + exit 1; \ + else \ + cd $(LIBXDP_DIR) && $(MAKE) all OBJDIR=.; \ + fi + +# Create dependency: detect if C-file change and touch H-file, to trigger +# target $(COMMON_OBJS) +$(COMMON_H): %.h: %.c + touch $@ + +# Detect if any of common obj changed and create dependency on .h-files +$(COMMON_OBJS): %.o: %.h + $(Q)$(MAKE) -C $(COMMON_DIR) + +$(USER_TARGETS): %: %.c $(OBJECT_LIBBPF) $(OBJECT_LIBXDP) Makefile $(COMMON_MK) $(COMMON_OBJS) $(KERN_USER_H) $(EXTRA_DEPS) $(XLB_OBJS) + $(QUIET_CC)$(CC) -Wall $(CFLAGS) $(LDFLAGS) -o $@ $(COMMON_OBJS) $(XLB_OBJS) $(LIB_OBJS) \ + $< $(LDLIBS) + +$(XDP_OBJ): %.o: %.c Makefile $(COMMON_MK) $(KERN_USER_H) $(EXTRA_DEPS) $(OBJECT_LIBBPF) + $(QUIET_CLANG)$(CLANG) -S \ + -target bpf \ + -D __BPF_TRACING__ \ + $(BPF_CFLAGS) \ + -Wall \ + -Wno-unused-value \ + -Wno-pointer-sign \ + -Wno-compare-distinct-pointer-types \ + -Werror \ + -O2 -emit-llvm -c -g -o ${@:.o=.ll} $< + $(QUIET_LLC)$(LLC) -march=bpf -filetype=obj -o $@ ${@:.o=.ll} + + $(PROJ_CLEAN): @echo; echo $@; $(MAKE) -C $(subst _clean,,$@) clean @@ -51,4 +167,3 @@ check_submodule: echo " consider running: git submodule update" ;\ echo "" ;\ fi\ - diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/bpf_use_errno_test.o b/eBPF_Supermarket/Network_Subsystem/net_manager/bpf_use_errno_test.o deleted file mode 100644 index 77fad42d6..000000000 Binary files a/eBPF_Supermarket/Network_Subsystem/net_manager/bpf_use_errno_test.o and /dev/null differ diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/common/common_params.c b/eBPF_Supermarket/Network_Subsystem/net_manager/common/common_params.c index 0bfafedff..7233919ff 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/common/common_params.c +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/common/common_params.c @@ -213,7 +213,7 @@ void parse_cmdline_args(int argc, char **argv, goto error; } // 设置文件路径 - cfg->mac_filter_file = (char *)&cfg->mac_filter_file_buf; //初始化ip_filter_file + cfg->mac_filter_file = (char *)&cfg->mac_filter_file_buf; //初始化mac_filter_file strncpy(cfg->mac_filter_file, optarg, FILE_MAXSIZE); break; case 'k': @@ -224,7 +224,7 @@ void parse_cmdline_args(int argc, char **argv, goto error; } // 设置文件路径 - cfg->router_file = (char *)&cfg->router_file_buf; //初始化ip_filter_file + cfg->router_file = (char *)&cfg->router_file_buf; //初始化router_file strncpy(cfg->router_file, optarg, FILE_MAXSIZE); break; case 'g': diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/common_kern_user.h b/eBPF_Supermarket/Network_Subsystem/net_manager/common_kern_user.h similarity index 86% rename from eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/common_kern_user.h rename to eBPF_Supermarket/Network_Subsystem/net_manager/common_kern_user.h index c146b8528..11f3173b5 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/common_kern_user.h +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/common_kern_user.h @@ -46,7 +46,18 @@ struct rules_ipv4 { __u16 next_rule; }; +struct conn_mac { + unsigned char dest[ETH_ALEN]; + unsigned char source[ETH_ALEN]; +}; +struct rules_mac { + unsigned char dest[ETH_ALEN]; + unsigned char source[ETH_ALEN]; + __u16 action; + __u16 prev_rule; + __u16 next_rule; +}; // 转发表项 struct rt_item { __u32 saddr; diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/black_ipv4.conf b/eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/black_ipv4.conf similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/black_ipv4.conf rename to eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/black_ipv4.conf diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/mac_load.conf b/eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/mac_load.conf new file mode 100644 index 000000000..b4a92a3d9 --- /dev/null +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/mac_load.conf @@ -0,0 +1,3 @@ +00:0c:29:57:00:4d 00:00:00:00:00:00 ALLOW +00:0c:29:00:00:00 00:00:00:00:00:00 DENY +00:00:00:00:00:00 00:00:00:00:00:00 ALLOW \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/router_load.conf b/eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/router_load.conf similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/router_load.conf rename to eBPF_Supermarket/Network_Subsystem/net_manager/conf.d/router_load.conf diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter1.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter1.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter1.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter1.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter2.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter2.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter2.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter2.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter3.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter3.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter3.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter3.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter4.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter4.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/ip_filter4.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/ip_filter4.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter1.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter1.png new file mode 100644 index 000000000..db204dbe4 Binary files /dev/null and b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter1.png differ diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter2.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter2.png new file mode 100644 index 000000000..6d7d20631 Binary files /dev/null and b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter2.png differ diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter3.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter3.png new file mode 100644 index 000000000..a875fa4d2 Binary files /dev/null and b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter3.png differ diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter4.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter4.png new file mode 100644 index 000000000..28ca9a380 Binary files /dev/null and b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/mac_filter4.png differ diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager1.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager1.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager1.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager1.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager2.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager2.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager2.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager2.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager3.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager3.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager3.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager3.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager4.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager4.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager4.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager4.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager5.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager5.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager5.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager5.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager6.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager6.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager6.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager6.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager7.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager7.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager7.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager7.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager8.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager8.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/net_manager8.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/net_manager8.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/session_keep1.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/session_keep1.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/session_keep1.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/session_keep1.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/session_keep2.png b/eBPF_Supermarket/Network_Subsystem/net_manager/document/image/session_keep2.png similarity index 100% rename from eBPF_Supermarket/Network_Subsystem/net_manager/document/pic/session_keep2.png rename to eBPF_Supermarket/Network_Subsystem/net_manager/document/image/session_keep2.png diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/ip_filter.md b/eBPF_Supermarket/Network_Subsystem/net_manager/document/ip_filter.md index 1d6b7bb7d..63d339e63 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/document/ip_filter.md +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/document/ip_filter.md @@ -6,7 +6,7 @@ ### 实现 -![image-20240726104526418](./pic/ip_filter1.png) +![image-20240726104526418](./image/ip_filter1.png) #### 输入参数优化 @@ -25,7 +25,7 @@ 因此其使用的方法十分固定,要求路径必须在相应的位置,如: ``` -sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t +sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t ``` 将其绑定到-i参数上 @@ -40,7 +40,7 @@ strncpy(cfg->ip_filter_file, optarg, FILE_MAXSIZE); 去掉这种限制 ``` -sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t +sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t ``` #### 增添输出格式 @@ -52,7 +52,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con 本功能的使用命令为 ``` -sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf +sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf ``` 也可以在其中加入-t/T选项,t参数会定时统计所有策略对应的报文数,T参数会输出所有匹配条目与策略 @@ -63,7 +63,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con sudo xdp-loader status ``` -![image-20240726114124092](./pic/ip_filter2.png) +![image-20240726114124092](./image/ip_filter2.png) 其中可以看到对应网卡上挂载的XDP程序 @@ -131,7 +131,7 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con 可以发现已经drop了所有报文 -![image-20240726110021447](./pic/ip_filter3.png) +![image-20240726110021447](./image/ip_filter3.png) ### 输出分析 @@ -144,6 +144,6 @@ sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.con sudo cat /sys/kernel/debug/tracing/trace_pipe ``` -![image-20240726153912838](./pic/ip_filter4.png) +![image-20240726153912838](./image/ip_filter4.png) 其中可以看到符合匹配的相关报文信息,其中包括四元组、协议类型、XDP策略行为以及匹配条目的序号。 \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/mac_filter.md b/eBPF_Supermarket/Network_Subsystem/net_manager/document/mac_filter.md new file mode 100644 index 000000000..ec11fc7ec --- /dev/null +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/document/mac_filter.md @@ -0,0 +1,116 @@ +## MAC过滤 + +### 概述 + +​ 本工具通过XDP技术,在内核层实现了高效的MAC地址过滤,专注于基于设备物理地址的流量控制。MAC地址过滤能够在网络层面上直接识别和控制特定设备的访问权限,无需依赖上层协议的验证机制。通过配置特定设备的MAC地址黑白名单,能够有效防止未经授权的设备接入网络,确保网络安全性。 + +其主要应用在于 + +1. **硬件级别过滤**: MAC地址是网络接口卡的唯一标识,不会像IP地址那样频繁变化,因此在底层网络设备上做过滤更有效。 +2. **物理位置绑定**: 在局域网中,MAC地址通常和设备物理位置绑定,有助于对物理设备进行精确控制。 +3. **隔离内外网**:通过限制外部设备基于MAC地址接入本地网络,可以强化内外网隔离的策略,从而间接提高内部网络的安全性。 + +MAC地址仅在局域网中有效,跨路由器的网络(如广域网)无法通过MAC地址进行过滤 + +### 实现 + +总体框架流程如下: + +![image-20240825133247633](./image/mac_filter1.png) + +具体匹配策略如下: + +```c +int mac_match(__u8 *conn_mac, __u8 *rule_mac) { + __u8 zero_mac[ETH_ALEN] = {0}; // 全零的MAC地址 + + // 如果rule_mac全为零,匹配所有MAC地址 + if (bpf_memcmp(rule_mac, zero_mac, ETH_ALEN) == 0) { + return 1; + } + + // 如果rule_mac的后三个字节为零,且前三个字节与conn_mac相同 + if (bpf_memcmp(&rule_mac[3], zero_mac, 3) == 0) { + if (bpf_memcmp(conn_mac, rule_mac, 3) == 0) { + return 1; // 匹配前三字节 + } + } + + // 检查规则MAC与连接MAC是否完全匹配 + if (bpf_memcmp(rule_mac, conn_mac, ETH_ALEN) == 0) { + return 1; // 完全匹配 + } + + return 0; // 不匹配 +} +``` + +### 使用方法 + +本功能的使用命令为 + +```c +sudo ./netmanager -d ens33 -S --progname=xdp_entry_mac -m conf.d/mac_load.conf -t +``` + +之后可以使用xdp-loader查看挂载程序及卸载 + +在 ./conf.d 目录里有样例规则文件 mac_load.conf 代表条目名单。程序会按顺序逐行加载进BPF Map,同样,XDP程序执行时也会逐行匹配规则,所以写在前面的规则具有更高的优先级。每行规则的格式为: + +``` +[SOURCE_MAC] [DEST_MAC] [ALLOW/DENY] +``` + +其中分别为源MAC地址、目的MAC地址及条目策略。 + +需要注意,**XDP只对收包路径上的数据有效,因此此处的源为另一端,而目的为本机**。 + +**当某段字段为0时,代表不进行此处的过滤,为全部匹配**。 + +若要实现黑名单,根据匹配的优先级顺序,则需要在规则的最后⼀条写上(也可不加),默认为ALLOW,当匹配不到其余规则时会默认进行PASS策略(但仍建议增添) + +```c +00:00:00:00:00:00 00:00:00:00:00:00 ALLOW +``` + +若要实现白名单,需要将最后⼀条规则写为(必须增添,否则没有实际效果) + +```c +00:00:00:00:00:00 00:00:00:00:00:00 DENY +``` + +我们还对某一厂商的MAC地址进行泛化匹配,当前三字节不为0(固定厂商)且后三字节为0时,可以对其进行泛化,匹配到所有改厂商的MAC地址,如 + +``` +00:0c:29:00:00:00 00:00:00:00:00:00 ALLOW +``` + +最终给出实例,我们在规则配置文件中写入 + +```c +00:0c:29:57:00:4d 00:00:00:00:00:00 ALLOW +00:0c:29:00:00:00 00:00:00:00:00:00 DENY +00:00:00:00:00:00 00:00:00:00:00:00 ALLOW +``` + +其中,00:0c:29开头的MAC地址是VMware虚拟网卡固定分配的前缀 + +之后加载到程序中 + +```shell +sudo ./netmanager -d ens33 -S --progname=xdp_entry_mac -m conf.d/mac_load.conf -t +``` + +之后通过不同虚拟机使用ping/curl来连接该主机 + +当MAC地址为00:0c:29:57:00:4d(特定主机),其可以正常连接 + +![image-20240825132436960](./image/mac_filter2.png) + +而其余虚拟机进行访问时会被拒绝 + +![image-20240825132526078](./image/mac_filter3.png) + +可以看到,相应报文已经被DROP + +![image-20240825132551308](./image/mac_filter4.png) \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/net_manager.md b/eBPF_Supermarket/Network_Subsystem/net_manager/document/net_manager.md index b6ff8fd10..969c6c49a 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/document/net_manager.md +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/document/net_manager.md @@ -6,7 +6,7 @@ netmanager是一款基于 eBPF 技术的高效网络管理工具,核心技术 目前netmanager的整体框架为 -![image-20240711091259144](./pic/net_manager1.png) +![image-20240711091259144](./image/net_manager1.png) @@ -70,23 +70,23 @@ netmanager目前实现了过滤、转发、统计信息和会话保持四大功 ```c 黑白名单:加载到本地链路 ens33 上 - sudo ./xdp_loader -d ens33 --progname=xdp_entry_state -S + sudo ./netmanager -d ens33 --progname=xdp_entry_state -S 会话保持: - sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf + sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf ``` **以会话保持为例** -![image-20240711110643737](./pic/net_manager2.png) +![image-20240711110643737](./image/net_manager2.png) 可以借助xdp-loader工具进行操作 -![image-20240711110713174](./pic/net_manager3.png) +![image-20240711110713174](./image/net_manager3.png) 可以看到我们的程序被挂载到相应的端口上 -![image-20240711110826395](./pic/net_manager4.png) +![image-20240711110826395](./image/net_manager4.png) 可以看到其能抓到本机网络通信的各个报文,并获取其中的基本信息和连接状态。 @@ -133,18 +133,18 @@ netmanager目前实现了过滤、转发、统计信息和会话保持四大功 之后加载到程序中 ```bash -sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t +sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t ``` 之后加载到程序中 ```bash -sudo ./xdp_loader -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t +sudo ./netmanager -d ens33 -S --progname=xdp_entry_ipv4 -i conf.d/black_ipv4.conf -t ``` 统计信息如下 -![image-20240715202110387](./pic/net_manager5.png) +![image-20240715202110387](./image/net_manager5.png) 可以发现已经drop了所有icmp报文 @@ -194,7 +194,7 @@ sudo xdp-loader unload ens33 --all ### Makefile结构 -![image-20240711102520620](./pic/net_manager6.png) +![image-20240711102520620](./image/net_manager6.png) 为递归make,尝试修改,较为困难 @@ -202,8 +202,8 @@ sudo xdp-loader unload ens33 --all 主用户态代码 -![image-20240711105855149](./pic/net_manager7.png) +![image-20240711105855149](./image/net_manager7.png) ### ./net_manager/xdp_prog_kern.c -![image-20240711110039806](./pic/net_manager8.png) \ No newline at end of file +![image-20240711110039806](./image/net_manager8.png) \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/document/session_keep.md b/eBPF_Supermarket/Network_Subsystem/net_manager/document/session_keep.md index eacfdbf26..1cea057c2 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/document/session_keep.md +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/document/session_keep.md @@ -10,7 +10,7 @@ 其在lo网卡上监测的信息 -![image-20240719173203213](./pic/session_keep1.png) +![image-20240719173203213](./image/session_keep1.png) 增加对通用网卡的监测,UDP、ICMP的监测,输出格式的转化,但由于XDP仅在收包路径,所以发送报文/相关状态获取不到 @@ -19,13 +19,13 @@ 使用命令将程序挂载到相应网卡 ```c -sudo ./xdp_loader -d ens33 --progname=xdp_entry_state -S +sudo ./netmanager -d ens33 --progname=xdp_entry_state -S ``` 查看挂载程序 ``` -sudo ./xdp_loader status +sudo xdp-loader status ``` 查看输出 @@ -36,7 +36,7 @@ sudo cat /sys/kernel/debug/tracing/trace_pipe 实例截图 -![image-20240719173840908](./pic/session_keep2.png) +![image-20240719173840908](./image/session_keep2.png) 进行卸载 diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/Makefile b/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/Makefile deleted file mode 100644 index e29a040e9..000000000 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) - -XDP_TARGETS := xdp_prog_kern -USER_TARGETS := xdp_loader - -COMMON_DIR = ../common - -# Extend with another COMMON_OBJS -COMMON_OBJS += $(COMMON_DIR)/common_user_bpf_xdp.o - - -EXTRA_DEPS := $(COMMON_DIR)/parsing_helpers.h - -include $(COMMON_DIR)/common.mk diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/mac_load.conf b/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/mac_load.conf deleted file mode 100644 index 3b41e21a5..000000000 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/conf.d/mac_load.conf +++ /dev/null @@ -1,2 +0,0 @@ -00:0c:29:dd:17:2c DENY -00:0c:29:fd:69:58 DENY \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_loader.c b/eBPF_Supermarket/Network_Subsystem/net_manager/netmanager.c similarity index 92% rename from eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_loader.c rename to eBPF_Supermarket/Network_Subsystem/net_manager/netmanager.c index 288c1f178..dcec95697 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_loader.c +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/netmanager.c @@ -22,12 +22,12 @@ static const char *__doc__ = "XDP loader\n" #include #include /* depend on kernel-headers installed */ -#include "../common/common_params.h" -#include "../common/common_user_bpf_xdp.h" -#include "../common/common_libbpf.h" +#include "./common/common_params.h" +#include "./common/common_user_bpf_xdp.h" +#include "./common/common_libbpf.h" #include "common_kern_user.h" -static const char *default_filename = "xdp_prog_kern.o"; +static const char *default_filename = "netmanager_kern.o"; static const char *default_progname = "xdp_entry_state"; static const struct option_wrapper long_options[] = { @@ -316,7 +316,7 @@ int pin_maps_in_bpf_object(struct bpf_object *bpf_obj) char *ifname; int rules_ipv4_map; int rtcache_map4; -int src_macs; +int rules_mac_map; int print_usage(int id){ switch(id){ @@ -362,7 +362,7 @@ int open_map(const char *ifname, const char *map_name){ int load_bpf_map(){ rules_ipv4_map = open_map(ifname, "rules_ipv4_map"); rtcache_map4 = open_map(ifname, "rtcache_map4"); - src_macs = open_map(ifname, "src_macs"); + rules_mac_map = open_map(ifname, "rules_mac_map"); // Check if any map failed to open if (rules_ipv4_map < 0) { fprintf(stderr, "Failed to open rules_ipv4_map\n"); @@ -370,11 +370,11 @@ int load_bpf_map(){ if (rtcache_map4 < 0) { fprintf(stderr, "Failed to open rtcache_map4\n"); } - if (src_macs < 0) { - fprintf(stderr, "Failed to open src_macs\n"); + if (rules_mac_map < 0) { + fprintf(stderr, "Failed to open rules_mac_map\n"); } - if (rules_ipv4_map < 0 || rtcache_map4 < 0 || src_macs < 0) { + if (rules_ipv4_map < 0 || rtcache_map4 < 0 || rules_mac_map < 0) { fprintf(stderr, "load bpf map error, check device name\n"); return -1; } @@ -405,7 +405,7 @@ int clear_map(){ bpf_map_delete_batch(rules_ipv4_map, &keys, &count, &opts); bpf_map_delete_batch(rtcache_map4, &keys, &count, &opts); - bpf_map_delete_batch(src_macs, &keys, &count, &opts); + bpf_map_delete_batch(rules_mac_map, &keys, &count, &opts); return count; } @@ -576,38 +576,61 @@ int load_handler_mac(char* mac_filter_file){ perror("Error opening file"); return 1; } + __u16 keys[MAX_RULES]; + struct rules_mac rules[MAX_RULES]; + __u32 i = 1; + keys[0] = 0; - //__u64 src_mac_u64; - __u32 action_mac; char line[256]; - - clear_map(); + printf("-----------------------------------------------------------------------------------------------\n"); + while (fgets(line, sizeof(line), file) != NULL) { line[strcspn(line, "\n")] = '\0'; __u8 src_mac[6]; + __u8 dest_mac[6]; char action[10]; - sscanf(line, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %s", + sscanf(line, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhx:%hhx:%hhx:%hhx:%hhx:%hhx %s", &src_mac[0], &src_mac[1], &src_mac[2], &src_mac[3], &src_mac[4], &src_mac[5], + &dest_mac[0], &dest_mac[1], &dest_mac[2], &dest_mac[3], &dest_mac[4], &dest_mac[5], action); //src_mac_u64 = mac_to_u64(src_mac); - printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x, Action: %s\n", - src_mac[0], src_mac[1], src_mac[2], - src_mac[3], src_mac[4], src_mac[5], action); + memcpy(rules[i].source, src_mac, ETH_ALEN); + memcpy(rules[i].dest, dest_mac, ETH_ALEN); if(strcmp("ALLOW", action) == 0){ - action_mac = XDP_PASS; + rules[i].action = XDP_PASS; }else if(strcmp("DENY", action) == 0){ - action_mac = XDP_DROP; + rules[i].action = XDP_DROP; }else{ - action_mac = XDP_ABORTED; + rules[i].action = XDP_ABORTED; } - bpf_map_update_elem(src_macs, src_mac, &action_mac, BPF_ANY); + rules[i-1].next_rule = i; + rules[i].prev_rule = i - 1; + rules[i].next_rule = 0; + keys[i] = i; + + printf("MAC_SRC: %02x:%02x:%02x:%02x:%02x:%02x, MAC_DEST: %02x:%02x:%02x:%02x:%02x:%02x ,Action: %s\n", + src_mac[0], src_mac[1], src_mac[2],src_mac[3], src_mac[4], src_mac[5], + dest_mac[0], dest_mac[1], dest_mac[2],dest_mac[3], dest_mac[4], dest_mac[5], + action); + + i += 1; } + printf("-----------------------------------------------------------------------------------------------\n"); + printf("%d rules loaded\n",i-1); + rules[0].prev_rule = i - 1; + + DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts, + .elem_flags = 0, + .flags = 0, + ); + clear_map(); + bpf_map_update_batch(rules_mac_map, keys, rules, &i, &opts); return 0; } @@ -634,7 +657,6 @@ int main(int argc, char **argv) int len; // 字符串长度 char errmsg[1024]; // 错误消息字符串 - // 配置结构体,包括XDP模式、接口索引、是否卸载程序以及程序名称等信息 struct config cfg = { .attach_mode = XDP_MODE_NATIVE, diff --git a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_prog_kern.c b/eBPF_Supermarket/Network_Subsystem/net_manager/netmanager_kern.c similarity index 76% rename from eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_prog_kern.c rename to eBPF_Supermarket/Network_Subsystem/net_manager/netmanager_kern.c index 509e3e595..42d02abac 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_manager/net_manager/xdp_prog_kern.c +++ b/eBPF_Supermarket/Network_Subsystem/net_manager/netmanager_kern.c @@ -5,7 +5,7 @@ #include #include "common_kern_user.h" -#include "../common/parsing_helpers.h" +#include "./common/parsing_helpers.h" #ifndef memcpy #define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) @@ -42,6 +42,13 @@ struct { __uint(max_entries, MAX_RULES); } rules_ipv4_map SEC(".maps"); +// mac—filter +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u16); + __type(value, struct rules_mac); + __uint(max_entries, MAX_RULES); +} rules_mac_map SEC(".maps"); // router struct { @@ -59,16 +66,6 @@ struct { __uint(max_entries, MAX_RULES); } rtcache_map4 SEC(".maps"); - -/*filter-pass-drop*/ -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, ETH_ALEN); - __type(value, __u32); - __uint(max_entries, MAX_RULES); -} src_macs SEC(".maps"); - - // 会话保持 struct { __uint(type, BPF_MAP_TYPE_HASH); @@ -213,7 +210,7 @@ static int match_rules_ipv4_loop(__u32 index, void *ctx) if(index == 0) goto out_match_rules_ipv4_loop; - //bpf_printk("match_rules_ipv4_loop %d",index); + bpf_printk("match_rules_ipv4_loop %d",index); if( ipv4_cidr_match(p_ctx->conn->saddr, p_r->saddr, p_r->saddr_mask) && ipv4_cidr_match(p_ctx->conn->daddr, p_r->daddr, p_r->daddr_mask) && port_match(p_ctx->conn->sport, p_r->sport) && @@ -328,7 +325,7 @@ int xdp_entry_ipv4(struct xdp_md *ctx) /* Solution to packet03/assignment-4 */ SEC("xdp") -int xdp_entry_router(struct xdp_md *ctx) +int xdp_entry_router1(struct xdp_md *ctx) { xdp_act action = XDP_PASS; void *data_end = (void *)(long)ctx->data_end; @@ -368,7 +365,7 @@ int xdp_entry_router(struct xdp_md *ctx) nitem.saddr = ip4_saddr; // 首先精确查找转发表,如果找到就直接转发,不必再经历最长前缀匹配的慢速通配查找 - match_rules(&nitem); + match_rules(&nitem);//rtcache_map4 @@ -476,6 +473,92 @@ int xdp_entry_router(struct xdp_md *ctx) return xdp_stats_record_action(ctx, action); } +struct match_rules_loop_mac_ctx{ + __u16 action; + __u16 next_rule; + struct conn_mac *conn; +}; + +static inline int bpf_memcmp(const void *a, const void *b, size_t len) { + const unsigned char *p1 = a; + const unsigned char *p2 = b; + size_t i; + + for (i = 0; i < len; i++) { + if (p1[i] != p2[i]) { + return p1[i] - p2[i]; + } + } + return 0; +} +static __always_inline +int mac_match(__u8 *conn_mac, __u8 *rule_mac) { + __u8 zero_mac[ETH_ALEN] = {0}; // 全零的MAC地址 + + // 如果rule_mac全为零,匹配所有MAC地址 + if (bpf_memcmp(rule_mac, zero_mac, ETH_ALEN) == 0) { + return 1; + } + + // 如果rule_mac的后三个字节为零,且前三个字节与conn_mac相同 + if (bpf_memcmp(&rule_mac[3], zero_mac, 3) == 0) { + if (bpf_memcmp(conn_mac, rule_mac, 3) == 0) { + return 1; // 匹配前三字节 + } + } + + // 检查规则MAC与连接MAC是否完全匹配 + if (bpf_memcmp(rule_mac, conn_mac, ETH_ALEN) == 0) { + return 1; // 完全匹配 + } + + return 0; // 不匹配 +} + + +static int match_rules_mac_loop(__u32 index, void *ctx) +{ + struct match_rules_loop_mac_ctx *p_ctx = (struct match_rules_loop_mac_ctx *)ctx; + if(index != p_ctx->next_rule) + return 0; + struct rules_mac *p_r = bpf_map_lookup_elem(&rules_mac_map, &index); + if(!p_r){ + return 1; //out of range + } + p_ctx->next_rule = p_r->next_rule; + + if(index == 0) + goto out_match_rules_mac_loop; + //bpf_printk("match_rules_ipv4_loop %d",index); + // bpf_printk("MAC_SRC: %02x:%02x:%02x:%02x:%02x:%02x\n",p_r->source[0], p_r->source[1], p_r->source[2],p_r->source[3], p_r->source[4], p_r->source[5]); + // bpf_printk("MAC_DEST: %02x:%02x:%02x:%02x:%02x:%02x ,Action: %d\n",p_r->dest[0], p_r->dest[1], p_r->dest[2],p_r->dest[3], p_r->dest[4], p_r->dest[5], + // p_r->action); + if(mac_match(p_ctx->conn->dest, p_r->dest)&&mac_match(p_ctx->conn->source, p_r->source)) + { + p_ctx->action = p_r->action; + return 1; + } + +out_match_rules_mac_loop: + if(p_r->next_rule == 0) + return 1; //go out loop + + return 0; +} + +static __always_inline +xdp_act match_rules_mac(struct conn_mac *conn) +{ + struct match_rules_loop_mac_ctx ctx = {.action = XDP_PASS, .conn = conn, .next_rule = 0}; + + + for(int i=0; ih_source); - /* check if src mac is in src_macs map */ - value = bpf_map_lookup_elem(&src_macs, eth->h_source); - if (value) { - action = *value; - goto out; + // /* check if src mac is in src_macs map */ + // value = bpf_map_lookup_elem(&src_macs, eth->h_source); + // if (value) { + // action = *value; + // goto out; + // } + for (int i = 0; i < ETH_ALEN; i++) { + conn.source[i] = eth->h_source[i]; + conn.dest[i] = eth->h_dest[i]; } - + action = match_rules_mac(&conn); out: return xdp_stats_record_action(ctx, action); @@ -705,11 +793,105 @@ int xdp_entry_state(struct xdp_md *ctx) } -SEC("xdp") -int test(struct xdp_md *ctx) +// 最简单的一个转发表项 +struct rt_item_tab{ + int ifindex; // 转发出去的接口 + char eth_source[ETH_ALEN]; // 封装帧的源MAC地址。 + char eth_dest[ETH_ALEN]; // 封装帧的目标MAC地址。 +}; + +// 路由转发表缓存 +struct { + __uint(type, BPF_MAP_TYPE_LRU_HASH); + __type(key, __u32); + __type(value, struct rt_item_tab); + __uint(max_entries, MAX_RULES); +} rtcache_map SEC(".maps"); +// 递减TTL还是要的 +static __always_inline int __ip_decrease_ttl(struct iphdr *iph) { - bpf_printk("1111111111 test\n"); - return XDP_PASS; + __u32 check = iph->check; + check += bpf_htons(0x0100); + iph->check = (__u16)(check + (check >= 0xFFFF)); + return --iph->ttl; } +// 字节码的C程序本身 +SEC("xdp") +int xdp_entry_router(struct xdp_md *ctx) +{ + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + struct bpf_fib_lookup ifib; + struct ethhdr *eth = data; + struct iphdr *iph; + struct rt_item_tab *pitem = NULL; + unsigned int daddr = 0; + __u16 h_proto; + __u64 nh_off; + char fast_info[] = "Fast path to [%d]\n"; + char slow_info[] = "Slow path to [%d]\n"; + int action = XDP_DROP; + nh_off = sizeof(*eth); + if (data + nh_off > data_end) { + return XDP_DROP; + } + + __builtin_memset(&ifib, 0, sizeof(ifib)); + h_proto = eth->h_proto; + if (h_proto != bpf_htons(ETH_P_IP)) { + return XDP_PASS; + } + + iph = data + nh_off; + + if (iph + 1 > data_end) { + return XDP_DROP; + } + + daddr = iph->daddr; + + pitem = bpf_map_lookup_elem(&rtcache_map, &daddr); + // 首先精确查找转发表,如果找到就直接转发,不必再经历最长前缀匹配的慢速通配查找 + // 这个动作是可以offload到硬件中的。 + if (pitem) { + __ip_decrease_ttl(iph); + memcpy(eth->h_dest, pitem->eth_dest, ETH_ALEN); + memcpy(eth->h_source, pitem->eth_source, ETH_ALEN); + bpf_printk("%s----daddr : %d prot:%d",fast_info,daddr,pitem->ifindex); + //bpf_trace_printk(fast_info, sizeof(fast_info), pitem->ifindex); + action = bpf_redirect(pitem->ifindex, 0); + goto out; + } + // 否则只能执行最长前缀匹配了 + ifib.family = AF_INET; + ifib.tos = iph->tos; + ifib.l4_protocol = iph->protocol; + ifib.tot_len = bpf_ntohs(iph->tot_len); + ifib.ipv4_src = iph->saddr; + ifib.ipv4_dst = iph->daddr; + ifib.ifindex = ctx->ingress_ifindex; + + // 调用eBPF封装的路由查找函数,虽然所谓慢速查找,也依然不会进入协议栈的。 + if (bpf_fib_lookup(ctx, &ifib, sizeof(ifib), 0) == 0) { + struct rt_item_tab nitem; + + __builtin_memset(&nitem, 0, sizeof(nitem)); + memcpy(&nitem.eth_dest, ifib.dmac, ETH_ALEN); + memcpy(&nitem.eth_source, ifib.smac, ETH_ALEN); + nitem.ifindex = ifib.ifindex; + // 插入新的表项 + bpf_map_update_elem(&rtcache_map, &daddr, &nitem, BPF_ANY); + __ip_decrease_ttl(iph); + memcpy(eth->h_dest, ifib.dmac, ETH_ALEN); + memcpy(eth->h_source, ifib.smac, ETH_ALEN); + bpf_printk("%s----daddr : %d prot:%d",slow_info,daddr,nitem.ifindex); + //bpf_trace_printk(slow_info, sizeof(slow_info), ifib.ifindex); + action = bpf_redirect(ifib.ifindex, 0); + goto out; + } + action = XDP_PASS; +out: + return xdp_stats_record_action(ctx, action); +} char _license[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h index b7e775a8a..4e92f5633 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h @@ -633,4 +633,4 @@ static __always_inline u64 log2l(u64 v) { } /* help functions end */ -#endif +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c index 263459c7c..7c409a890 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c @@ -1569,4 +1569,4 @@ int main(int argc, char **argv) { cleanup: netwatcher_bpf__destroy(skel); return err < 0 ? -err : 0; -} +} \ No newline at end of file diff --git a/eBPF_Supermarket/eBPF_Performance_Analysis/README.md b/eBPF_Supermarket/eBPF_Performance_Analysis/README.md new file mode 100644 index 000000000..5a3944280 --- /dev/null +++ b/eBPF_Supermarket/eBPF_Performance_Analysis/README.md @@ -0,0 +1,54 @@ +# eBPF多维度分析 +## 一、简介 + +​ **eBPF(扩展伯克利数据包过滤器)** 是一项革命性技术,允许在内核态执行用户定义的程序。这些程序可以在内核中安全高效地运行,而无需更改内核源代码,从而实现了对系统行为的深度观察和实时调整。eBPF在网络、安全、监控、性能调优等领域有着广泛的应用。通过eBPF实现高效的数据包过滤和流量分析,优化网络性能。例如,Cilium利用eBPF技术提供可伸缩的网络和安全性,特别适用于Kubernetes和其他云原生环境。通过内核态的性能数据收集和分析,发现系统瓶颈并进行优化。eBPF可以用于捕捉各种性能指标,如CPU使用率、内存使用情况等,从而提供深度的性能分析。eBPF可以无缝地插入内核代码路径,提供详细的性能监测功能。它能够实时收集详细的性能数据,帮助系统管理员和开发者识别并解决性能瓶颈。eBPF可以用于监测容器的资源使用情况,包括CPU、内存、网络等方面的数据。通过与Prometheus等监控工具集成,eBPF可以提供精细的容器监控数据,帮助运维人员更好地管理和优化容器化应用。 + +​ 尽管eBPF在网络、安全、监控、性能调优等领域展现了巨大的潜力和广泛的应用,但目前业界对eBPF本身的性能分析和优化研究仍然不足。因此,本次研究的目的在于通过系统化的性能评估和对比分析,深入探索eBPF在不同使用场景下的表现,特别是对比在不同负载的情境下eBPF中不同类型的map、不同挂载点的性能差异、不同内核版本的使用差异。通过编写和运行各种测试程序,我们将全面分析eBPF在实际操作中的效率和性能瓶颈。最终,基于这些数据,提出针对不同应用场景的最佳实践指导,帮助开发者和运维人员更高效地利用eBPF技术,从而推动eBPF在业界的深入应用和发展。 + +## 二、测试目的 + +​ 我的研究旨在通过系统化的性能评估和对比分析,全面评估和优化eBPF(扩展伯克利数据包过滤器)的性能。具体而言,我们希望深入探索eBPF在各种使用场景下的性能表现,包括比较不同类型的映射(map)、分析不同挂载点的性能差异,以及评估不同内核版本的影响。通过编写和执行一系列测试程序,我们的目标是深入了解eBPF的操作效率,并识别潜在的性能瓶颈。最终,我们将根据研究结果提出针对特定应用场景的最佳实践指南,推动eBPF技术在各行业的应用和发展。 + +## 三、测试方案: +[理论分析.md](./docs/Map理论分析.md) + +[测试方案.md](./docs/eBPF性能测试方案.md) + +## 四、工具使用说明: + +### 1.环境准备: + +1.1ebpf运行环境: + +```shell +#在eBPF_Performance_Analysis/目录下执行指令: +make deps +``` + +1.2python环境: + +```shell +#下载python3 +sudo apt install python3 +#检查是否下载成功: +python3 --version +#下载pandas库 +sudo pip3 install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple +#下载matplotlib库 +pip3 install matplotlib +``` + +2.运行: + +```shell +#在eBPF_Performance_Analysis/目录下运行shell脚本: +#此脚本用来比较不同Map类型在时间层面进行增删改查操作的差异 +sudo bash run_ebpf_and_process.sh +``` +3.结果: + +```shell +#运行结束后,程序会生成python工具分析后的图像文件 +``` + + diff --git "a/eBPF_Supermarket/eBPF_Performance_Analysis/docs/Map\347\220\206\350\256\272\345\210\206\346\236\220.md" "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/Map\347\220\206\350\256\272\345\210\206\346\236\220.md" new file mode 100644 index 000000000..47462cb11 --- /dev/null +++ "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/Map\347\220\206\350\256\272\345\210\206\346\236\220.md" @@ -0,0 +1,381 @@ +# Hashmap和Arraymap对比测试 + +测试之前,先对hashmap和arraymap进行理论上的分析: + +## 一、理论分析 + +**HashMap:** + +- 在eBPF中,HashMap实际上是一个哈希表,用于将键映射到值。它使用哈希函数来计算键的哈希值,并将其映射到一个存储桶(bucket)中。 +- 哈希表内部由一个数组(buckets)和链表(或者是红黑树)组成。数组中的每个元素是一个链表头或树的根节点,用于处理哈希冲突。 +- HashMap在eBPF中可以动态调整大小,这意味着它可以根据需要动态增长或缩小。这一点是通过在哈希表达到负载因子阈值时重新分配更大的存储空间来实现的。 +- 在eBPF的内核代码中,HashMap的实现涉及到哈希函数的选择和哈希冲突的处理。 +- 适合在运行时需要动态添加、删除键值对的场景。 +- 适合快速查找特定键对应的值,复杂度为 O(1)。 + +**1.Hashmap的查找元素源码:(/kernel/bpf/hashtab.c)** + +```c +/* + * 函数: __htab_map_lookup_elem + * ---------------------------- + * 此函数用于在 eBPF 程序或系统调用上下文中查找 HashTable Map 中的元素。 + * 根据提供的键查找并返回对应的元素。 + * + * 参数: + * - map: 指向 BPF map(bpf_map)基本结构的指针。 + * - key: 用于在 HashTable Map 中定位元素的键的指针。 + * + * 返回: + * - 成功时返回指向查找到的元素的指针;如果未找到则返回 NULL。 + */ + +static void *__htab_map_lookup_elem(struct bpf_map *map, void *key) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + struct hlist_nulls_head *head; + struct htab_elem *l; + u32 hash, key_size; + + // 检查是否在 RCU 读取锁定期间执行 + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); + + key_size = map->key_size; // 获取键的大小 + + // 计算键的哈希值 + hash = htab_map_hash(key, key_size, htab->hashrnd); + + // 根据哈希值选择对应的桶 + head = select_bucket(htab, hash); + + // 在选定的桶中查找元素 + l = lookup_nulls_elem_raw(head, hash, key, key_size, htab->n_buckets); + + return l; // 返回查找到的元素指针,如果未找到则返回 NULL +} +``` + +```c +static inline u32 htab_map_hash(const void *key, u32 key_len, u32 hashrnd) +{ + // 如果键的长度是 4 的倍数,使用 jhash2 计算哈希值 + if (likely(key_len % 4 == 0)) + return jhash2(key, key_len / 4, hashrnd); + + // 否则,使用 jhash 计算哈希值 + return jhash(key, key_len, hashrnd); +} +``` + +```c +/* + * 函数: jhash + * ------------ + * 哈希一个任意的键序列。 + * + * 参数: + * - key: 作为键的字节序列的指针。 + * - length: 键的长度(以字节为单位)。 + * - initval: 先前的哈希值,或者一个任意的值作为初始哈希值。 + * + * 返回: + * - 键的哈希值。结果依赖于系统的字节序。 + *这段代码通过对输入的字节序列进行迭代处理,按照特定的算法(包括混合操作和最终化操作)计算出一个哈希值,用 + *于对任意数据进行快速的哈希映射。 + */ + +static inline u32 jhash(const void *key, u32 length, u32 initval) +{ + u32 a, b, c; + const u8 *k = key; + + /* 设置内部状态 */ + a = b = c = JHASH_INITVAL + length + initval; + + /* 处理除最后一个块外的所有块:影响(a, b, c)的32位 */ + while (length > 12) { + a += __get_unaligned_cpu32(k); // 获取未对齐的32位整数 + b += __get_unaligned_cpu32(k + 4); // 获取未对齐的32位整数 + c += __get_unaligned_cpu32(k + 8); // 获取未对齐的32位整数 + __jhash_mix(a, b, c); // 混合操作,影响哈希值 + length -= 12; // 减去处理的字节数 + k += 12; // 指针移动到下一个块 + } + + /* 最后一个块:影响(c)的所有32位 */ + /* 所有 case 语句都会顺序执行 */ + switch (length) { + case 12: c += (u32)k[11]<<24; + case 11: c += (u32)k[10]<<16; + case 10: c += (u32)k[9]<<8; + case 9: c += k[8]; + case 8: b += (u32)k[7]<<24; + case 7: b += (u32)k[6]<<16; + case 6: b += (u32)k[5]<<8; + case 5: b += k[4]; + case 4: a += (u32)k[3]<<24; + case 3: a += (u32)k[2]<<16; + case 2: a += (u32)k[1]<<8; + case 1: a += k[0]; + __jhash_final(a, b, c); // 最终混合和收尾操作 + case 0: /* 没有剩余的字节需要处理 */ + break; + } + + return c; // 返回计算得到的哈希值 +} + +``` + +**2.Hashmap的查找元素源码:(/kernel/bpf/hashtab.c)** + +```c +static long htab_lru_map_delete_elem(struct bpf_map *map, void *key) +{ + // 将 map 转换为包含它的 htab 结构体 + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + + // 定义一个指向 hlist_nulls_head 结构体的指针 head + struct hlist_nulls_head *head; + + // 定义一个指向 bucket 结构体的指针 b + struct bucket *b; + + // 定义一个指向 htab_elem 结构体的指针 l + struct htab_elem *l; + + // 定义一个用于保存标志位的变量 flags + unsigned long flags; + + // 定义一个无符号 32 位整数变量 hash 和 key_size + u32 hash, key_size; + + // 定义一个整数变量 ret 用于保存返回值 + int ret; + + // 检查是否持有 RCU 读锁,如果没有则发出警告 + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); + + // 获取 map 的 key_size + key_size = map->key_size; + + // 计算 key 的 hash 值 + hash = htab_map_hash(key, key_size, htab->hashrnd); + + // 根据 hash 值选择对应的桶 + b = __select_bucket(htab, hash); + + // 获取桶的头部指针 + head = &b->head; + + // 尝试锁定桶,返回值保存在 ret 中 + ret = htab_lock_bucket(htab, b, hash, &flags); + + // 如果锁定失败,则直接返回错误码 + if (ret) + return ret; + + // 在桶中查找与 key 对应的元素 + l = lookup_elem_raw(head, hash, key, key_size); + + // 如果找到了元素,则从链表中删除该元素 + if (l) + hlist_nulls_del_rcu(&l->hash_node); + else + // 如果没有找到元素,则设置返回值为 -ENOENT + ret = -ENOENT; + + // 解锁桶 + htab_unlock_bucket(htab, b, hash, flags); + + // 如果找到了元素,则将其推送到 LRU free 列表 + if (l) + htab_lru_push_free(htab, l); + + // 返回结果 + return ret; +} +``` + +```c +static inline void __hlist_nulls_del(struct hlist_nulls_node *n) +{ + // 获取当前节点的下一个节点 + struct hlist_nulls_node *next = n->next; + + // 获取指向当前节点前一个节点的指针 + struct hlist_nulls_node **pprev = n->pprev; + + // 使用 WRITE_ONCE 宏将当前节点的前一个节点的 next 指针指向当前节点的下一个节点 + WRITE_ONCE(*pprev, next); + + // 如果当前节点的下一个节点不是一个空节点 + if (!is_a_nulls(next)) + // 使用 WRITE_ONCE 宏将下一个节点的前一个节点的指针指向当前节点的前一个节点 + WRITE_ONCE(next->pprev, pprev); +} +``` + +**Arraymap:** + +- ArrayMap是一个数组,其中每个元素存储一个键值对。这种设计使得ArrayMap的存储顺序和插入顺序完全一致。 +- ArrayMap在创建时需要指定最大大小,因为它的大小在运行时是不可变的。 +- ArrayMap的实现比较简单,只需要一个数组和一个计数器。它的插入和查找操作都非常高效,因为它可以直接通过数组索引访问元素。 +- 适合在运行时知道最大键值对数量的场景。 +- 适合需要按照插入顺序进行遍历或处理的场景,因为它的元素存储顺序与插入顺序完全一致。 + +**1.Arraymap的查找元素源码:(/kernel/bpf/arraymap.c)** + +```c +static void *array_map_lookup_elem(struct bpf_map *map, void *key) +{ + /* 将基本的 BPF map 指针转换为特定的 BPF array map 结构 */ + struct bpf_array *array = container_of(map, struct bpf_array, map); + + /* 解引用键指针以获取索引 */ + u32 index = *(u32 *)key; + + /* 检查索引是否超出数组最大条目数 */ + if (unlikely(index >= array->map.max_entries)) + return NULL; + + /* 计算并返回元素地址 */ + return array->value + (u64)array->elem_size * (index & array->index_mask); +} +``` + +**2.Arraymap的插入元素源码:(/kernel/bpf/arraymap.c)** + +```c +static long array_map_update_elem(struct bpf_map *map, void *key, void *value, + u64 map_flags) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + u32 index = *(u32 *)key; // 解引用键指针以获取索引 + char *val; + // 检查是否存在未知标志位 + if (unlikely((map_flags & ~BPF_F_LOCK) > BPF_EXIST)) + return -EINVAL; + // 检查索引是否超出最大条目数限制 + if (unlikely(index >= array->map.max_entries)) + return -E2BIG; + // 检查是否禁止不存在元素的插入 + if (unlikely(map_flags & BPF_NOEXIST)) + return -EEXIST; + // 如果要求使用锁定,并且未定义自旋锁字段,则返回错误 + if (unlikely((map_flags & BPF_F_LOCK) && + !btf_record_has_field(map->record, BPF_SPIN_LOCK))) + return -EINVAL; + // 根据数组类型进行操作分支 + if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { + // 对于 BPF_MAP_TYPE_PERCPU_ARRAY 类型的数组 + val = this_cpu_ptr(array->pptrs[index & array->index_mask]); + copy_map_value(map, val, value); // 复制值到本地 CPU 的指定位置 + bpf_obj_free_fields(array->map.record, val); // 释放对象字段 + } else { + // 对于其他类型的数组 + val = array->value + + (u64)array->elem_size * (index & array->index_mask); + if (map_flags & BPF_F_LOCK) + copy_map_value_locked(map, val, value, false); // 锁定状态下复制值 + else + copy_map_value(map, val, value); // 非锁定状态下复制值 + bpf_obj_free_fields(array->map.record, val); // 释放对象字段 + } + return 0; // 操作成功返回 0 +} +``` + +**3.AraayMap删除元素:(/kernel/bpf/arraymap.c)** + +```c +/* + * 此函数用于在 eBPF 程序或系统调用上下文中删除 ArrayMap 中的元素。 + * 根据提供的键删除 ArrayMap 中的元素,并释放相关资源。 + */ + +static long fd_array_map_delete_elem(struct bpf_map *map, void *key) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + void *old_ptr; + u32 index = *(u32 *)key; + + // 检查索引是否超出最大条目数限制 + if (index >= array->map.max_entries) + return -E2BIG; + + // 如果 map_poke_run 操作存在,则使用 mutex 锁定并执行相关操作 + //当执行特定的 map 操作时(如更新或删除元素),如果该操作涉及到需要额外的处理或者通知机制,就会调用 //map_poke_run 函数来完成这些额外的任务。 + if (map->ops->map_poke_run) { + mutex_lock(&array->aux->poke_mutex); + old_ptr = xchg(array->ptrs + index, NULL); + map->ops->map_poke_run(map, index, old_ptr, NULL); + mutex_unlock(&array->aux->poke_mutex); + } else { + // 否则直接执行元素交换操作 + old_ptr = xchg(array->ptrs + index, NULL); + } + + // 如果成功删除元素,则释放相关资源 + if (old_ptr) { + //在 eBPF 中,文件描述符通常用于操作与内核资源相关的对象,如 bpf_map 中的数据结构。当不再需要 + //这些资源时,就需要调用 map_fd_put_ptr 函数指针所指向的函数,来释放相关的资源或执行清理操作, + //以避免资源泄漏或者内存泄漏问题。 + map->ops->map_fd_put_ptr(old_ptr); + return 0; + } else { + // 如果元素不存在,则返回错误码 -ENOENT + return -ENOENT; + } +} +``` + +## 二、理论分析结果: + +#### **1. Hash Map (`hashmap`)** + +##### **特点:** + +- **数据结构**:基于哈希表实现,每个键值对通过哈希函数来确定其在表中的位置。 +- **查找效率**:通常具有常数时间复杂度(O(1))用于插入、查找和删除操作,但在哈希冲突严重时,性能可能下降。 +- **键值对**:键(key)和值(value)的数据类型可以不同,但键必须是可哈希的。 +- **内存使用**:由于哈希表需要存储哈希桶和链表(或其他结构),内存使用可能较高。 + +#### **适用场景:** + +- **动态键值对**:适合用于存储和检索动态的键值对,尤其是当键的范围不固定或不可预测时。 +- **频繁查找**:当需要快速查找、更新和删除操作时,hashmap 是理想的选择。 +- **数据稀疏**:适用于数据稀疏且键值对不连续的场景,例如,跟踪网络流量中的源IP和目的IP。 + +#### 2. **Array Map (`arraymap`)** + +##### **特点:** + +- **数据结构**:基于数组实现,所有的键是整数索引,值是与索引对应的数据。 +- **查找效率**:具有常数时间复杂度(O(1))用于插入、查找和删除操作,因索引可以直接映射到数组位置。 +- **键值对**:键必须是整数索引,通常从0开始,并且连续。值可以是任意类型,但数组的大小必须在创建时定义。 +- **内存使用**:由于使用数组,内存使用较为稳定,不受哈希表可能导致的内存碎片影响。 + +#### **适用场景:** + +- **固定范围键**:适合用于存储键为连续整数索引的场景,例如,跟踪数组中每个位置的状态。 +- **简单索引**:当键是已知的、有限范围的整数时,arraymap 是更高效的选择。 +- **性能稳定**:在内存使用和性能上都较为稳定,适合用于固定大小的配置数据或状态跟踪。 + +#### 3.**总结:** + +- **Hash Map**: + - **优点**:灵活,适用于动态和不规则的数据。 + - **缺点**:可能需要处理哈希冲突,内存使用可能不如 arraymap 稳定。 + - **适用场景**:复杂的键值对数据,动态范围的数据。 +- **Array Map**: + - **优点**:高效、内存使用稳定,适合固定范围的整数键。 + - **缺点**:不适用于键范围不固定的场景。 + - **适用场景**:需要高效、固定范围的索引数据。 + +#### 4.**选择指南:** + +- 如果你的应用场景需要处理复杂的键值对,并且键是动态或不连续的,`hashmap` 是更合适的选择。 +- 如果你有一个固定范围的、连续的整数索引,并且希望获得最稳定的性能和内存使用,`arraymap` 是更适合的选择。 diff --git "a/eBPF_Supermarket/eBPF_Performance_Analysis/docs/eBPF\346\200\247\350\203\275\346\265\213\350\257\225\346\226\271\346\241\210.md" "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/eBPF\346\200\247\350\203\275\346\265\213\350\257\225\346\226\271\346\241\210.md" new file mode 100644 index 000000000..95e6a142d --- /dev/null +++ "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/eBPF\346\200\247\350\203\275\346\265\213\350\257\225\346\226\271\346\241\210.md" @@ -0,0 +1,444 @@ +# eBPF多维度性能分析测试方案 + +## 一、测试准备 + +​ 在本次eBPF性能分析以及测试中,将从多个维度去分析eBPF程序在不同内核版本下以及在不同负载情境下,不同Map类型和挂载点类型的性能差异。 + +​ 首先,我们先在测试之前进行测试的一些必要的准备。 + +​ 使用以下表格来说明本次测试需要的准备: + +| 准备项 | 说明 | +| -------------- | ---------------------------------- | +| 内核版本的选取 | 选取本次测试需要测试的内核版本 | +| 负载环境的选取 | 确定本次测试的负载方案 | +| Map类型的选取 | 确定好本次测试将要测试的Map类型 | +| 挂载点的选取 | 确定好本次测试将要测试的挂载点类型 | +| 测试机配置 | 说明测试机的各项配置 | + +### **1.内核版本的选取:** + +​ 首先,在选取需要测试的Linux内核版本时,考虑两个方面,第一个是在eBPF发展中比较有转折点的内核版本,其次是目前企业应用和日常学习中,大家比较常用的Linux内核版本。首先,以下是eBPF技术在主要内核版本中的发展过程及其引入的功能(主要关注Map和程序类型): + +| 内核版本 | 时间 | 新增功能 | +| ---------- | ------- | ------------------------------------------------------------ | +| Linux 3.18 | 2014.12 | 基础的eBPF Maps引入:最初引入的map类型有`hash map`和`array map` | +| Linux 4.6 | 2016.5 | 引入了`Per-CPU`的哈希表和数组类型 | +| Linux 4.3 | 2015.11 | 支持了`kprobe`和`tracepoints` | +| Linux 4.14 | 2017.11 | 支持eBPF程序附加到`perf events`,用于性能分析和监控 | +| Linux 4.19 | 2018.10 | 引入了环形缓冲区类型的`Ring Buffer Map` | +| Linux 5.19 | 2022.7 | 增强了`XDP`和`BPF trampoline`功能,使得动态附加eBPF程序更加高效和灵活 | +| Linux 6.2 | 2023.2 | 增强了对 `fentry` 和 `fexit` 程序类型的支持,使得 eBPF 程序可以更灵活地附加到内核函数的入口和退出点 | +| Linux 6.5 | 2023.8 | 引入了新的机制`bpf_cookie`:允许 eBPF 程序为特定事件分配和管理 `cookie` | + +​ 通过查阅资料并进行调研,本次测试选取的内核版本为4.19、5.19、6.5三个Linux内核版本来进行分别的测试。 + +### 2.负载环境的选取: + +#### 1.系统负载 + +​ 在本次测试中,会使用负载工具(stress-ng)对整个系统进行加压,比如,对cpu、内存、IO速率进行加压。在这种系统高负载以及在内核版本固定,负载环境固定的情况下,比较不同Map类型和不同挂载点类型在高负载环境下的表现情况。 + +​ 这种设计是考虑eBPF程序在整个系统高负载情况下不同Map类型、不同挂载点类型的性能测试。接下来,还需要测试在eBPF程序本身的高负载环境下,不同Map类型、不同挂载点类型的表现情况。 + +#### 2.程序内部高负载 + +​ 在本次实验中,也会对eBPF的不同Map进行大量的增删改查操作,来模拟对Map操作的高负载情境。比如,控制eBPF的挂载点相同、内核版本相同、测试环境相同、对不同的Map类型进行相同且大量的增删改查操作,来对比不同Map类型在各种前提都相同,它们的操作在时间性能上存在的差异。 + +### 3.Map类型的选取: + +​ 在本次测试中,我们选取的Linux内核版本分别为:4.19、5.19、6.5这三个版本,接下来通过查看内核源码来查看这三个版本分别支持的Map类型,内核路径为:(/include/uapi/linux/bpf.h) + +Linux4.19版本支持的Map类型: + +```c +enum bpf_map_type { + BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PROG_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_STACK_TRACE, + BPF_MAP_TYPE_CGROUP_ARRAY, + BPF_MAP_TYPE_LRU_HASH, + BPF_MAP_TYPE_LRU_PERCPU_HASH, + BPF_MAP_TYPE_LPM_TRIE, + BPF_MAP_TYPE_ARRAY_OF_MAPS, + BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, + BPF_MAP_TYPE_CPUMAP, + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, + BPF_MAP_TYPE_CGROUP_STORAGE, + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, +};//21种 +``` + +Linux5.19版本支持的Map类型: + +```c +enum bpf_map_type { + BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PROG_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_STACK_TRACE, + BPF_MAP_TYPE_CGROUP_ARRAY, + BPF_MAP_TYPE_LRU_HASH, + BPF_MAP_TYPE_LRU_PERCPU_HASH, + BPF_MAP_TYPE_LPM_TRIE, + BPF_MAP_TYPE_ARRAY_OF_MAPS, + BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, + BPF_MAP_TYPE_CPUMAP, + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, + BPF_MAP_TYPE_CGROUP_STORAGE, + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, + BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, + BPF_MAP_TYPE_QUEUE, + BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_SK_STORAGE, + BPF_MAP_TYPE_DEVMAP_HASH, + BPF_MAP_TYPE_STRUCT_OPS, + BPF_MAP_TYPE_RINGBUF, + BPF_MAP_TYPE_INODE_STORAGE, + BPF_MAP_TYPE_TASK_STORAGE, + BPF_MAP_TYPE_BLOOM_FILTER, +};//31种 +``` + +Linux6.5版本支持的Map类型: + +```c +enum bpf_map_type { + BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PROG_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_STACK_TRACE, + BPF_MAP_TYPE_CGROUP_ARRAY, + BPF_MAP_TYPE_LRU_HASH, + BPF_MAP_TYPE_LRU_PERCPU_HASH, + BPF_MAP_TYPE_LPM_TRIE, + BPF_MAP_TYPE_ARRAY_OF_MAPS, + BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, + BPF_MAP_TYPE_CPUMAP, + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, + BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, + BPF_MAP_TYPE_CGROUP_STORAGE = BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, + BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, + BPF_MAP_TYPE_QUEUE, + BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_SK_STORAGE, + BPF_MAP_TYPE_DEVMAP_HASH, + BPF_MAP_TYPE_STRUCT_OPS, + BPF_MAP_TYPE_RINGBUF, + BPF_MAP_TYPE_INODE_STORAGE, + BPF_MAP_TYPE_TASK_STORAGE, + BPF_MAP_TYPE_BLOOM_FILTER, + BPF_MAP_TYPE_USER_RINGBUF, + BPF_MAP_TYPE_CGRP_STORAGE, +};//34种 +``` + +​ 在本次测试中,将对三个内核版本进行分别的分析和测试。 + +​ 目前,将分析并测试常用的Map类型,在Linux4.19内核版本中,将分析并测试以下Map类型: + +```c + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, +``` + +​ 在Linux5.19内核版本中,将分析并测试常用的以下Map类型: + +```c + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_QUEUE, + BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_RINGBUF, +``` + +​ 在Linux6.5内核版本中,将分析并测试常用的以下Map类型: + +```c + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_QUEUE, + BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_RINGBUF, + BPF_MAP_TYPE_USER_RINGBUF, +``` + +### 4.挂载点类型的选取: + +​ 和上面的分析类似,我们先看不同内核版本所支持的挂载点类型: + +Linux4.19版本支持的挂载点类型: + +```c +enum bpf_prog_type { + BPF_PROG_TYPE_UNSPEC, + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_SCHED_CLS, + BPF_PROG_TYPE_SCHED_ACT, + BPF_PROG_TYPE_TRACEPOINT, + BPF_PROG_TYPE_XDP, + BPF_PROG_TYPE_PERF_EVENT, + BPF_PROG_TYPE_CGROUP_SKB, + BPF_PROG_TYPE_CGROUP_SOCK, + BPF_PROG_TYPE_LWT_IN, + BPF_PROG_TYPE_LWT_OUT, + BPF_PROG_TYPE_LWT_XMIT, + BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_RAW_TRACEPOINT, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, + BPF_PROG_TYPE_SK_REUSEPORT, +};//22种 +``` + +Linux5.19版本支持的挂载点类型: + +```c +enum bpf_prog_type { + BPF_PROG_TYPE_UNSPEC, + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_SCHED_CLS, + BPF_PROG_TYPE_SCHED_ACT, + BPF_PROG_TYPE_TRACEPOINT, + BPF_PROG_TYPE_XDP, + BPF_PROG_TYPE_PERF_EVENT, + BPF_PROG_TYPE_CGROUP_SKB, + BPF_PROG_TYPE_CGROUP_SOCK, + BPF_PROG_TYPE_LWT_IN, + BPF_PROG_TYPE_LWT_OUT, + BPF_PROG_TYPE_LWT_XMIT, + BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_RAW_TRACEPOINT, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, + BPF_PROG_TYPE_SK_REUSEPORT, + BPF_PROG_TYPE_FLOW_DISSECTOR, + BPF_PROG_TYPE_CGROUP_SYSCTL, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, + BPF_PROG_TYPE_CGROUP_SOCKOPT, + BPF_PROG_TYPE_TRACING, + BPF_PROG_TYPE_STRUCT_OPS, + BPF_PROG_TYPE_EXT, + BPF_PROG_TYPE_LSM, + BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_SYSCALL, +};//32种 +``` + +Linux6.5版本支持的挂载点类型: + +```c +enum bpf_prog_type { + BPF_PROG_TYPE_UNSPEC, + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_SCHED_CLS, + BPF_PROG_TYPE_SCHED_ACT, + BPF_PROG_TYPE_TRACEPOINT, + BPF_PROG_TYPE_XDP, + BPF_PROG_TYPE_PERF_EVENT, + BPF_PROG_TYPE_CGROUP_SKB, + BPF_PROG_TYPE_CGROUP_SOCK, + BPF_PROG_TYPE_LWT_IN, + BPF_PROG_TYPE_LWT_OUT, + BPF_PROG_TYPE_LWT_XMIT, + BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_RAW_TRACEPOINT, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, + BPF_PROG_TYPE_SK_REUSEPORT, + BPF_PROG_TYPE_FLOW_DISSECTOR, + BPF_PROG_TYPE_CGROUP_SYSCTL, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, + BPF_PROG_TYPE_CGROUP_SOCKOPT, + BPF_PROG_TYPE_TRACING, + BPF_PROG_TYPE_STRUCT_OPS, + BPF_PROG_TYPE_EXT, + BPF_PROG_TYPE_LSM, + BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_SYSCALL, + BPF_PROG_TYPE_NETFILTER, +};//33种 +``` + +​ 在测试这三个不同内核版本的挂载点表现差异时,我们选取常用的挂载点类型,如下所示: + +```c + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_TRACEPOINT, + BPF_PROG_TYPE_XDP, + BPF_PROG_TYPE_PERF_EVENT, + BPF_PROG_TYPE_SYSCALL, +``` + +### 5.测试机的配置 + +本次测试的主机配置如下所示: + +| 名称 | 配置 | +| ------------ | ------------------------------------------------------ | +| CPU | 13th Gen Intel(R) Core(TM) i9-13900HX 2.20 GHz 16核 | +| 内存 | 16GB | +| 硬盘大小 | 100GB | +| 虚拟机 | VMware Workstation 上搭建的ubuntu 22.04.3 LTS | +| 内核版本 | 4.19、5.19、6.5 | +| eBPF开发工具 | libbpf | + +在测试之前,我们需要关闭CPU的P-states和C-states,来确保CPU频率一致性。**P-states** 是处理器的性能状态,用于调整 CPU 的工作频率和电压,以达到性能和功耗的平衡。P-states 允许处理器在不同的性能状态之间切换,以适应当前的计算负载。**C-states** 是处理器的休眠状态,用于降低 CPU 的功耗当其处于空闲状态时。C-states 允许处理器在不使用时进入更深的节能状态,从而减少功耗。 + +配置如下: + +**关闭P-states:** + +```shell +GRUB_CMDLINE_LINUX="resume=/dev/mapper/ao_anolis-swap rd.lvm.lv=ao_anolis/root rd.lvm.lv=ao_anolis/swap rhgb quiet" +更改为: +GRUB_CMDLINE_LINUX="resume=/dev/mapper/ao_anolis-swap rd.lvm.lv=ao_anolis/root rd.lvm.lv=ao_anolis/swap rhgb quiet intel_pstate=disable noacpi" +``` + +**关闭C-states:** + +```shell +GRUB_CMDLINE_LINUX="resume=/dev/mapper/ao_anolis-swap rd.lvm.lv=ao_anolis/root rd.lvm.lv=ao_anolis/swap rhgb quiet intel_pstate=disable noacpi" +更改为: +GRUB_CMDLINE_LINUX="resume=/dev/mapper/ao_anolis-swap rd.lvm.lv=ao_anolis/root rd.lvm.lv=ao_anolis/swap rhgb quiet intel_pstate=disable noacpi processor.max_cstate=0" +``` + +## 二、测试工具引入: + +​ 在本次测试过程中,会使用以下工具来进行测试: + +| 工具 | 工具说明 | +| ------------------ | ------------------------------------------------------------ | +| libbpf | 使用libbpf工具来进行eBPF程序的编写 | +| stress-ng | 通过该工具对系统进行加压,模拟高负载环境 | +| Visual Studio Code | 使用该开发工具进行虚拟机控制和程序编写 | +| Python | 使用Python语言喝Python数据分析的相关库来对测试后的数据进行分析 | +| shell脚本 | 编写shell脚本来自动化测试用例和数据分析的运行 | +| Typora | 编写测试相关的文档,包括测试分析和测试结果等 | + +## 三、测试计划 + +| 时间 | 任务 | 产出 | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 7.20-8.2 | 详细设计出测试方案,对后面做出详细的规划 | 输出详细的测试方案 | +| Map: | | | +| 8.3-8.9 | 在不同的内核版本下,对Map的各个类型进行详细的理论分析 | 输出详细的Map类型分析报告并给出分析结论 | +| 8.10-8.16 | 编写测试代码并从时间维度,不同负载的情境下对不同Map进行测试 | 输出详细的测试结果 | +| 8.17-8.23 | 完善测试并对结果进行分析 | 输出测试结果和理论分析,并不同版本的Map特性,结合理论分析给出一个操作指南 | +| 挂载点: | | | +| 8.24-8.30 | 在不同的内核版本下,对挂载点的各个类型进行详细的理论分析 | 输出详细的挂载点类型分析报告并给出分析结论 | +| 8.31-9.6 | 编写测试代码并从时间维度,不同负载的情境下对不同挂载点进行测试 | 输出详细的测试结果 | +| 9.7-9.13 | 完善测试并对结果进行分析 | 输出测试结果和理论分析,并给出不同版本的挂载点特性,结合理论分析给出一个操作指南 | +| 测试补充: | | | +| 9.14-9.20 | 通过测试过程中发现的问题和遗漏,再补充一些需要的测试结果 | 初步输出一个项目总体测试文档,并查漏补缺 | +| 9.21-9.30 | 完善项目总体开发测试文档 | 输出最终的测试报告并整理项目代码 | + +## 四、测试方案 + +​ 在测试之前,需要通过查阅资料和阅读内核源码给出一个详细且准确的理论分析报告,然后再通过下述的测试过程和测试结果来验证理论分析的正确性。并且最终给出一个eBPF最佳实践指南。 + +#### 4.1 Map类型的测试方案: + +​ Map类型的测试方案说明了本次测试方案是从时间的角度去分析不同Map类型的差异。 + +**测试的流程如下图所示:** + +![Map测试方案](./images/Map测试方案.png) + +对上图进行详细解释: + +1.首先,通过上面的分析。我们需要在测试之前确定一些环境因素: + +- 确定内核版本,本次测试将从内核版本6.5、5.19、4.19这个顺序来进行测试。 +- 确定负载,本次测试将负载定为两大类,分别为:对系统进行加压负载、对Map的操作次数进行设置。 +- 确定测试指标,本次测试会对不同Map类型定义相同的空间大小,并且进行相同的操作,来测试这些不同的Map类型在各种环境都确定的情况下,它们在时间维度上的差异。 + +2.接下来就是编写测试程序,这里会使用libbpf来编写,编写程序的关键点为: + +- 根据前面分析的结果,定义选定内核版本需要测试的Map类型。 +- 将定义好的所有Map结构体挂载在同一个函数上。 +- 在用户态对这些定义的Map进行获取并进行相同次数的相同操作。 +- 将每个Map类型的操作时间记录下来。 +- 循环上述操作,获取多组测试数据。 + +3.最后,编写python脚本来对得出的操作时间进行数据分析,并编写shell脚本进行上述所有操作的整合,自动化测试程序: + +- 通过测试程序输出的时间数据,进行数据分析。 +- 将分析的结果以文件和图表的方式展现出来。 +- 输出测试报告并结合理论分析的结果给出一个在Map方面的最佳实践指南。 + +通过上述的描述,接下来给出一个流程图来说明本次测试的具体过程: + +![Map性能测试流程](./images/Map测试流程.png) + +测试用例设计: + +| 事项 | 内容 | +| ---------------- | ------------------------------------------------------------ | +| 场景 | 在同一系统环境下,针对不同类型的eBPF Map(如HashMap、ArrayMap、LRUHashMap等)进行性能测试。测试内容包括增删改查(CRUD)操作的耗时情况。 | +| 测试目的 | 评估不同类型的eBPF Map在高频率的CRUD操作下的性能表现,特别是针对相同操作次数所需的时间差异。 | +| 负载压力产生方法 | 在ebpf程序中对不同类型的Map设置一个固定的操作次数并记录每次操作的开始和结束时间。确保每个Map类型在相同的条件下测试。 | +| 执行脚本 | map_difference.py | +| 执行方法 | 部署并加载eBPF程序;执行./run_ebpf_and_process.sh脚本;查看分析结果 | +| 与生产环境差异 | 测试环境为隔离的虚拟机,Map的操作次数可能高于生产环境的实际负载,以便突显性能差异。 | +| 指标要求 | 每种Map类型的CRUD操作次数必须相同;相同操作次数下,不同Map类型的耗时差异不应超过预期范围; | +| 测试结果 | 记录每种Map类型的总操作时间,并汇总到报告中,生成柱状图或折线图展示不同Map类型的性能差异。 | +| 测试结果分析 | 分析不同Map类型在CRUD操作下的性能差异,确定性能瓶颈。评估哪种Map类型在高并发场景下表现最优。 | +| 后续Action | 如果某种Map类型在测试中表现出显著劣势,建议在生产环境中慎用或优化其使用场景。 | + + +#### 4.2对挂载点类型的测试方案: + +未完待续。。。 + +## 五、测试开发与执行 + +## 六、测试分析 diff --git "a/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\226\271\346\241\210.png" "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\226\271\346\241\210.png" new file mode 100644 index 000000000..cae6c82c4 Binary files /dev/null and "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\226\271\346\241\210.png" differ diff --git "a/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\265\201\347\250\213.png" "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\265\201\347\250\213.png" new file mode 100644 index 000000000..411fe5fea Binary files /dev/null and "b/eBPF_Supermarket/eBPF_Performance_Analysis/docs/images/Map\346\265\213\350\257\225\346\265\201\347\250\213.png" differ